简体   繁体   English

使用邻接矩阵在C ++上的有向图中查找所有循环的算法

[英]Algorithm for finding all cycles in a directed graph on C++ using Adjacency matrix

Given graph adjacency matrix (for ex. g[][]), graph is directed. 给定图邻接矩阵(例如[] [] []),指向图。 Needs find count of all graph cycles (if exists) and print them. 需求找到所有图形周期的计数(如果存在)并打印它们。

I tried to wrote this algorithm in Java, sometimes it works correctly. 我试图用Java编写这个算法,有时它可以正常工作。 If graph has complex cycles, algorithm return crazy cycles. 如果图形具有复杂的周期,则算法返回疯狂周期。 Please, look at my code and help to resolve this problem 请查看我的代码并帮助解决此问题

public static final int k = 6;

public static int g[][] = { { 0, 1, 0, 0, 0, 0 },
                            { 1, 0, 1, 0, 0, 0 },
                            { 0, 0, 0, 1, 0, 0 },
                            { 0, 0, 0, 0, 1, 0 },
                            { 0, 0, 1, 0, 0, 0 },
                            { 0, 0, 0, 0, 0, 0 } };

public static Vector stack = new Vector();

public static void printStack() {
    System.out.print("stack is: { ");
    for (int i = 0; i < stack.size(); i++) {
        System.out.print(stack.get(i) + " ");
    }
    System.out.println("};");

}

public static boolean checkCycle() {
    boolean res = false;

    for (int i = 0; i < stack.size() - 1; i++) {
        if (stack.get(i).equals(stack.lastElement())) {
            res = true;
            break;
        }

    }
    return res;
}

public static boolean go_to_line(int line) {
    boolean res = false;
    for (int i = 0; i < k; i++) {
        if (g[line][i] == 1) {
            stack.add(i);
            if (checkCycle() == true) {
                System.out.println("Cycle found!");
                res = true;
            } else {
                res = go_to_line(i);
            }
        }
    }

    return res;
}

public static int cycles_count() {
    int res = 0;

    for (int i = 0; i < k; i++) {
        if (g[i][i] == 1) {
            System.out.println("Knot detected at item {" + i + "}!");
            res++;
        }

        for (int j = i + 1; j < k; j++) {
            if (g[j][i] == 1) {
                stack.add(j);
                stack.add(i);

                if (go_to_line(i) == true) {
                    res++;

                    System.out.print("Final ");
                    printStack();
                    stack.removeAllElements();
                }
            }
        }
    }

    return res;
}

This problem has exponential complexity in the general case. 在一般情况下,该问题具有指数复杂性。 The thing is that if each vertex is connected to each then the count of all graph cycles is more than 2^n (any subset of nodes forms several cycles). 问题在于,如果每个顶点连接到每个顶点,则所有图形循环的计数大于2^n (节点的任何子集形成几个循环)。

Thus there is no good algorithm in the general case. 因此,在一般情况下没有好的算法。 To find some cycle you may use breadth-first search. 要找到某个周期,您可以使用广度优先搜索。 To find all cycles you should use brute force algorithm. 要查找所有周期,您应该使用强力算法。

If C++ is the problem then change for another language. 如果C ++是问题,那么换另一种语言。 up to my knowledge C++ does not have particular feature that make it more efficient/convenient to work on graph matters. 据我所知,C ++没有特定的功能,可以更有效/方便地处理图形问题。 Alternatively you might want to look for a framework that will abstract the low level, letting you focusing on the high-level question. 或者,您可能希望寻找一个抽象低级别的框架,让您专注于高级问题。 You might consider Boost Graph library for that purpose. 您可以考虑使用Boost Graph库来实现此目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM