Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 贝尔曼·福特和希普·诺兹';不能使用自定义比较函数_C++_Graph_Dijkstra_Stdset_Bellman Ford - Fatal编程技术网

C++ 贝尔曼·福特和希普·诺兹';不能使用自定义比较函数

C++ 贝尔曼·福特和希普·诺兹';不能使用自定义比较函数,c++,graph,dijkstra,stdset,bellman-ford,C++,Graph,Dijkstra,Stdset,Bellman Ford,我已经实现了一个Bellman-Ford算法来解决一个问题(用一个图),但是这个解决方案太慢了,所以我用一个堆(std::set)替换了Bellman-Ford的队列,所以最短路径的解决方案会更快地找到。(某种程度上接近Dijkstra算法) 现在,我在堆中插入节点编号,因此默认的std::set将使用节点编号而不是成本对节点进行排序。一切都很好,算法给出了正确的答案 如果我为std::set实现了一个自定义比较函数,这样节点将按其距离而不是数量进行排序,那么算法将不再向其余节点提供最短距离 这

我已经实现了一个Bellman-Ford算法来解决一个问题(用一个图),但是这个解决方案太慢了,所以我用一个堆(std::set)替换了Bellman-Ford的队列,所以最短路径的解决方案会更快地找到。(某种程度上接近Dijkstra算法)

现在,我在堆中插入节点编号,因此默认的std::set将使用节点编号而不是成本对节点进行排序。一切都很好,算法给出了正确的答案

如果我为std::set实现了一个自定义比较函数,这样节点将按其距离而不是数量进行排序,那么算法将不再向其余节点提供最短距离

这是我的比较函数:

 struct cmp{

    bool operator() (const int &a,const int &b) const{
        return (d[Q][a] < d[Q][b] );
    }
  };
 set <int,cmp> q;
struct-cmp{
布尔运算符(){
报税表(d[Q][a]
因此,作为一个BF算法,该算法一直运行到无法改进为止。比较函数是否会“弄乱”std::set,因为这是我能理解为什么添加这个比较函数会给出错误答案的唯一原因

我的意思是,如果节点是完全随机的,那么它为什么会工作,但如果它们是按成本排序的,那么它就不工作…

据我回忆,它更新了节点的距离。因此,使用权重作为
std::set
的键并不容易:如果只是更改距离,则在
std::set
中的搜索将无法找到相应的值。按照此方向需要执行的操作是删除要更新的节点,更改节点的距离,然后重新插入。还请注意,
std::set
中的对象需要一个唯一的密钥:插入一个已经存在的密钥将失败

您说过您正在使用
std::set
作为某种优先级队列。你看了
std::priority\u queue
了吗?这正是这样做的,但它往往比使用
std::set
更有效。
std::priority_queue
的问题是您无法更改对象优先级:您只能访问当前的top。很久以前,我创建了一个优先级队列(堆)集合,其中包括允许更改对象优先级的优先级队列版本(它们是Boost的初始库的一部分,但从未通过审阅过程)。我不知道您如何使用优先级队列,因此我不知道这是否是一个合理的方向


也就是说,我不明白您为什么要为Bellman-Ford算法设置
std::set
。我的理解是,该算法反复遍历图形,并用新的最短距离更新节点。你有没有看过的实现?

1)我也做过(擦除和插入),但没有成功2)使用set而不是队列将使BF更快地到达解决方案,类似于Dijkstra的算法。3) 我认为如果我更新距离而不更新集合,算法也应该有效,因为即使元素不再有序,算法仍应运行,直到达到解决方案。我还忘记了另外两件事(我将把它们添加到答案中):
std::set
只存储每个距离的一个副本,即,如果集合中的节点具有相同的距离,则忽略后一个节点。2.您是否考虑过使用
st::priority\u queue
作为优先级队列?哦,还有multiset。因此,即使在集合I中存储唯一的数字,由于比较函数,节点可以相等,因此需要多集合。。。这是我睡前的想法:我希望它能起作用。好的,我用multiset解决了这个问题。但又有另一个问题。当我必须更新一个元素(搜索、删除、插入)时,如果有多个元素具有相同的距离multiset.erase(multiset.find(element))将从那些具有相同距离的元素中删除一个随机元素。我必须使用equal_range并遍历multiset中的相等元素,以准确地找到我要查找的节点。