我无法理解Donald Johnson发表的关于在图表中查找周期(电路)的论文的某些部分。
更具体我无法理解伪代码的以下行中提到的矩阵Ak是什么:
Ak:=强组分K的邻接结构最少 由{s,s + 1,...... n}引起的G子图中的顶点;
为了让事情变得更糟,有些线路是“为了我在Vk做”而没有声明Vk是什么......
据我所知,我们有以下内容: 1)通常,强组件是图的子图,其中对于该子图的每个节点,存在到子图的任何节点的路径(换句话说,您可以访问该子图的任何节点)来自子图的任何其他节点的子图)
2)由节点列表引起的子图 包含所有这些节点以及连接这些节点的所有边的图。 在文中,数学定义是“F是由W引起的G的子图,如果W是V的子集,F =(W,{u,y)| u,W在W中,而y(y,y)在E中)})其中u,y是边,E是图中所有边的集合,W是一组节点。
3)在代码实现中,节点由整数1 ... n命名。
4)我怀疑 Vk是强组件K的节点集。
现在回答这个问题。假设我们有一个图G =(V,E),其中V = {1,2,3,4,5,6,7,8,9},它可以分为3个强组分,SC1 = {1, 4,7,8} SC2 = {2,3,9} SC3 = {5,6}(及其边缘)
任何人都可以给我一个s = 1,s = 2,s = 5的例子,如果根据代码成为Vk和Ak怎么办?
伪代码在我之前的问题中 Understanding the pseudocode in the Donald B. Johnson's algorithm
可以找到论文 Understanding the pseudocode in the Donald B. Johnson's algorithm
提前谢谢
答案 0 :(得分:10)
有效!在earlier iteration的Johnson algorithm中,我认为A
是adjacency matrix。相反,它似乎代表adjacency list。在下面实现的示例中,顶点{a, b, c}编号为{0,1,2},产生以下电路。
附录:如此提议的edit和有用的answer中所述,该算法指定unblock()
应删除具有值的元素 {{1} },而不是具有索引 w
的元素。
w
示例输出:
0 1 0 0 1 2 0 0 2 0 0 2 1 0 1 0 1 1 0 2 1 1 2 0 1 1 2 1 2 0 1 2 2 0 2 2 1 0 2 2 1 2
默认情况下,程序以list.remove(Integer.valueOf(w));
开头;实施s = 0
作为优化仍然存在。显示仅生成唯一周期的变体here。
s := least vertex in V
答案 1 :(得分:1)
我已经向@ trashgod的代码发送edit请求,以修复unblock()
中抛出的异常。本质上,该算法声明要从列表中删除元素w
(不索引)。上面的代码使用了list.remove(w)
,它将w
视为索引。
我的edit请求被拒绝了!不知道为什么,因为我已经在20,000个节点和70,000个边缘的网络上对我的修改进行了测试,并且它没有崩溃。
我还修改了Johnson的算法以更适应无向图。如果有人想要这些修改,请与我联系。
以下是unblock()
的代码。
private void unblock(int u) {
blocked[u] = false;
List<Integer> list = b.get(u);
int w;
for (int iw=0; iw < list.size(); iw++) {
w = Integer.valueOf(list.get(iw));
//delete w from B(u);
list.remove(iw);
if (blocked[w]) {
unblock(w);
}
}
}
答案 2 :(得分:1)
@trashgod,您的样本输出包含循环,这是循环排列。 例如0-1-0和1-0-1是相同的 实际上输出应该只包含5个周期,即 0 1 0, 0 2 0, 0 1 2 0, 0 2 1 0, 1 2 1,
约翰逊论文解释了一个循环是什么: &#39;如果一个不是另一个的循环置换,则两个基本电路是不同的。 &#39; 还可以检查wolfram页面:这也为同一输入输出5个周期。http://demonstrations.wolfram.com/EnumeratingCyclesOfADirectedGraph/
答案 3 :(得分:1)
以下变体会产生独特的循环。根据此example,它是根据answer提供的@user1406062进行调整的。
代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
* @see https://en.wikipedia.org/wiki/Johnson%27s_algorithm
* @see https://stackoverflow.com/questions/2908575
* @see https://stackoverflow.com/questions/2939877
* @see http://en.wikipedia.org/wiki/Adjacency_matrix
* @see http://en.wikipedia.org/wiki/Adjacency_list
*/
public final class CircuitFinding {
final Stack<Integer> stack = new Stack<Integer>();
final Map<Integer, List<Integer>> a;
final List<List<Integer>> b;
final boolean[] blocked;
final int n;
Integer s;
public static void main(String[] args) {
List<List<Integer>> a = new ArrayList<List<Integer>>();
a.add(new ArrayList<Integer>(Arrays.asList(1, 2)));
a.add(new ArrayList<Integer>(Arrays.asList(0, 2)));
a.add(new ArrayList<Integer>(Arrays.asList(0, 1)));
CircuitFinding cf = new CircuitFinding(a);
cf.find();
}
/**
* @param a adjacency structure of strong component K with least vertex in
* subgraph of G induced by {s, s + 1, n};
*/
public CircuitFinding(List<List<Integer>> A) {
this.a = new HashMap<Integer, List<Integer>>(A.size());
for (int i = 0; i < A.size(); i++) {
this.a.put(i, new ArrayList<Integer>());
for (int j : A.get(i)) {
this.a.get(i).add(j);
}
}
n = a.size();
blocked = new boolean[n];
b = new ArrayList<List<Integer>>();
for (int i = 0; i < n; i++) {
b.add(new ArrayList<Integer>());
}
}
private void unblock(int u) {
blocked[u] = false;
List<Integer> list = b.get(u);
for (int w : list) {
//delete w from B(u);
list.remove(Integer.valueOf(w));
if (blocked[w]) {
unblock(w);
}
}
}
private boolean circuit(int v) {
boolean f = false;
stack.push(v);
blocked[v] = true;
L1:
for (int w : a.get(v)) {
if (w == s) {
//output circuit composed of stack followed by s;
for (int i : stack) {
System.out.print(i + " ");
}
System.out.println(s);
f = true;
} else if (!blocked[w]) {
if (circuit(w)) {
f = true;
}
}
}
L2:
if (f) {
unblock(v);
} else {
for (int w : a.get(v)) {
//if (v∉B(w)) put v on B(w);
if (!b.get(w).contains(v)) {
b.get(w).add(v);
}
}
}
v = stack.pop();
return f;
}
public void find() {
s = 0;
while (s < n) {
if (!a.isEmpty()) {
//s := least vertex in V;
L3:
for (int i : a.keySet()) {
b.get(i).clear();
blocked[i] = false;
}
circuit(s);
a.remove(s);
for (Integer j : a.keySet()) {
if (a.get(j).contains(s)) {
a.get(j).remove(s);
}
}
s++;
} else {
s = n;
}
}
}
}
输出:
0 1 0
0 1 2 0
0 2 0
0 2 1 0
1 2 1
所有周期,供参考:
0 1 0
0 1 2 0
0 2 0
0 2 1 0
1 0 1
1 0 2 1
1 2 0 1
1 2 1
2 0 1 2
2 0 2
2 1 0 2
2 1 2