Reachability in graph - C - c

I have implemented my graph in adjacency list. How can I estimate one vertex reachability from another when user provides indexes?
int isReachable(int nodes, int graph[nodes][nodes], int src, int dest)
Checking for direct neighbors is easy, but I struggle with implementing algorithm as whole.

Code from: http://www.geeksforgeeks.org/transitive-closure-of-a-graph/
int reach[V][V], i, j, k;
/* Initialize the solution matrix same as input graph matrix. Or
we can say the initial values of shortest distances are based
on shortest paths considering no intermediate vertex. */
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
reach[i][j] = graph[i][j];
/* Add all vertices one by one to the set of intermediate vertices.
---> Before start of a iteration, we have reachability values for
all pairs of vertices such that the reachability values
consider only the vertices in set {0, 1, 2, .. k-1} as
intermediate vertices.
----> After the end of a iteration, vertex no. k is added to the
set of intermediate vertices and the set becomes {0, 1, .. k} */
for (k = 0; k < V; k++)
{
// Pick all vertices as source one by one
for (i = 0; i < V; i++)
{
// Pick all vertices as destination for the
// above picked source
for (j = 0; j < V; j++)
{
// If vertex k is on a path from i to j,
// then make sure that the value of reach[i][j] is 1
reach[i][j] = reach[i][j] || (reach[i][k] && reach[k][j]);
}
}
}
// Print the shortest distance matrix
printSolution(reach);
}

Related

Unable to implement Dijkstra's Algorithm using OpenMP in C

