Graph Convolutional Branch and Bound v1.0.0
A TSP solver that combines a graph convolutional network with a 1-Tree branch-and-bound.
Loading...
Searching...
No Matches
kruskal.c
Go to the documentation of this file.
1
15#include "kruskal.h"
16
17
18static void swap(Graph *graph, unsigned short swap_1, unsigned short swap_2) {
19
20 Edge * edges = graph->edges;
21
22 //printf("\nswap values %lf - %lf, at %d - %d\n", edges[swap_1].weight, edges[swap_2].weight, swap_1, swap_2);
23
24 graph->edges_matrix[edges[swap_1].src][edges[swap_1].dest].positionInGraph = swap_2;
25 graph->edges_matrix[edges[swap_2].src][edges[swap_2].dest].positionInGraph = swap_1;
26
27
28 graph->edges_matrix[edges[swap_1].dest][edges[swap_1].src].positionInGraph = swap_2;
29 graph->edges_matrix[edges[swap_2].dest][edges[swap_2].src].positionInGraph = swap_1;
30
31 edges[swap_1].positionInGraph = swap_2;
32 edges[swap_2].positionInGraph = swap_1;
33 Edge temp = edges[swap_1];
34 edges[swap_1] = edges[swap_2];
35 edges[swap_2] = temp;
36}
37
38
39static int pivot_quicksort(Graph * graph, unsigned short first, unsigned short last) {
40 Edge * edges = graph->edges;
41 Edge last_edge = edges[last];
42 Edge first_edge = edges[first];
43 unsigned short middle = (first + last) / 2;
44 Edge middle_edge = edges[middle];
45 double pivot_weight = first_edge.weight;
46 double pivot_prob = first_edge.prob;
47
48 if (last_edge.weight > first_edge.weight ||
49 (HYBRID && last_edge.weight == first_edge.weight && last_edge.prob < first_edge.prob)){
50 if ((last_edge.weight > middle_edge.weight) ||
51 (HYBRID && last_edge.weight == middle_edge.weight && last_edge.prob < middle_edge.prob)) {
52 if ((middle_edge.weight > first_edge.weight) ||
53 (HYBRID && middle_edge.weight == first_edge.weight && middle_edge.prob < first_edge.prob)){
54 pivot_weight = middle_edge.weight;
55 pivot_prob = middle_edge.prob;
56 swap(graph, first, middle);
57 }
58 } else {
59 pivot_weight = last_edge.weight;
60 pivot_prob = last_edge.prob;
61 swap(graph, first, last);
62 }
63 } else {
64 if (last_edge.weight > middle_edge.weight ||
65 (HYBRID && last_edge.weight == middle_edge.weight && last_edge.prob < middle_edge.prob)) {
66 pivot_weight = last_edge.weight;
67 pivot_prob = last_edge.prob;
68 swap(graph, first, last);
69
70 } else if ((first_edge.weight > middle_edge.weight) ||
71 (HYBRID && first_edge.weight == middle_edge.weight && first_edge.prob < middle_edge.prob)) {
72 pivot_weight = middle_edge.weight;
73 pivot_prob = middle_edge.prob;
74 swap(graph, first, middle);
75 }
76 }
77 unsigned short j = last;
78 unsigned short i = first + 1;
79 bool condition = true;
80 while (condition) {
81 Edge i_edge = edges[i];
82 while (i <= j && ((!HYBRID && pivot_weight >= i_edge.weight) ||
83 (HYBRID && (pivot_weight > i_edge.weight || (pivot_weight == i_edge.weight && pivot_prob <= i_edge.prob))))){
84 i += 1;
85 i_edge = edges[i];
86 }
87 Edge j_edge = edges[j];
88 while (i <= j && (j_edge.weight > pivot_weight
89 || (HYBRID && (j_edge.weight == pivot_weight && j_edge.prob < pivot_prob)))) {
90 j -= 1;
91 j_edge = edges[j];
92 }
93 if (i <= j) {
94 swap(graph, i, j);
95 } else {
96 condition = false;
97 }
98
99 }
100
101 if(j != first){
102 swap( graph, first, j);
103 }
104
105 return j;
106
107}
108
109
110static void quick_sort(Graph * graph, unsigned short first, unsigned short last) {
111 if (first < last) {
112 unsigned short pivot = pivot_quicksort(graph, first, last);
113 if(pivot -1 > first) {
114 quick_sort(graph, first, pivot - 1);
115 }
116 if(pivot + 1 < last) {
117 quick_sort(graph, pivot + 1, last);
118 }
119 }
120}
121
122
123void wrap_quick_sort(Graph * graph) {
124 if (!graph->orderedEdges) {
125 graph->orderedEdges = true;
126 quick_sort(graph, 0, graph->num_edges - 1);
127 }
128}
129
130
131void kruskal(Graph * graph, MST * mst) {
132 create_mst(mst, graph->nodes, graph->num_nodes);
133 Forest forest;
134 create_forest(&forest, graph->nodes, graph->num_nodes);
135 wrap_quick_sort(graph);
136 unsigned short num_edges_inG = 0;
137 unsigned short num_edges_inMST = 0;
138
139 while (num_edges_inG < graph->num_edges && num_edges_inMST < graph->num_nodes - 1) {
140 // get the edge with the minimum weight
141 Edge current_edge = graph->edges[num_edges_inG];
142 unsigned short src = current_edge.src;
143 unsigned short dest = current_edge.dest;
144
145 Set *set1_root = find(&forest.sets[src]);
146 Set *set2_root = find(&forest.sets[dest]);
147
148 if (set1_root->num_in_forest != set2_root->num_in_forest) {
149 merge(set1_root, set2_root);
150 // add the edge to the MST
151 add_edge(mst, &current_edge);
152 num_edges_inMST++;
153 }
154 num_edges_inG++;
155 }
156 if (num_edges_inMST == graph->num_nodes - 1) {
157 mst->isValid = true;
158 }
159}
static void swap(Graph *graph, unsigned short swap_1, unsigned short swap_2)
Definition: kruskal.c:18
void kruskal(Graph *graph, MST *mst)
The Kruskal algorithm to find the Minimum Spanning Tree O(|E| log |V|)
Definition: kruskal.c:131
static int pivot_quicksort(Graph *graph, unsigned short first, unsigned short last)
Definition: kruskal.c:39
void wrap_quick_sort(Graph *graph)
The wrapper of the quick sort algorithm.
Definition: kruskal.c:123
static void quick_sort(Graph *graph, unsigned short first, unsigned short last)
Definition: kruskal.c:110
The declaration of the functions needed to compute the MST with Kruskal's algorithm.
void merge(Set *set1, Set *set2)
Merge two Sets in the Forest if they are not already in the same Set.
Definition: mfset.c:53
Set * find(Set *set)
Find the root of a Set.
Definition: mfset.c:44
void create_forest(Forest *forest, const Node *nodes, unsigned short num_nodes)
Create a new Forest with n Sets, each Set containing a Node, without constraints.
Definition: mfset.c:31
void add_edge(MST *tree, const Edge *edge)
Add an Edge to the MST.
Definition: mst.c:38
void create_mst(MST *mst, const Node *nodes, unsigned short num_nodes)
Create a Minimum Spanning Tree from a set of Nodes.
Definition: mst.c:17
Structure of an Edge.
Definition: graph.h:40
unsigned short dest
ID of the destination vertex.
Definition: graph.h:42
unsigned short src
ID of the source vertex.
Definition: graph.h:41
double prob
Probability of the Edge to be in an optimal tour.
Definition: graph.h:45
double weight
Weight of the Edge, 1 if the data_structures is not weighted.
Definition: graph.h:44
unsigned short positionInGraph
Position of the Edge in the list of Edges of the Graph.
Definition: graph.h:46
A Forest is a list of Sets.
Definition: mfset.h:28
Set sets[MAX_VERTEX_NUM]
Array of Sets.
Definition: mfset.h:30
Structure of a Graph.
Definition: graph.h:51
Edge edges_matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]
Adjacency matrix of the Graph.
Definition: graph.h:59
unsigned short num_edges
Number of Edges in the Graph.
Definition: graph.h:55
bool orderedEdges
True if the Edges are ordered by weight, false otherwise.
Definition: graph.h:56
Edge edges[MAX_EDGES_NUM]
Array of Edges.
Definition: graph.h:58
Node nodes[MAX_VERTEX_NUM]
Array of Nodes.
Definition: graph.h:57
unsigned short num_nodes
Number of Nodes in the Graph.
Definition: graph.h:54
Minimum Spanning Tree, or MST, and also a 1-Tree.
Definition: mst.h:28
bool isValid
True if the MST has the correct number of Edges, false otherwise.
Definition: mst.h:29
A Set is a node in the Forest.
Definition: mfset.h:19
unsigned short num_in_forest
Number of the position of the Set in the Forest.
Definition: mfset.h:23