I have done a lot of research and it seems that all of the examples are using an adjacency list to store the graph, and that seems to change how to find cycles within the graph. I am storing a graph using an adjacency matrix. This is the code for my graph. The isCyclic functions are what I have found, but don't work with an adjacency matrix, they also don't print the cycles.
#pragma once
#include"edge1.h"
#include <string>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <vector>
using namespace std;
class Graph
{
public:
Graph(string f);
void display();
void computeTour();
bool isCyclic();
private:
char getChar(int n) { return (n + 'A'); }
int getInt(char c) { return (c - 'A'); }
void markCycles();
void createGraphFromFile(string file);
void addEdge(char a, char b);
bool isCyclicUtil(int v, bool* visited, int parent);
int totalNodes;
int totalEdges;
int **adj;
bool *visited;
vector<Edge> edges;
};
Graph::Graph(string f)
{
createGraphFromFile(f);
}
void Graph::createGraphFromFile(string file)
{
fstream fin;
fin.open(file);
fin >> totalNodes >> totalEdges;
visited = new bool[totalNodes];
adj = new int*[totalNodes];
for (int i = 0; i < totalNodes; i++)
{
adj[i] = new int[totalNodes];
for (int j = 0; j < totalNodes; j++)
{
adj[i][j] = 0;
}
}
char a, b;
while (fin >> a >> b)
{
addEdge(a,b);
}
fin.close();
}
void Graph::addEdge(char a, char b)
{
Edge e;
e.set(a, b);
edges.push_back(e);
int x = getInt(a);
int y = getInt(b);
if (x > totalNodes || y > totalNodes || x < 0 || y < 0)
{
cout << "Invalid edge!\n";
}
adj[x][y] = 1;
adj[y][x] = 1;
}
bool Graph::isCyclicUtil(int v, bool* visited, int parent)
{
visited[v] = true;
for (int i = 0; i < totalNodes; i++)
{
if (!visited[i])
{
if (isCyclicUtil(i, visited, v))
return true;
}
else if (i != parent)
return true;
}
return false;
}
bool Graph::isCyclic()
{
for (int i = 0; i < totalEdges; i++)
visited[i] = false;
for (int i = 0; i < totalEdges; i++)
{
if (!visited[i])
if (isCyclicUtil(i, visited, -1))
return true;
}
return false;
}
There is also an edge class that holds info about the edges:
#include <sstream>
#include <assert.h>
using namespace std;
class Edge
{ public:
int toNode; // Subscript of one endpoint in node array. Nodes are stored as numbers, but printed as characters.
int fromNode; // Subscript of other endpoint in node array
int cycleID; // Cycle which the edge is a member of, -1 if it is included in no cycle
bool used; // true if edge is used in final tour
// Create a string version of Edge
// Edge endpoints are stored as numbers, but printed as characters.
string toString()
{ ostringstream os; // allows string to act like stream to use stream operations
char t = toNode + 'A';
char f = fromNode + 'A';
os << " "<<f << "-"<<t << "(" << cycleID << ")" ;
return os.str();
}
// if oneNode is an endpoint, return other endpoint
int getOtherEndpoint(int oneNode)
{ if (fromNode==oneNode) return toNode;
assert(toNode==oneNode);
return fromNode;
}
// Set initial values of an edge from Node f to Node t
void set(char f, char t)
{ fromNode = f -'A';
toNode = t-'A';
cycleID = -1;
used = false;
cout << "creating Edge " << toString()<<endl;
}
};
The graph I am working with has 7 nodes and 9 edges. Here is the output when creating the graph, just for reference. The (-1) is just the cycle ID for each edge, as they are all just being created, they don't belong to a cycle yet. That is where I need help.
creating Edge A-B(-1)
creating Edge B-C(-1)
creating Edge C-A(-1)
creating Edge A-E(-1)
creating Edge E-D(-1)
creating Edge D-A(-1)
A B C D E
A 0 1 1 1 1
B 1 0 1 0 0
C 1 1 0 0 0
D 1 0 0 0 1
E 1 0 0 1 0
I can't figure out how to traverse the graph and find and print all of the cycles.