I have a Directed Cyclic Graph and need to find longest path from point A to point B. The graph is a 2D array. I already wrote code that can find longest path in Acyclic Graph, but when I change the graph to the Cyclic one it doesn't work. Here's the code:
#include <iostream>
#include <queue>
#include <list>
#include <stack>
#include <limits.h>
#define NINF INT_MIN
//#define NINF -1
struct vec2 {
int x, y;
};
class AdjListNode {
vec2 v;
int weight;
public:
AdjListNode(vec2 _v, int _w)
{
v.x = _v.x;
v.y = _v.y;
weight = _w;
}
vec2 getV() { return {v.x, v.y}; }
int getWeight() { return weight; }
};
class Graph {
vec2 V;
std::list<AdjListNode> adj[8][8];
void topologicalSortUtil(vec2 v, bool visited[8][8], std::stack<vec2>& Stack);
public:
Graph(int V_x, int V_y);
~Graph();
void addEdge(vec2 u, vec2 v, int weight);
void longestPath(vec2 s);
};
Graph::Graph(int V_x, int V_y)
{
V.x = V_x;
V.y = V_y;
}
Graph::~Graph()
{
}
void Graph::addEdge(vec2 u, vec2 v, int weight)
{
if (v.x == 0 && v.y == 0) //So we have no edge back to the root node
return;
AdjListNode node(v, weight);
adj[u.x][u.y].push_back(node);
}
void Graph::topologicalSortUtil(vec2 v, bool visited[8][8], std::stack<vec2>& Stack)
{
visited[v.x][v.y] = true;
std::list<AdjListNode>::iterator i;
for (i = adj[v.x][v.y].begin(); i != adj[v.x][v.y].end(); i++) {
AdjListNode node = *i;
if (!visited[node.getV().x][node.getV().y])
{
topologicalSortUtil({ node.getV().x, node.getV().y }, visited, Stack);
}
}
Stack.push(v);
}
void Graph::longestPath(vec2 s)
{
std::stack<vec2> Stack;
int dist[8][8];
std::vector<vec2> path;
vec2 pred[8][8];
bool visited[8][8];
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
visited[i][j] = false;
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
if (visited[i][j] == false)
topologicalSortUtil({ i, j }, visited, Stack);
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
dist[i][j] = NINF;
dist[s.x][s.y] = 0;
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
pred[i][j] = {NINF, NINF};
while (Stack.empty() == false) {
vec2 u = Stack.top();
Stack.pop();
std::list<AdjListNode>::iterator i;
if (dist[u.x][u.y] != NINF) {
for (i = adj[u.x][u.y].begin(); i != adj[u.x][u.y].end(); i++) {
if (dist[i->getV().x][i->getV().y] < dist[u.x][u.y] + i->getWeight())
{
dist[i->getV().x][i->getV().y] = dist[u.x][u.y] + i->getWeight();
pred[i->getV().x][i->getV().y].x = u.x;
pred[i->getV().x][i->getV().y].y = u.y;
}
}
}
}
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
(dist[i][j] == NINF) ? std::wcout << "INF " : std::wcout << "dist[" << i << "][" << j << "] :" << dist[i][j] << " ";
int maxDist = 0;
vec2 nodeIdx;
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
{
if (dist[i][j] > maxDist)
{
maxDist = dist[i][j];
nodeIdx.x = i;
nodeIdx.y = j;
}
}
std::wcout << "\nmaxDist: " << maxDist << "\n";
std::wcout << "nodeIdx: {" << nodeIdx.x << "," << nodeIdx.y << "} \n";
for (int i = 0; i < V.x; i++)
for (int j = 0; j < V.y; j++)
std::wcout << "pred[" << i << "][" << j <<"] :" << "{" << pred[i][j].x << "," << pred[i][j].y << "}\n";
vec2 crawl = {nodeIdx.x, nodeIdx.y};
path.push_back(crawl);
while ((pred[crawl.x][crawl.y].x != NINF) &&
(pred[crawl.x][crawl.y].y != NINF))
{
path.push_back(pred[crawl.x][crawl.y]);
crawl = pred[crawl.x][crawl.y];
}
std::wcout << "\nPath is::\n";
for (int i = path.size() - 1; i >= 0; i--)
std::wcout << "{" << path[i].x << "," << path[i].y << "} ";
}
int main()
{
Graph g(8, 8);
//This is a test graph
//This acyclic graph works just fine and returns the longest path
g.addEdge({ 0, 0 }, { 1, 1 }, 1);
g.addEdge({ 0, 0 }, { 3, 3 }, 1);
g.addEdge({ 0, 0 }, { 7, 7 }, 1);
g.addEdge({ 1, 1 }, { 2, 2 }, 1);
g.addEdge({ 3, 3 }, { 4, 4 }, 1);
g.addEdge({ 3, 3 }, { 7, 7 }, 1);
g.addEdge({ 4, 4 }, { 5, 5 }, 1);
g.addEdge({ 4, 4 }, { 6, 6 }, 1);
g.addEdge({ 4, 4 }, { 7, 7 }, 1);
g.addEdge({ 5, 5 }, { 6, 6 }, 1);
g.addEdge({ 6, 6 }, { 7, 7 }, 1);
//But when I add this and make the graph cyclic it doesn't work as intended
//g.addEdge({ 2, 2 }, { 0, 0 }, 1);
//g.addEdge({ 2, 2 }, { 3, 3 }, 1);
//g.addEdge({ 3, 3 }, { 2, 2 }, 1);
vec2 s = {0, 0};
std::wcout << "Following are longest distances from source vertex {"
<< s.x << "," << s.y << "}\n";
g.longestPath(s);
return 0;
}
The code was taken from: https://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/ and modified to take 2D points as input instead of 1D points. The code was also modified based on: https://www.geeksforgeeks.org/shortest-path-unweighted-graph/ and https://www.geeksforgeeks.org/longest-path-undirected-tree/ to show the actual path instead of distance
That is my final graph/2D array that I need to get the longest path from
g.addEdge({0,0}, {1,1},1);
g.addEdge({0,0}, {2,2},1);
g.addEdge({0,0}, {3,3},1);
g.addEdge({0,0}, {4,4},1);
g.addEdge({0,0}, {5,5},1);
g.addEdge({0,0}, {6,6},1);
g.addEdge({0,0}, {7,7},1);
g.addEdge({0,1}, {1,0},1);
g.addEdge({0,2}, {1,2},1);
g.addEdge({0,2}, {2,2},1);
g.addEdge({0,2}, {3,2},1);
g.addEdge({0,2}, {4,2},1);
g.addEdge({0,2}, {5,2},1);
g.addEdge({0,2}, {6,2},1);
g.addEdge({0,2}, {7,2},1);
g.addEdge({0,3}, {0,4},1);
g.addEdge({0,3}, {0,5},1);
g.addEdge({0,3}, {0,6},1);
g.addEdge({0,3}, {0,7},1);
g.addEdge({0,4}, {1,4},1);
g.addEdge({0,4}, {2,4},1);
g.addEdge({0,4}, {3,4},1);
g.addEdge({0,4}, {4,4},1);
g.addEdge({0,4}, {5,4},1);
g.addEdge({0,4}, {6,4},1);
g.addEdge({0,4}, {7,4},1);
g.addEdge({0,5}, {0,6},1);
g.addEdge({0,5}, {0,7},1);
g.addEdge({0,6}, {1,5},1);
g.addEdge({0,6}, {2,4},1);
g.addEdge({0,6}, {3,3},1);
g.addEdge({0,6}, {4,2},1);
g.addEdge({0,6}, {5,1},1);
g.addEdge({0,6}, {6,0},1);
g.addEdge({0,7}, {1,7},1);
g.addEdge({0,7}, {2,7},1);
g.addEdge({0,7}, {3,7},1);
g.addEdge({0,7}, {4,7},1);
g.addEdge({0,7}, {5,7},1);
g.addEdge({0,7}, {6,7},1);
g.addEdge({0,7}, {7,7},1);
g.addEdge({1,0}, {1,1},1);
g.addEdge({1,0}, {1,2},1);
g.addEdge({1,0}, {1,3},1);
g.addEdge({1,0}, {1,4},1);
g.addEdge({1,0}, {1,5},1);
g.addEdge({1,0}, {1,6},1);
g.addEdge({1,0}, {1,7},1);
g.addEdge({1,1}, {1,2},1);
g.addEdge({1,1}, {1,3},1);
g.addEdge({1,1}, {1,4},1);
g.addEdge({1,1}, {1,5},1);
g.addEdge({1,1}, {1,6},1);
g.addEdge({1,1}, {1,7},1);
g.addEdge({1,2}, {0,2},1);
g.addEdge({1,3}, {2,3},1);
g.addEdge({1,3}, {3,3},1);
g.addEdge({1,3}, {4,3},1);
g.addEdge({1,3}, {5,3},1);
g.addEdge({1,3}, {6,3},1);
g.addEdge({1,3}, {7,3},1);
g.addEdge({1,4}, {0,4},1);
g.addEdge({1,5}, {2,5},1);
g.addEdge({1,5}, {3,5},1);
g.addEdge({1,5}, {4,5},1);
g.addEdge({1,5}, {5,5},1);
g.addEdge({1,5}, {6,5},1);
g.addEdge({1,5}, {7,5},1);
g.addEdge({1,6}, {2,7},1);
g.addEdge({1,7}, {0,6},1);
g.addEdge({2,0}, {2,1},1);
g.addEdge({2,0}, {2,2},1);
g.addEdge({2,0}, {2,3},1);
g.addEdge({2,0}, {2,4},1);
g.addEdge({2,0}, {2,5},1);
g.addEdge({2,0}, {2,6},1);
g.addEdge({2,0}, {2,7},1);
g.addEdge({2,1}, {3,1},1);
g.addEdge({2,1}, {4,1},1);
g.addEdge({2,1}, {5,1},1);
g.addEdge({2,1}, {6,1},1);
g.addEdge({2,1}, {7,1},1);
g.addEdge({2,2}, {2,1},1);
g.addEdge({2,2}, {2,0},1);
g.addEdge({2,3}, {3,2},1);
g.addEdge({2,3}, {4,1},1);
g.addEdge({2,3}, {5,0},1);
g.addEdge({2,4}, {1,3},1);
g.addEdge({2,4}, {0,2},1);
g.addEdge({2,5}, {2,6},1);
g.addEdge({2,5}, {2,7},1);
g.addEdge({2,6}, {3,6},1);
g.addEdge({2,6}, {4,6},1);
g.addEdge({2,6}, {5,6},1);
g.addEdge({2,6}, {6,6},1);
g.addEdge({2,6}, {7,6},1);
g.addEdge({2,7}, {2,6},1);
g.addEdge({2,7}, {2,5},1);
g.addEdge({2,7}, {2,4},1);
g.addEdge({2,7}, {2,3},1);
g.addEdge({2,7}, {2,2},1);
g.addEdge({2,7}, {2,1},1);
g.addEdge({2,7}, {2,0},1);
g.addEdge({3,0}, {4,1},1);
g.addEdge({3,0}, {5,2},1);
g.addEdge({3,0}, {6,3},1);
g.addEdge({3,0}, {7,4},1);
g.addEdge({3,1}, {4,2},1);
g.addEdge({3,1}, {5,3},1);
g.addEdge({3,1}, {6,4},1);
g.addEdge({3,1}, {7,5},1);
g.addEdge({3,2}, {4,3},1);
g.addEdge({3,2}, {5,4},1);
g.addEdge({3,2}, {6,5},1);
g.addEdge({3,2}, {7,6},1);
g.addEdge({3,3}, {2,2},1);
g.addEdge({3,3}, {1,1},1);
g.addEdge({3,4}, {4,4},1);
g.addEdge({3,4}, {5,4},1);
g.addEdge({3,4}, {6,4},1);
g.addEdge({3,4}, {7,4},1);
g.addEdge({3,5}, {2,5},1);
g.addEdge({3,5}, {1,5},1);
g.addEdge({3,5}, {0,5},1);
g.addEdge({3,6}, {4,5},1);
g.addEdge({3,6}, {5,4},1);
g.addEdge({3,6}, {6,3},1);
g.addEdge({3,6}, {7,2},1);
g.addEdge({3,7}, {2,7},1);
g.addEdge({3,7}, {1,7},1);
g.addEdge({3,7}, {0,7},1);
g.addEdge({4,0}, {3,0},1);
g.addEdge({4,0}, {2,0},1);
g.addEdge({4,0}, {1,0},1);
g.addEdge({4,1}, {4,2},1);
g.addEdge({4,1}, {4,3},1);
g.addEdge({4,1}, {4,4},1);
g.addEdge({4,1}, {4,5},1);
g.addEdge({4,1}, {4,6},1);
g.addEdge({4,1}, {4,7},1);
g.addEdge({4,2}, {3,3},1);
g.addEdge({4,2}, {2,4},1);
g.addEdge({4,2}, {1,5},1);
g.addEdge({4,2}, {0,6},1);
g.addEdge({4,3}, {3,2},1);
g.addEdge({4,3}, {2,1},1);
g.addEdge({4,3}, {1,0},1);
g.addEdge({4,4}, {5,5},1);
g.addEdge({4,4}, {6,6},1);
g.addEdge({4,4}, {7,7},1);
g.addEdge({4,5}, {5,6},1);
g.addEdge({4,5}, {6,7},1);
g.addEdge({4,6}, {3,5},1);
g.addEdge({4,6}, {2,4},1);
g.addEdge({4,6}, {1,3},1);
g.addEdge({4,6}, {0,2},1);
g.addEdge({4,7}, {5,7},1);
g.addEdge({4,7}, {6,7},1);
g.addEdge({4,7}, {7,7},1);
g.addEdge({5,0}, {4,0},1);
g.addEdge({5,0}, {3,0},1);
g.addEdge({5,0}, {2,0},1);
g.addEdge({5,0}, {1,0},1);
g.addEdge({5,1}, {5,2},1);
g.addEdge({5,1}, {5,3},1);
g.addEdge({5,1}, {5,4},1);
g.addEdge({5,1}, {5,5},1);
g.addEdge({5,1}, {5,6},1);
g.addEdge({5,1}, {5,7},1);
g.addEdge({5,2}, {6,1},1);
g.addEdge({5,2}, {7,0},1);
g.addEdge({5,3}, {6,3},1);
g.addEdge({5,3}, {7,3},1);
g.addEdge({5,4}, {4,4},1);
g.addEdge({5,4}, {3,4},1);
g.addEdge({5,4}, {2,4},1);
g.addEdge({5,4}, {1,4},1);
g.addEdge({5,4}, {0,4},1);
g.addEdge({5,5}, {6,5},1);
g.addEdge({5,5}, {7,5},1);
g.addEdge({5,6}, {4,6},1);
g.addEdge({5,6}, {3,6},1);
g.addEdge({5,6}, {2,6},1);
g.addEdge({5,6}, {1,6},1);
g.addEdge({5,6}, {0,6},1);
g.addEdge({5,7}, {5,6},1);
g.addEdge({5,7}, {5,5},1);
g.addEdge({5,7}, {5,4},1);
g.addEdge({5,7}, {5,3},1);
g.addEdge({5,7}, {5,2},1);
g.addEdge({5,7}, {5,1},1);
g.addEdge({5,7}, {5,0},1);
g.addEdge({6,0}, {6,1},1);
g.addEdge({6,0}, {6,2},1);
g.addEdge({6,0}, {6,3},1);
g.addEdge({6,0}, {6,4},1);
g.addEdge({6,0}, {6,5},1);
g.addEdge({6,0}, {6,6},1);
g.addEdge({6,0}, {6,7},1);
g.addEdge({6,1}, {6,2},1);
g.addEdge({6,1}, {6,3},1);
g.addEdge({6,1}, {6,4},1);
g.addEdge({6,1}, {6,5},1);
g.addEdge({6,1}, {6,6},1);
g.addEdge({6,1}, {6,7},1);
g.addEdge({6,2}, {6,3},1);
g.addEdge({6,2}, {6,4},1);
g.addEdge({6,2}, {6,5},1);
g.addEdge({6,2}, {6,6},1);
g.addEdge({6,2}, {6,7},1);
g.addEdge({6,3}, {6,4},1);
g.addEdge({6,3}, {6,5},1);
g.addEdge({6,3}, {6,6},1);
g.addEdge({6,3}, {6,7},1);
g.addEdge({6,4}, {6,5},1);
g.addEdge({6,4}, {6,6},1);
g.addEdge({6,4}, {6,7},1);
g.addEdge({6,5}, {5,4},1);
g.addEdge({6,5}, {4,3},1);
g.addEdge({6,5}, {3,2},1);
g.addEdge({6,5}, {2,1},1);
g.addEdge({6,5}, {1,0},1);
g.addEdge({6,6}, {6,5},1);
g.addEdge({6,6}, {6,4},1);
g.addEdge({6,6}, {6,3},1);
g.addEdge({6,6}, {6,2},1);
g.addEdge({6,6}, {6,1},1);
g.addEdge({6,6}, {6,0},1);
g.addEdge({6,7}, {5,7},1);
g.addEdge({6,7}, {4,7},1);
g.addEdge({6,7}, {3,7},1);
g.addEdge({6,7}, {2,7},1);
g.addEdge({6,7}, {1,7},1);
g.addEdge({6,7}, {0,7},1);
g.addEdge({7,0}, {6,1},1);
g.addEdge({7,0}, {5,2},1);
g.addEdge({7,0}, {4,3},1);
g.addEdge({7,0}, {3,4},1);
g.addEdge({7,0}, {2,5},1);
g.addEdge({7,0}, {1,6},1);
g.addEdge({7,0}, {0,7},1);
g.addEdge({7,1}, {6,1},1);
g.addEdge({7,1}, {5,1},1);
g.addEdge({7,1}, {4,1},1);
g.addEdge({7,1}, {3,1},1);
g.addEdge({7,1}, {2,1},1);
g.addEdge({7,1}, {1,1},1);
g.addEdge({7,1}, {0,1},1);
g.addEdge({7,2}, {6,2},1);
g.addEdge({7,2}, {5,2},1);
g.addEdge({7,2}, {4,2},1);
g.addEdge({7,2}, {3,2},1);
g.addEdge({7,2}, {2,2},1);
g.addEdge({7,2}, {1,2},1);
g.addEdge({7,2}, {0,2},1);
g.addEdge({7,3}, {6,3},1);
g.addEdge({7,3}, {5,3},1);
g.addEdge({7,3}, {4,3},1);
g.addEdge({7,3}, {3,3},1);
g.addEdge({7,3}, {2,3},1);
g.addEdge({7,3}, {1,3},1);
g.addEdge({7,3}, {0,3},1);
g.addEdge({7,4}, {6,4},1);
g.addEdge({7,4}, {5,4},1);
g.addEdge({7,4}, {4,4},1);
g.addEdge({7,4}, {3,4},1);
g.addEdge({7,4}, {2,4},1);
g.addEdge({7,4}, {1,4},1);
g.addEdge({7,4}, {0,4},1);
g.addEdge({7,5}, {7,6},1);
g.addEdge({7,5}, {7,7},1);
g.addEdge({7,6}, {7,5},1);
g.addEdge({7,6}, {7,4},1);
g.addEdge({7,6}, {7,3},1);
g.addEdge({7,6}, {7,2},1);
g.addEdge({7,6}, {7,1},1);
g.addEdge({7,6}, {7,0},1);
The graph has 64 points each having from 1 to 7 edges (connections). Last point {7, 7} has no connections going out and only connections going to that point. Some points have connections to each other, for example point {5, 2} connects to point {7, 0} and point {7, 0} connects to point {5, 2}. Also the path needs to go from Point {0, 0} to Point {7, 7} and ideally reach every point.
The fact that the longest path is from point {0, 0} to point {7, 7} and that the path goes through every point is sure. But I need to get the exact path
Now the program show that the longest path from point {0, 0} is to point {0, 4} which isn't true.
Already tried to find solution online, found some Stack Overflow questions, but the answers didn't satisfy my because most of them were very general and explaining only concepts which I couldn't in 100% understand and thus implement.