Найти и распечатать циклы в неориентированном графе, который хранится с использованием матрицы смежности - PullRequest
0 голосов
/ 24 апреля 2018

Я провел много исследований, и кажется, что все примеры используют список смежности для хранения графа, и это, похоже, меняет способ нахождения циклов внутри графа. Я храню граф, используя матрицу смежности. Это код для моего графика. Я нашел функции 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

Я не могу понять, как пройти по графику, найти и напечатать все циклы.

...