mirror of
https://github.com/TheAlgorithms/C
synced 2024-11-24 06:19:37 +03:00
feat: Prims algorithm (#815)
* Added prim.c * Updated formatting in prim.c * Docs: updated prim.c documentation * feat: Included testing in prim.c * feat: eliminated globals & changed variable types * Docs: added documentation for minimum function * updating DIRECTORY.md * Updated documentation * Docs: Changed function docs & made test function static * Docs: made further requested changes Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
4b65a6b6b1
commit
c6a3279b9b
@ -134,6 +134,7 @@
|
||||
|
||||
## Greedy Approach
|
||||
* [Djikstra](https://github.com/TheAlgorithms/C/blob/master/greedy_approach/djikstra.c)
|
||||
* [Prim](https://github.com/TheAlgorithms/C/blob/master/greedy_approach/prim.c)
|
||||
|
||||
## Hash
|
||||
* [Hash Adler32](https://github.com/TheAlgorithms/C/blob/master/hash/hash_adler32.c)
|
||||
|
203
greedy_approach/prim.c
Normal file
203
greedy_approach/prim.c
Normal file
@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @file
|
||||
* @author [Timothy Maloney](https://github.com/sl1mb0)
|
||||
* @brief [Prim's algorithm](https://en.wikipedia.org/wiki/Prim%27s_algorithm)
|
||||
* implementation in C to find the MST of a weighted, connected graph.
|
||||
* @details Prim's algorithm uses a greedy approach to generate the MST of a weighted connected graph.
|
||||
* The algorithm begins at an arbitrary vertex v, and selects a next vertex u,
|
||||
* where v and u are connected by a weighted edge whose weight is the minimum of all edges connected to v.
|
||||
* @references Page 319 "Introduction to the Design and Analysis of Algorithms" - Anany Levitin
|
||||
*
|
||||
* To test - run './prim -test'
|
||||
* prim() will find the MST of the following adj. matrix:
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 1 0 4 6
|
||||
* 2 4 0 5
|
||||
* 3 6 5 0
|
||||
*
|
||||
* The minimum spanning tree for the above weighted connected graph is given by the following adj matrix:
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 1 0 0 0
|
||||
* 2 0 0 0
|
||||
* 3 0 0 0
|
||||
*
|
||||
*
|
||||
* The following [link](https://visualgo.net/en/mst) provides a visual representation of graphs that can be used to test/verify the algorithm for different adj
|
||||
* matrices and their weighted, connected graphs.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /// for IO operations
|
||||
#include <string.h> /// for string comparison
|
||||
#include <assert.h> /// for assert()
|
||||
#include <inttypes.h> /// for uint16_t
|
||||
|
||||
#define MAX 20
|
||||
#define INF 999
|
||||
|
||||
/**
|
||||
* @brief Finds index of minimum element in edge list for an arbitrary vertex
|
||||
* @param arr graph row
|
||||
* @param N number of elements in arr
|
||||
* @returns index of minimum element in arr
|
||||
*/
|
||||
uint16_t minimum(uint16_t arr[], uint16_t N)
|
||||
{
|
||||
uint16_t index = 0;
|
||||
uint16_t min = INF;
|
||||
|
||||
for (uint16_t i = 0; i < N; i++)
|
||||
{
|
||||
if (arr[i] < min)
|
||||
{
|
||||
min = arr[i];
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Used to find MST of user-generated adj matrix G
|
||||
* @returns void
|
||||
*/
|
||||
void prim(uint16_t G[][MAX], uint16_t MST[][MAX], uint16_t V)
|
||||
{
|
||||
uint16_t u, v;
|
||||
uint16_t E_t[MAX], path[MAX];
|
||||
uint16_t V_t[MAX], no_of_edges;
|
||||
|
||||
E_t[0] = 0; // edges for current vertex
|
||||
V_t[0] = 1; // list of visited vertices
|
||||
|
||||
for (uint16_t i = 1; i < V; i++)
|
||||
{
|
||||
E_t[i] = G[i][0];
|
||||
path[i] = 0;
|
||||
V_t[i] = 0;
|
||||
}
|
||||
|
||||
no_of_edges = V - 1;
|
||||
|
||||
while (no_of_edges > 0)
|
||||
{
|
||||
u = minimum(E_t, V);
|
||||
while (V_t[u] == 1)
|
||||
{
|
||||
E_t[u] = INF;
|
||||
u = minimum(E_t, V);
|
||||
}
|
||||
|
||||
v = path[u];
|
||||
MST[v][u] = E_t[u];
|
||||
MST[u][v] = E_t[u];
|
||||
no_of_edges--;
|
||||
V_t[u] = 1;
|
||||
|
||||
for (uint16_t i = 1; i < V; i++)
|
||||
{
|
||||
if (V_t[i] == 0 && G[u][i] < E_t[i])
|
||||
{
|
||||
E_t[i] = G[u][i];
|
||||
path[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Self-test implementations
|
||||
* @returns void
|
||||
*/
|
||||
static void test(uint16_t G[][MAX], uint16_t MST[][MAX], uint16_t V)
|
||||
{
|
||||
|
||||
uint16_t test[4][4] = {{0,1,2,3},{1,0,4,6},{2,4,0,5},{3,6,5,0}};
|
||||
uint16_t solution[4][4] = {{0,1,2,3},{1,0,0,0},{2,0,0,0},{3,0,0,0}};
|
||||
|
||||
V = 4;
|
||||
|
||||
for(uint16_t i = 0; i < V; ++i)
|
||||
{
|
||||
for(uint16_t j = 0; j < V; ++j)
|
||||
{
|
||||
G[i][j] = test[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
prim(&(*G),&(*MST),V);
|
||||
|
||||
for(uint16_t i = 0; i < V; ++i)
|
||||
{
|
||||
for(uint16_t j = 0; j < V; ++j)
|
||||
{
|
||||
assert(MST[i][j] == solution[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function user_graph();
|
||||
* gets user input adj. matrix and finds MST of that graph
|
||||
* @returns void
|
||||
*/
|
||||
void user_graph(uint16_t G[][MAX], uint16_t MST[][MAX], uint16_t V)
|
||||
{
|
||||
printf("Enter the number of vertices: ");
|
||||
scanf(" %hd", &V);
|
||||
|
||||
assert(V <= MAX);
|
||||
|
||||
printf("Enter the adj matrix\n");
|
||||
uint16_t i, j;
|
||||
for (i = 0; i < V; ++i)
|
||||
{
|
||||
for (j = 0; j < V; ++j)
|
||||
{
|
||||
printf("G[%d][%d]: ", i, j);
|
||||
scanf(" %hd", &G[i][j]);
|
||||
if (G[i][j] == 0)
|
||||
G[i][j] = INF;
|
||||
}
|
||||
}
|
||||
|
||||
prim(&(*G),&(*MST),V);
|
||||
|
||||
printf("minimum spanning tree:\n");
|
||||
for (i = 0; i < V; ++i)
|
||||
{
|
||||
printf("\n");
|
||||
for (j = 0; j < V; ++j)
|
||||
{
|
||||
printf("%d\t", MST[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @param argc commandline argument count (ignored)
|
||||
* @param argv commandline array of arguments (ignored)
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
|
||||
uint16_t G[MAX][MAX]; ///< weighted, connected graph G
|
||||
uint16_t MST[MAX][MAX]; ///< adj matrix to hold minimum spanning tree of G
|
||||
uint16_t V; ///< number of vertices in V in G
|
||||
|
||||
|
||||
if(argc == 2 && strcmp(argv[1],"-test") == 0)
|
||||
{
|
||||
test(&(*G),&(*MST),V);
|
||||
}
|
||||
else
|
||||
{
|
||||
user_graph(&(*G),&(*MST),V);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user