使用 Kruskal 算法查找最小生成树的错误
Bug in finding minimum spanning tree using Kruskal's algorithm
我编写将顶点添加到图形中的代码并更新边缘的权重,然后找到最小生成树。我认为我已经做到了,但似乎有一些错误,但我无法找到它。系统使用 Valgrind 并在 MST 的调用中指示"大小为 4 的无效写入"和"大小为 4 的无效读取",但我认为它工作正常。瓦尔格林德的整个错误是 https://docs.google.com/document/d/1_AhOdDkyZGNTBVHspyGtnSQoU1tYkm0nVA5UABmKljI/edit?usp=sharing
以下代码由 like 调用
CreateNewGraph();
AddEdge(1, 2, 10);
AddEdge(2, 4, 10);
AddEdge(1, 3, 100);
AddEdge(3, 4, 10);
GetMST(mst_edges);
结果将是 (1,2( (2,4( (3,4(。
并致电
UpdateEdge(1, 3, 0.1);
GetMST(mst_edges);
结果将是 (1,2( (1,3( (2,4(。
它被发送到一个系统执行,它将像上面一样被调用,但在上面的很多时间周期中。
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
namespace HOMEWORK{
class Edge{
public:
Edge(unsigned int, unsigned int, double);
unsigned int u;
unsigned int v;
double w;
friend bool operator<(const Edge& a, const Edge& b){
return a.w < b.w;
}
};
Edge::Edge(unsigned int source = 0, unsigned int destination = 0, double weight = 0.0){
u = source;
v = destination;
w = weight;
}
vector<Edge> graph(0);
vector<int> parent(0);
int findset(int x){
if(x != parent[x])parent[x] = findset(parent[x]);
return parent[x];
}
void CreateNewGraph(){
graph.clear();
parent.clear();
}
void AddEdge(unsigned int u, unsigned int v, double w){
graph.push_back(Edge(u,v,w));
}
void UpdateEdge(unsigned int u, unsigned int v, double w){
for(int i = 0; i < graph.size(); i ++){
if(graph[i].u == u && graph[i].v == v)graph[i] = Edge(u,v,w);
}
}
void GetMST(vector<pair<unsigned int, unsigned int> >& mst_edges){
mst_edges.clear();
parent.clear();
int e = graph.size();
for(int i = 0; i <= e + 1; i ++)parent.push_back(i);
stable_sort(graph.begin(), graph.end());
for(int i = 0; i < e; i ++){
//cout << graph[i].u << ":" << graph[i].v << ":" << graph[i].w << ":" << parent[i + 1] << endl;
int pu = findset(graph[i].u);
int pv = findset(graph[i].v);
if(pu != pv){
parent[pu] = parent[pv];
mst_edges.push_back(make_pair(graph[i].u, graph[i].v));
}
}
}
void Init(){
}
void Cleanup(){
}
}
我认为问题在于您如何设置父指针。 请注意,您已将parents
设置为
for(int i = 0; i <= e + 1; i ++) parent.push_back(i);
这会在 parent
数组中为图形中的每个边创建一个条目,外加一个额外的条目。 但是,每个节点都有一个父节点,而不是每个边,并且图中的节点数可以大于边数加 1。 例如,假设您获得了以下一组边:
1 2
3 4
5 6
这张图显然有六个节点(编号为 1 ...6(,但您的代码只会为 parents
中的 4 个条目腾出空间。
尝试更改代码,以便将parents
设置为适当的大小,可能是通过在边缘列表中查找最大和最小编号节点并适当调整数组大小。 或者,考虑使用 std::unordered_map<int, int>
,如果顶点数不是连续从 0 开始,则更灵活。
希望这有帮助!
相关文章:
- C++20 个模块在 clang (Windows):在最简单的示例中键入信息错误
- 用于查找数组中最大元素的出现次数的代码,给出分段错误
- 错误C++在Visual Studio 2019中使用numeric_limits的长双精度最小值/最大值
- 在使用堆栈为下一个最大数字编写代码时面临 SIGSEGV(分段错误)
- 我在代码中找不到错误以找到最大的素因数?
- 尝试使用 EvtSetChannelConfigProperty() 函数更新最大事件日志文件大小时插入的错误值
- 使用 Prim 算法计算最小生成树:如何使其简单?
- 3 与错误最接近的总和:字符串常量之前的预期非限定 id
- 提升最小生成树,如何先做深度
- Prim 和 Boruvka 的最小生成树算法
- boost::变体访问者返回错误(最麻烦的解析?)
- 使用最小生成树(C/C++)查找从A到B的路径
- 尝试使用书中的最小生成树示例,但它不适用于大数据
- 如何使用 Prim 算法从输入文件中查找具有给定坐标集的最小生成树?
- Linker错误最可爱的二进制与matlab
- 使用 Kruskal 算法查找最小生成树的错误
- Kruskal的最小生成树算法
- 带Boost的最小生成树
- 在实现最小生成树的 Prim 算法时,逻辑错误是什么?
- 使用prim算法的最小生成树,不知道出了什么问题