Я провел много исследований, и кажется, что все примеры используют список смежности для хранения графа, и это, похоже, меняет способ нахождения циклов внутри графа. Я храню график, используя матрицу смежности. Это код для моего графика. Я обнаружил функции isCyclic, но они не работают с матрицей смежности, они также не печатают циклы.
#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;
}
Существует также класс ребер, который содержит информацию о ребрах:
#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;
}
};
Граф, с которым я работаю, имеет 7 узлов и 9 ребер. Вот вывод при создании графика, просто для справки. (-1) — это просто идентификатор цикла для каждого ребра, так как все они только что созданы, они еще не принадлежат циклу. Вот где мне нужна помощь.
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
Я не могу понять, как пройти по графику и найти и напечатать все циклы.
Задача ещё не решена.
Других решений пока нет …