微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试图二分性

如何解决测试图二分性

我为 edX 上的图算法课程(最初在 Coursera 上提供)编写了一个用于测试图二分性的算法,但它在他们的一个测试用例中失败了。

我考虑了一下,到目前为止还找不到我可能遗漏的东西,我使用 BFS 遍历为节点着色来测试二分性,它适用于一些简单的测试用例和 edX 上 28 个测试用例中的 17 个。

private static final int WHITE = -1;
private static final int BLACK = -2;
private static final int START_INDEX = 0;

static boolean isBipartite(ArrayList<Integer>[] adj) { // an array of lists of neighbors
    int[] colors = new int[adj.length];
    boolean[] visited = new boolean[adj.length];
    colors[START_INDEX] = WHITE;
    Queue<Integer> queue = new LinkedList<>();
    // start with some node
    queue.add(START_INDEX);

    while (!queue.isEmpty()) {
        int node = queue.poll();
        ArrayList<Integer> neighbors = adj[node];
        for (int neighbor : neighbors) {
            if (!visited[neighbor]) {
                if (node != neighbor) {
                    // add for traversal and color with an opposite color
                    queue.add(neighbor);
                    colors[neighbor] = colors[node] == WHITE ? BLACK : WHITE;
                } else {
                    // self cycle will always be odd
                    return false;
                }
            } else {
                // return immediately if encountered an already colored node 
                // with the same color,there is an odd cycle
                if (colors[node] == colors[neighbor]) {
                    return false;
                }
            }
        }
        visited[node] = true;
    }


    // final check of u and v colors for all edges
    for (int u = 0; u < adj.length; u++) {
        for (int i = 0; i < adj[u].size(); i++) {
            int v = adj[u].get(i);
            if (colors[u] == colors[v]) {
                return false;
            }
        }
    }

    return true;
}

任何建议我的算法中可能缺少什么? 同样如果没有最终检查,我的算法将在 28 个测试用例中的第 3 个测试用例中失败(我没有看到输入),即使我不明白为什么 - 我应该已经在主 for 循环中找到了奇数周期。

请帮忙。

我自己测试的一些示例图,第一个不是二部的,第二个是二部的。

enter image description here

enter image description here

解决方法

正如评论中所指出的,您假设每个节点都可以从起始节点到达。好消息是这很容易解决。定义三个值的枚举 ColorsNoColorBlackWhite。伪代码如下:

输入:图G,节点整数从0n - 1

Initialise array colors of length n with all values set to NoColor;
for each `i` from `0` to `n - 1`,do {
    if colors[i] = NoColor then {
        Initialise q to an empty queue (or stack - whatever floats your boat);
        push i onto queue;
        colors[i] <- Black;
        while q is not empty do {
            pop k off of q;
            for each neighbour i of k such that colors[i] = NoColor do
                colors[i] <- the opposite color of colors[k];
                push i onto q;
            }
        }
    }
}

如果存在着色,这将为您提供 2 着色。在这种情况下,您需要验证它实际上是 2 着色,以检查图形是否为二部图。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。