У меня есть неориентированный график, который показан ниже:
Не могли бы вы порекомендовать или указать, какой тип алгоритма графика мне следует применить?
Сначала я подумал, что могу применить алгоритм «Топологическая сортировка», но он идентифицирует сильно связанный компонент, но не циклы?
Я пытался реализовать алгоритм на основе https://www.geeksforgeeks.org/print-all-the-cycles-in-an-undirected-graph/,но он обнаруживает циклы, когда они связаны нециклическими ребрами.
addEdge(1, 2);
addEdge(2, 3);
addEdge(3, 4);
addEdge(4, 6);
addEdge(4, 7);
addEdge(5, 6);
addEdge(3, 5);
addEdge(7, 8);
addEdge(6, 10);
addEdge(5, 9);
addEdge(10, 11);
addEdge(11, 12);
addEdge(11, 13);
addEdge(12, 13);
// arrays required to color the
// graph, store the parent of node
int[] color = new int[N];
int[] par = new int[N];
// mark with unique numbers
int[] mark = new int[N];
// store the numbers of cycle
int cyclenumber = 0;
int edges = 13; //E0.Count
// call DFS to mark the cycles
dfs_cycle(1, 0, color, mark, par, ref cyclenumber);
// function to print the cycles
printCycles(edges, mark, ref cyclenumber);
for (int i = 0; i < N; i++)
{
graph[i] = new List<int>();
cycles[i] = new List<int>();
}
const int N = 100000;
List<int>[] graph = new List<int>[N];
List<int>[] cycles = new List<int>[N];
//function to mark the vertex with
//different collor for different cycles
void dfs_cycle(int u, int p, int[] color, int[] mark, int[] par, ref int cyclenumber){
//already (completely visited vertex)
if(color[u] == 2)
return;
// seen vertex, but was not completely visited -> cycle detected.
// backtrack based on parents to find the complete cycle.
if (color[u] == 1) {
cyclenumber++;
int cur = p;
mark[cur] = cyclenumber;
// backtrack the vertex which are
// in the current cycle thats found
while (cur != u) {
cur = par[cur];
mark[cur] = cyclenumber;
}
return;
}
par[u] = p;
// partially visited.
color[u] = 1;
// simple dfs on graph
foreach (int v in graph[u]) { //[u]
// if it has not been visited previously
if (v == par[u]) {
continue;
}
dfs_cycle(v, u, color, mark, par, ref cyclenumber);
}
// completely visited.
color[u] = 2;
}
// add the edges to the graph
void addEdge(int u, int v)
{
if(graph[u] == null)
graph[u] = new List<int>();
if(graph[v] == null)
graph[v] = new List<int>();
graph[u].Add(v);
graph[v].Add(u);
}
// Function to print the cycles
void printCycles(int edges, int[] mark, ref int cyclenumber)
{
// push the edges that into the
// cycle adjacency list
for (int i = 1; i <= edges; i++) {
if (mark[i] != 0) {
if(cycles[mark[i]] == null)
cycles[mark[i]] = new List<int>();
cycles[mark[i]].Add(i);
}
}
// print all the vertex with same cycle
for (int i = 1; i <= cyclenumber; i++) {
// Print the i-th cycle
Print("Cycle Number " + i.ToString() + ":");
// cout << "Cycle Number " << i << ": ";
foreach (int x in cycles[i])
Print(x.ToString() + " ");
// cout << x << " ";
// cout << endl;
}
}
Имеет узлы 0,1,2,3,4,5,6.А ребро 0-1, 1-0, 0-3, 3-0, 2-3, 3-2, 1-2, 2-1, 3-5, 5-3, 4-5, 5-4,4-5, 2-4, 4-2, 6-4, 4-6, 1-6, 6-1.
Я хотел бы выделить циклы: 0-1-2-3 2-4-5-3 1-6-4-2