Попытка использовать пример Minimum Spanning Tree из книги, но он не работает с большими данными

Примечание: это не мой код

Я пытаюсь использовать структуры данных с алгоритмом минимального связующего дерева учебника C ++, но, как вы можете видеть, я создал массив ребер [] и закомментировал массив старых ребер [], но похоже, что он не работает для большего количества края или что-то. (Кстати, я просто использую символы в качестве целых)

Кто-нибудь знает почему? Я не сильно изменился, я просто изменил массив ребер.
Он компилируется просто отлично, но если вы запустите его, вы увидите, что он не будет работать с моими данными, но будет работать с исходными данными.

Массивы находятся прямо над основным (последнее)

Кроме того, если вы не хотите раскрывать свой ide, вот мой код в онлайн-среде IDE: http://goo.gl/35KMcK

Вот код:

#include <iostream>

using namespace std;

class MSTEdge
{
char src;
char dest;
int weight;
public:
MSTEdge(char s = 0, char d = 0, int w = 0) : src(s), dest(d), weight(w) { }
char& getSrc() { return src; }
char& getDest() { return dest; }
int& getWeight() { return weight; }
int& get() { return getWeight(); }
};

// undirected and weighted graph
class Graph
{
int V, E;
MSTEdge* edge;
int icount;
public:
Graph(int v, int e) : V(v), E(e), icount(0)
{
edge = new MSTEdge[e];
}
int& getVertexAmount() { return V; }
int& getEdgeAmount() { return E; }
MSTEdge*& getEdges() { return edge; }
MSTEdge& operator [](int x) { return edge[x]; }
void insert(MSTEdge& e)
{
edge[icount++] = e;
}
};

// subset for union-find
class subset
{
int parent;
int rank;
public:
subset(int p = 0, int r = 0) : parent(p), rank(r) {}
int& getTheParent() { return parent; }
int& getTheRank() { return rank; }
};

// find set of an element i
int find(subset* subsets, int i)
{
// find root and make root as parent of i (path compression)
if (subsets[i].getTheParent() != i)
subsets[i].getTheParent() = find(subsets, subsets[i].getTheParent());

return subsets[i].getTheParent();
}

// union of two sets of x and y
void Union(subset* subsets, int x, int y)
{
int x_root = find(subsets, x);
int yroot = find(subsets, y);

// Attach smaller rank tree under root of high rank tree
// (Union by Rank)
if (subsets[x_root].getTheRank() < subsets[yroot].getTheRank())
subsets[x_root].getTheParent() = yroot;
else if (subsets[x_root].getTheRank() > subsets[yroot].getTheRank())
subsets[yroot].getTheParent() = x_root;

// If ranks are same, then make one as root and increment its rank by one
else
{
subsets[yroot].getTheParent() = x_root;
subsets[x_root].getTheRank()++;
}
}

template <typename T>
void partition_array(T* arr, int& i, int& j, T pivot)
{
while (i <= j)
{
while (arr[i].get() < pivot.get())
i++;
while (arr[j].get() > pivot.get())
j--;
if (i <= j)
{
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
}

template <typename T>
void quickSort_array(T* arr, int left, int right)
{
int i = left, j = right;
T pivot = arr[(left + right) / 2];

// partition
partition_array(arr, i, j, pivot);

// recursion
if (left < j)
quickSort_array(arr, left, j);
if (i < right)
quickSort_array(arr, i, right);
}

// The main function to construct MST
void MST(Graph& graph)
{
int V = graph.getVertexAmount();
MSTEdge* result = new MSTEdge[V];  // Tnis will store the resultant MST
int e = 0;  // An index variable, used for result[]
int i = 0;  // An index variable, used for sorted edges

quickSort_array(graph.getEdges(), 0, graph.getEdgeAmount());

// Allocate memory for creating V ssubsets
subset* subsets = new subset[V];

// Create V subsets with single elements
for (int v = 0; v < V; ++v)
{
subsets[v].getTheParent() = v;
subsets[v].getTheRank() = 0;
}

// Number of edges to be taken is equal to V-1
while (e < V - 1)
{
// Step 2: Pick the smallest edge. And increment the index
// for next iteration
MSTEdge next_edge = graph[i++];

int x = find(subsets, next_edge.getSrc());
int y = find(subsets, next_edge.getDest());

// If including this edge does't cause cycle, include it
// in result and increment the index of result for next edge
if (x != y)
{
result[e++] = next_edge;
Union(subsets, x, y);
}
// Else discard the next_edge
}

// print the contents of result[] to display the built MST
cout << "Following are the edges in the constructed MST\n";
for (i = 0; i < e; ++i)
cout
<< result[i].getSrc()
<< " -- "<< result[i].getDest()
<< " == "<< result[i].getWeight()
<< endl;
return;
}

/* weighted graph
10
0-------- 1
|  \     |
6|   5\  |15
|      \ |
2 --------3
4
*///MSTEdge edges[] =  //THIS WORKS
//{
//  MSTEdge(0,1,10),
//  MSTEdge(0,2,6),
//  MSTEdge(0,3,5),
//  MSTEdge(1,3,15),
//  MSTEdge(2,3,4)
//};

MSTEdge edges[] =    // CAUSES PROBLEMS
{
MSTEdge('A','B',5),
MSTEdge('A','C',1),
MSTEdge('B','C',10),
MSTEdge('B','E',13),
MSTEdge('C','D',5),
MSTEdge('D','E',15),
MSTEdge('D','F',10),
MSTEdge('E','F',17)
};// Driver program to test above functions
int main()
{
int count = sizeof(edges) / sizeof(MSTEdge);
int V = count - 1;  // Number of vertices in graph
Graph graph(V, count);
for (int e = 0; e < count; e++)
graph.insert(edges[e]);
MST(graph);
return 1;
}

// Following are the edges in the constructed MST
// 2 -- 3 == 4
// 0 -- 3 == 5
// 0 -- 1 == 10

1

Решение

subsets массив инициализируется с помощью этого кода:

// Create V subsets with single elements
for (int v = 0; v < V; ++v)
{
subsets[v].getTheParent() = v;
subsets[v].getTheRank() = 0;
}

Это дает вам подмножества, имеющие parent значения от 0 до V-1

Затем код пытается найти эти подмножества, используя эту строку

int x = find(subsets, next_edge.getSrc());

Но ваши ребра имеют источник и назначение, установленные на «A», «B», «C» и т. Д. Таким образом, он никогда не сможет найти что-либо в subsets, Это, вероятно, доступ к элементам за пределами массива subsets и вызывая неопределенное поведение.

Чтобы исправить это, либо поменяйте edges массив использовать 0, 1, 2, в качестве идентификаторов узлов (вероятно, самый простой), или изменить subsets Инициализируйте код, чтобы установить для родителей «A», «B», «C» и т. д. Примечание: может быть больше мест, в которых предполагается, что идентификаторы узла начинаются с 0.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]