-
Notifications
You must be signed in to change notification settings - Fork 1
/
prim.c
140 lines (119 loc) · 4.19 KB
/
prim.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//Prim Minimum Spanning Tree
#include <stdio.h>
#include <stdlib.h>
#define INFINITY 2147483647
#define NEG_INFINITY -2147483647
#define true 1
#define false 0
//Decide on weather to compile main (Used as library or used in standalone)
// !!Comment out if used as library to prevent main redefinition!!
#define _DEFMAIN
//The meat of the the algorithm
//Takes In:
//map -> 2d matrix of distances between nodes
//cMap -> 2d matrix of Connectivity Booleans
//size -> Size of 2d matrixs (Number of nodes)
//start -> Starting Node
int prim(int * map, int * cMap, int size, int start){
//Set Total Cost, Lowest From Node, Lowest To Node, and Current Vertex Cost
int cost = 0;
int lowestFrom, lowestTo, currentCost;
//Visited Array -> Indicates What Nodes Have Already Been Visited (Prevent Self-Looping)
//Using calloc to pre-generate with all zeros
int * visited = (int*)calloc(size, sizeof(int));
visited[start] = true;
//TODO: Make More Efficient
//Loop Through size-1 So All Nodes Gets Touched
for(int i = 0; i < size-1; i++){
//Set lowestFrom, lowestTo, and , and currentCost to default value
//lowestFrom and lowestTo to -1. (Set to -1 to check if value has been changed)
//CurrentCost to INFINITY (Used for checking if cost is lowest)
lowestFrom = -1;
lowestTo = -1;
currentCost = INFINITY;
//Check for all visited nodes, acting as "from" node
for(int from = 0; from < size; from++){
if(visited[from]){
//Check connection to all possible nodes, acting as "to" node
for(int to = 0; to < size; to++){
//For navigating 2d arrays, using "(from*size) + to"
//AKA "(rows*size + column)"
//Checking If:
//The Nodes Are Connected (using cMap)
//The Node Is Not Part Of The Visited Nodes (Prevents Self Looping)
//Current Cost Is Lowest Cost
if(cMap[(from*size) + to] && visited[to] == false && map[(from*size) + to] < currentCost){
currentCost = map[(from*size) + to]; //Set new lowest cost
lowestFrom = from;
lowestTo = to;
}
}
}
}
//Checking If lowestFrom and lowestTo has been changed
if(lowestFrom != -1 && lowestTo != -1){
//Has Been Changed, Adding CurrentCost to Cost
cost = cost + currentCost;
visited[lowestTo] = true;
//Printing Debug Text
#ifdef DEBUG
printf("Vertex From %d to %d Cost %d (Now Cost %d)\n", lowestFrom, lowestTo, currentCost, cost);
#endif
}
else{
//Has Not Been Changed, Exiting Loop!
break;
}
}
//Free Allocated Memory (Visited Array)
free(visited);
//Return Cost
return cost;
}
#ifdef _DEFMAIN //Check if main should be compiled
int main(){
//Test Values
/*
int map[9][9] = {
{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}};
int cMap[9][9] = {
{0, 1, 0, 0, 0, 0, 0, 1, 0},
{1, 0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 0, 1},
{0, 0, 1, 0, 1, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 1, 1},
{1, 1, 0, 0, 0, 0, 1, 0, 1},
{0, 0, 1, 0, 0, 0, 1, 1, 0}};
*/
int map[5][5] = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}};
int cMap[5][5] = {
{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 1},
{0, 1, 1, 1, 0}};
//Run Prim And Get Result
int cost = prim(&map[0][0], &cMap[0][0], 5, 0);
//Print Final Cost
printf("%d\n", cost);
//Expected Output:
/*
16
*/
}
#endif //_DEFMAIN