Как определить циклы / циклины в необработанном графе? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть неориентированный график, который показан ниже: enter image description here

Не могли бы вы порекомендовать или указать, какой тип алгоритма графика мне следует применить?

Сначала я подумал, что могу применить алгоритм «Топологическая сортировка», но он идентифицирует сильно связанный компонент, но не циклы?

Я пытался реализовать алгоритм на основе 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...