如何解决测试图二分性
我为 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 循环中找到了奇数周期。
请帮忙。
我自己测试的一些示例图,第一个不是二部的,第二个是二部的。
解决方法
正如评论中所指出的,您假设每个节点都可以从起始节点到达。好消息是这很容易解决。定义三个值的枚举 Colors
:NoColor
、Black
和 White
。伪代码如下:
输入:图G
,节点整数从0
到n - 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 举报,一经查实,本站将立刻删除。