I am trying to parallelize Dijkstra using OpenMP, but the program is not working correctly. Sometimes the correct results are displayed while other times I get wrong values, I assume this is because multiple threads are updating the same variable. However I cannot find the source of this problem because I am making shared variable updates inside critical regions. Can someone please help me identify what mistake am I making my assignment is due soon and is this code conceptually correct?
int minDistance(int s,int e,int dist[], bool sptSet[])
{
// Initialize min value
int mini = INT_MAX, min_index;
for (int v = s; v <= e; v++){
if (sptSet[v] == false && dist[v] < mini){
mini = dist[v];
min_index = v;
}
//printf("min_ind %d\n",min_index);
}
return min_index;
}
void Update(int graph[V][V],int s,int e,int hold,int dist[], bool sptSet[]){
for (int v = s; v <= e; v++){
// Update dist[v] only if is not in sptSet,
// there is an edge from u to v, and total
// weight of path from src to v through u is
// smaller than current value of dist[v]
if (!sptSet[v] && graph[hold][v] && dist[hold] != INT_MAX && dist[hold] + graph[hold][v] < dist[v]){
dist[v] = dist[hold] + graph[hold][v];
}
}
}
void dijkstra(int graph[V][V],int src)
{
int dist[V]; // The output array. dist[i] will hold the
// shortest
// distance from src to i
bool sptSet[V]; // sptSet[i] will be true if vertex i is
// included in shortest
// path tree or shortest distance from src to i is
// finalized
// Initialize all distances as INFINITE and stpSet[] as
// false
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
// Distance of source vertex from itself is always 0
dist[src] = 0;
int min;
int hold;
int u;
// Find shortest path for all vertices
float start = omp_get_wtime();
#pragma omp parallel shared(hold) private(u) num_threads(3)
{
min=INT_MAX;
int x = omp_get_num_threads();
int chunk = V/x;
int me = omp_get_thread_num();
int startv = me * chunk;
int endv = startv + chunk - 1;
int count = 0;
for (count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex from the set of
// vertices not yet processed. u is always equal to
// src in the first iteration.
u = minDistance(startv,endv,dist, sptSet);
//updating overall minimum
#pragma omp critical
{
if(min > dist[u]){
min = dist[u];
hold = u;
}
}
//waiting for all threads to execute critical section bfr proceeding
#pragma omp barrier
// Mark the picked vertex as processed
#pragma omp single
{
sptSet[hold] = true;
}
#pragma omp barrier
// Update dist value of the adjacent vertices of the
// picked vertex.
Update(graph,startv,endv,hold,dist,sptSet);
min = INT_MAX;
}
}
float end = omp_get_wtime();
// print the constructed distance array
printSolution(dist);
printf("Running time: %f ms\n", (end - start)*1000);
}
----------------THE SERIAL CODE:--------------------
int minDistance(int dist[], bool sptSet[])
{
// Initialize min value
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
// A utility function to print the constructed distance
// array
void printSolution(int dist[])
{
printf("Vertex \t\t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t\t\t %d\n", i, dist[i]);
}
// Function that implements Dijkstra's single source
// shortest path algorithm for a graph represented using
// adjacency matrix representation
void dijkstra(int graph[V][V], int src)
{
int dist[V]; // The output array. dist[i] will hold the
// shortest
// distance from src to i
bool sptSet[V]; // sptSet[i] will be true if vertex i is
// included in shortest
// path tree or shortest distance from src to i is
// finalized
// Initialize all distances as INFINITE and stpSet[] as
// false
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
// Distance of source vertex from itself is always 0
dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex from the set of
// vertices not yet processed. u is always equal to
// src in the first iteration.
int u = minDistance(dist, sptSet);
// Mark the picked vertex as processed
sptSet[u] = true;
// Update dist value of the adjacent vertices of the
// picked vertex.
for (int v = 0; v < V; v++)
{
// Update dist[v] only if is not in sptSet,
// there is an edge from u to v, and total
// weight of path from src to v through u is
// smaller than current value of dist[v]
if (!sptSet[v] && graph[u][v]
&& dist[u] != INT_MAX
&& dist[u] + graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}
}
// print the constructed distance array
printSolution(dist);
}
Dijkstra's algorithm is a good example of an algorithm where the standard formulation is very hard to parallelize. Every step of 1. finding the minimum 2. updating its neighbors depends on the previous. Therefore the best you can do is 1. making that minimum into an OpenMP reduction 2. making the update into a parallel loop. On graphs with small degree this will not give you much speedup. It also means taht your code is not correct: you are trying to parallelize over the outer steps, which are sequential.
However, you don't have to update only the neighbors of that minimum point: you can update all points in every step. That simplifies the code, and reduces overhead. It also does more work, but in wall clock time it may finish slightly faster.

A question regarding making ordered pairs from every element in an array

I was curious about how I could possibly iterate through an array, and keep track of every single possible ordered pair.
To create a problem to illustrate this; lets say I have a function that takes in an input array, the length of that array and a "target" which is the product of 2 values, and outputs an array consisting of the indices of the input array that you need to multiply in order to get the "target".
int* multipairs(int* inputarray, int arraysize, int target){
/code
}
For example:
Given an array, arr = [2, 5, 1, 9, 1, 0, 10, 2], and target = 50
It should return output = [1,6].
In my mind, I would iterate through the arrays as follow;
(0,1) -> (0,2) -> (0,3) -> (0,4)....
In the second pass I would do:
(1,2) -> (1,3) -> (1,4)...
.
.
.
and so on
I have the idea of what I want to do, but I am unfamiliar with C programming, and have no idea how to make a proper for loop. Please help me figure this out.
Your description of the algorithm is complete - as you say, the first item in the pair is iterating over all the array indices. For each of those, you want to iterate over all the pairs that follow that in the array.
for (int i = 0, i < arraysize; i++)
{
for (int j = i + 1; j < arraysize; j++)
{
// operate on pair array[i] and array[j]
}
}
You can use nested for-loops to solve your problem.
int* multipairs(int* inputarray, int arraysize, int target){
int i, j, k = -1;
/*
Maximum number of such pairs can be arraysize*(arraysize-1)/2
Since, for each pair we store two indices (0-indexed),
maximum size of output array will be arraysize*(arraysize-1)
*/
int maxsize = arraysize*(arraysize-1);
int *output = (int*)malloc(sizeof(int)*maxsize);
for (i = 0, i < arraysize; i++){
for (j = i + 1; j < arraysize; j++){
if(inputarray[i] * inputarray[j] == target){
output[++k] = i;
output[++k] = j;
}
}
}
return output;
}

generating graph with random edges

I am trying to write a c/c++ program that uses Disjoint Sets using union by rank and path compression Graph Algorithm then apply Kruskal's algorithm on that graph.I already generated number_of_vertices-1 pairs (0,1),(1,2)...(n-2,n-1) as edges in the graph in order to make the graph connected. I need to generate the rest of 3*number_Of_Vertices+1 random edges as pairs of (vertex1,vertex2) without collisions(the same edge shall not be generated twice). I have to do this without using extra memory. By extra memory i mean an extra list, vector...Do you guyz have any idea how to do this?
This is what i did until now but it surely has collisions:
edge** createRandomEdges(nodeG **nodeArray, int n) {
edge **edgeArray = (edge**)malloc(sizeof(edge*)*n * 4);
for (int i = 0; i < n; i++)
edgeArray[i] = createEdge(nodeArray[0], nodeArray[i + 1], rand() % 100+1);
for (int i = n; i < 4 * n; i++) {
int nodeAindex = rand() % n;
int nodeBindex = rand() % n;
while (nodeAindex == nodeBindex) {
nodeAindex = rand() % n;
nodeBindex = rand() % n;
}
int weight = rand() % 100 + 1;
edgeArray[i] = createEdge(nodeArray[nodeAindex], nodeArray[nodeBindex], weight);
}
return edgeArray;
}
So you have N edges and want to mark K of them optimizing memory consumption. In this case you can use Reservoir sampling with O(K) memory complexity.
Make an array of integers with size K, fill it with 0..K-1 numbers, then walk a loop and randomly replace some numbers using rules that provide uniformity
ReservoirSample(S[1..n], R[1..k])
// fill the reservoir array
for i = 1 to k
R[i] := S[i]
// replace elements with gradually decreasing probability
for i = k+1 to n
j := random(1, i) // important: inclusive range
if j <= k
R[j] := S[i]

Graph Coloring in C: Unable to identify the logical error

I am trying to implement the graph coloring algorithm in C, this implementation is based on how we assign the colors by iterating through the adjacency matrix. I am unable to get it after assigning a color to the second vertex.
Here is the code of my program:
int n, a[10][10], i, j, k, c[10], max = 0, col, ct = 0, rt = 0, m, count = 2;
void main() {
printf("enter n\n");
scanf("%d", &n);
printf("enter the Adjacency Matrix for %d rows and %d columns\n", n, n);
for (i = 0; i < n; i++) {
c[i] = 0;
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
}
c[0] = 1;
c[1] = 2;
for (i = 1; i < n; i++) {
for (j = 0; j < n; j++)
if (a[i][j] > 0) {
m = 0;
for (col = 0; col < n; col++) {
if (a[i][col] > 0)
rt++;
if (a[col][i] > 0)
ct++;
}
m = rt;
if (ct > rt)
m = ct;
if (m < 2) {
if (a[0][i] > 0)
c[i] = 2;
else
c[i] = 1;
} else {
c[i] = count;
if (m > max) {
max = m;
count++;
}
}
rt = 0;
ct = 0;
}
if (c[i] < 1)
if (c[i - 1] > 1)
c[i] = 1;
else
c[i] = 2;
}
printf("The proper coloring is\n");
for (i = 0; i < n; i++)
printf("c%d=%d ", i + 1, c[i]);
printf("\n");
}
Example Input:
Consider a complete graph:
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0
Expected output:
c1=1 c2=2 c3=3 c4=4
Observed output:
c1=1 c2=2 c3=3 c4=3
The error seems to be in logic, as you may have inferred by the looks of the question title. The conditional statement where you are checking if m is greater than max and then updating max and count accordingly seem to be incorrect.
I could not exactly figure out what the intended logic was, but I can tell why it is incorrect.
In your usage, you keep the maximum number of neighbors you encountered in max, and update it when you find a vertex which has more neighbors. With it, you also update count, which I think holds the color of currently highest value. Now, unless you encounter a vertex with more neighbors at each step(while traversing each row), you don't update max, and therefore you don't update count. Consequently, unless you encounter such a vertex, you keep assigning the same currently highest count to all vertices you encountered.
You should explain some more about the algorithm you implemented. However, just by looking at your code I think you should at least increment count somewhere different.
A good idea might by just keeping an array equal to the number of vertices. Then for each vertex (inside outermost loop) you can reset the array and by traversing all of the neighbors of ith vertex you can set the colors used in them, and pick the smallest unused color.
It is probably not the most efficient way to do it, but you already have an O(n3) algorithm, so I think it wouldn't hurt going this way.
Below is your code, updated to reflect the changes I mentioned.
int n,a[10][10],i,j,k,c[10],max=0,col,ct=0,rt=0,m,count=2;
int used[11]; /* indices used are from 1 to n, inclusive */
void main()
{
printf("enter n\n");
scanf("%d",&n);
printf("enter the Adjacency Matrix for %d rows and %d columns\n",n,n);
for(i=0; i < n ; i++)
{
c[i]=0;
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
}
c[0]=1;
c[1]=2;
for(i = 1 ;i < n;i++)
{
for(j = 1 ;j <= n ;j++)
used[j] = 0;
for(j = 0 ;j < i ;j++)
{
if(a[i][j] > 0)
used[c[j]] = 1;
}
for(j = 1 ;j <= n ;j++)
if(!used[j])
{
c[i] = j;
break;
}
}
printf("The proper coloring is\n");
for(i = 0;i < n ;i++)
printf("c%d=%d ",i+1,c[i]);
printf("\n");
}
What does a straightforward algorithm to colour the verices look like?
Consider all vertices in a loop and assign a colour. Vertices that have been visited already have a colour; vertices that will still be visited are still uncoloured.
Determine which colours are used by adjacent vertices that have already been coloured.
With this information, pick the lowest possible colour.
What does your algorithm look like:
Assign colour 1 to vertex 1 and colour 2 to vertex 2. (Note that vertex 2 can use the same colour as vertex 1 if the two aren't connected.)
Loop over all remaining vertices; then loop over all vertices cnnected to that.
Count the number of incoming and outgoing links to the second vertex in yet another loop. (Note that merely counting the links doesn't give you information on which colours are still available. You could have many vertices coloured with colours 3 and 4, for example, but you base your new colour on the number of links. In this example, colour 1 would be a good choice.)
Your criterion for chosing a new colour is whether the number of links is greater or equal to 2. You then assign the count, but before incrementing it. That gives you the second 3 in your example, where there should be a 4.
So you loop once too many and have a poor criterion for choosing a colour. Instead of counting the lonks, you should keep a list of used colours in adjacent nodes and base your new colour on that list.
Other stylistic issues with your code:
All your variables should be local to main; there's no reason to make them global, especially since you don't use functions.
Please be more systematic with your variable declarations. To have them all slapped together in one large definition, which even claoesces arrays and scalars, make them hard to understand.
Please use braces around all code blocks, even if they are not strictly necessary. It makes reading the code easier. Small if s without an else in the inner block such as if (ct > rt) m = ct; don't need braces, but consider using them everywhere else.

I'm trying to store path in Dijkstra's algorithm

I'm trying to store the path Dijkstra's does when it calculates shortest path to every vertice from the source. This is currently what I'm doing right now but I'm struggling with how to actually store the path. I was hoping if someone can help me. You should also note that currently the u value's are ints and I want to return this specific path as characters. The array size is 26 by 26 as there are 26 characters in the alphabet. A possible path could be C B A, or 2, 1, 0.
void dijkstra(int graph[MAX_ROWS][MAX_COLUMNS], int src){
int dist[MAX_ROWS]; // The output array. dist[i] will hold the shortest distance from src to i
bool sptSet[MAX_ROWS]; // sptSet[i] will true if vertex i is included in shortest path tree or shortest distance from src to i is finalized
int i, count, v;
struct path {
char thepath[40];
} pathArray[MAX_ROWS];
// Initialize all distances as INFINITE and stpSet[] as false
for (i = 0; i < MAX_ROWS; i++)
dist[i] = INT_MAX, sptSet[i] = false;
// Distance of source vertex from itself is always 0
dist[src] = 0;
// Find shortest path for all vertices
for (count = 0; count < MAX_ROWS-1; count++){
// Pick the minimum distance vertex from the set of vertices not
// yet processed. u is always equal to src in first iteration.
int u = minDistance(dist, sptSet);
int baby = u + 'A';
char girl = baby;
printf("Count : %d, u : %c\n", count, girl);
pathArray[v].thepath[v] = girl;
// Mark the picked vertex as processed
sptSet[u] = true;
// Update dist value of the adjacent vertices of the picked vertex.
for (v = 0; v < MAX_ROWS; v++)
// Update dist[v] only if is not in sptSet, there is an edge from
// u to v, and total weight of path from src to v through u is
// smaller than current value of dist[v]
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u]+graph[u][v] < dist[v]){
dist[v] = dist[u] + graph[u][v];
}
}
// print the constructed distance array
printf("Vertex Distance from Source\n");
for (i = 0; i < MAX_ROWS; i++){
if (dist[i] != INT_MAX)
printf("%d \t\t %d Path: %s\n", i, dist[i], pathArray[i].thepath);
}
//printSolution(dist, MAX_ROWS, pathArray.thepath);
}
Your approach of pathArray has some problems:
First, you address the path via the vertex v, but v is uninitialised and it does not have any meaning outside the for loop.
Also, v isn't any meaningful information for the string: It is a vertex id. You also have the distance to the source, but the string index you need requires the number of steps to reach v from the source vertex, which you currently don't store.
Finally, you can only build your paths when all distances have been found, not during pathfinding.
A better approach is to keep an array prev[MAX_ROWS] that stores the vertex id of the vertex that lies directly before this vertex in the shortest path from the source to this vertex. That means you essentially store the path from the destination to the source. You can't do it the other way round, because the paths from the source may fork. Seen from the other end, that means that all paths eventually join when going towards the source, so storing the path as list of previous points is safe.
You set the previous vertex whenever you find a new shortest distance:
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX
&& dist[u]+graph[u][v] < dist[v])
{
dist[v] = dist[u] + graph[u][v];
prev[v] = u;
}
You can then print the path from each vertex i to the source:
v = i;
while (v != src) {
putchar('A' + v);
v = prev[v];
}
putchar('A' + src);
putchar(10);
If you want to store the forward-going path, you can implement a recursive approach or write the path to a string and then reverse it.

Resources