C# SortedSet.Remove()不删除任何内容

C# SortedSet.Remove()不删除任何内容,c#,graph,dijkstra,sortedset,C#,Graph,Dijkstra,Sortedset,我目前正在实现Dijkstra的算法,并使用C#SortedSet作为优先级队列。 但是,为了跟踪我已经访问过的顶点,我想从优先级队列中删除第一项 这是我的密码: static int shortestPath(int start, int target) { SortedSet<int> PQ = new SortedSet<int>(new compareByVertEstimate()); for (int i = 0; i

我目前正在实现Dijkstra的算法,并使用C#SortedSet作为优先级队列。 但是,为了跟踪我已经访问过的顶点,我想从优先级队列中删除第一项

这是我的密码:

static int shortestPath(int start, int target)
    {
        SortedSet<int> PQ = new SortedSet<int>(new compareByVertEstimate());
        for (int i = 0; i < n; i++)
        {
            if (i == start - 1)
                vertices[i].estimate = 0;
            else
                vertices[i].estimate = int.MaxValue;

            PQ.Add(i);
        }

        int noOfVisited = 0;
        while (noOfVisited < n)
        {
            int u = PQ.First();
            noOfVisited++;

            foreach (Edge e in vertices[u].neighbours)
            {
                if (vertices[e.target.Item1].estimate > vertices[u].estimate + e.length)
                {
                    vertices[e.target.Item1].estimate = vertices[u].estimate + e.length;
                }
            }

            PQ.Remove(u);
        }
        return vertices[target - 1].estimate;
    }
静态int最短路径(int开始,int目标)
{
SortedSet PQ=新的SortedSet(新的compareByVertEstimate());
对于(int i=0;i顶点[u]。估计+e.length)
{
顶点[e.target.Item1]。估计值=顶点[u]。估计值+e.length;
}
}
PQ.移除(u);
}
返回顶点[target-1]。估计;
}
这是比较器:

public class compareByVertEstimate : IComparer<int>
{
    public int Compare(int a, int b)
    {

        if (Program.vertices[a].estimate >= Program.vertices[b].estimate) return 1;
        else return -1;
    }
}
public类compareByVertEstimate:IComparer
{
公共整数比较(整数a、整数b)
{
if(Program.vertices[a].estimate>=Program.vertices[b].estimate)返回1;
否则返回-1;
}
}
我的优先级队列没有显式地保存顶点,而是有一个顶点数组,优先级队列保存索引。 因此,优先级队列根据每个顶点持有的“估计”整数进行排序

现在我的问题是,我可以使用.first()或.Min轻松地从SortedSet检索第一个元素,但是当我尝试使用.remove()删除该元素时,该方法返回false,并且不会删除任何内容。分拣数据集保持不变

有没有办法解决这个问题

提前谢谢

编辑 我将比较器更改为:

public class compareByVertEstimate : IComparer<int>
{
    public int Compare(int a, int b)
    {

        if (Program.vertices[a].estimate == Program.vertices[b].estimate) return 0;
        else if (Program.vertices[a].estimate >= Program.vertices[b].estimate) return 1;
        else return -1;
    }
}
public类compareByVertEstimate:IComparer
{
公共整数比较(整数a、整数b)
{
if(Program.vertices[a].estimate==Program.vertices[b].estimate)返回0;
else if(Program.vertices[a].estimate>=Program.vertices[b].estimate)返回1;
否则返回-1;
}
}
但是现在优先级队列不再包含所有正确的元素。 (注意,优先级队列将包含指向具有相同估计值的顶点的指针)

您的比较函数从不将两个元素进行相等的比较(
返回0;

您的集合将无法删除与其持有的任何元素不相等的元素

例如:

public class compareByVertEstimate : IComparer<int>
{
    public int Compare(int a, int b)
    {

        if (a == b) return 0;

        if (Program.vertices[a].estimate >= Program.vertices[b].estimate) return 1;

        return -1;
    }
}
public类compareByVertEstimate:IComparer
{
公共整数比较(整数a、整数b)
{
如果(a==b)返回0;
if(Program.vertices[a].estimate>=Program.vertices[b].estimate)返回1;
返回-1;
}
}
@当然,hvd是正确的,虽然上面的版本可以工作,但它已经完全崩溃了。更好的比较器可能是:

public class compareByVertEstimate : IComparer<int>
{
    public int Compare(int a, int b)
    {
        var ae = Program.vertices[a].estimate;
        var be = Program.vertices[b].estimate; 

        var result = ae.CompareTo(be);

        if (result == 0) return a.CompareTo(b);

        return result;
    }
}
public类compareByVertEstimate:IComparer
{
公共整数比较(整数a、整数b)
{
var ae=程序.顶点[a].估计;
var be=程序。顶点[b]。估计;
var结果=ae.比较(be);
如果(结果==0),则返回a.CompareTo(b);
返回结果;
}
}

我添加了一行来检查是否相等,但优先级队列是否仍然有效?有些顶点具有相同的估计值,我仍然希望将它们添加到优先级队列。@vanLeemhuyzen您不需要比较估计值,只需要确保某个索引与非常相同的索引进行比较。
compare(A,b)
中的比较器可以返回
1
,而
compare(b,A)
也可以同时返回
1
,因为它严重损坏,无法使用标准类。如果您检查了所有估算值,当然您需要的不仅仅是
=
。注意:将
==
更改为
=
是不够的。如果
a!=b
,但是
顶点[a]。估计==顶点[b]。估计
,您仍然会遇到这样的情况,
比较(a,b)
比较(b,a)
都返回
1
@hvd==只是我注意到的一个输入错误。新的比较器应该可以正常工作。相同值的估计值之间的排序顺序现在取决于索引值,但真正重要的是它们之间的比较并不相等。虽然您的直接问题已经得到回答,但我认为有必要指出,在将顶点添加到
SortedSet
后,您似乎正在更改顶点的估计值。那是行不通的
SortedSet
不会对任何项目进行重新排序,如果项目不再排序,它将严重损坏。我注意到,我也更改了代码,因此每次发现新顶点时,它都会添加到SortedSet,而不是预先添加它们。