【发布时间】:2010-06-30 10:50:46
【问题描述】:
在 Floyd–Warshall/Dijkstra 回复洪水到来之前,请让我解释一下情况,因为我确信任何一种算法都可以针对这种情况进行调整,并且必须如此,因为这不是一个玩具示例程序(请注意, 在 java 中所以必须保持它在内存方面的可管理性)
我所拥有的是从节点 0 到节点 n 生成的网络图,节点 3 无法链接到节点 5,因为当节点 3 选择它的 外链接 时节点 5 不存在。每个“节点”都表示为 in_neighbours[nodeID] 和 out_neighbours[nodeID] 表示 nodeId=3,所以我们谈论的是节点 3。还要注意 in_/out_ 都已排序,(in_ 自然排序为 5 将选择它的 out 链接一次全部,只有这样 6 才会选择 out_links,因此 3 的 in_ 永远不能包含 {6, 5, 7}) 并且 ofc 都可以包含重复项。 (in/out 是大小为 n 的 ArrayList 数组,其中 out_ 的大小始终为 d 或 m,与 n 一起由用户在启动时指定)
没有重量。我必须做的是找到averageDistance()
public double getAvgDistance() {
int sum = 0;
for (int i=1; i<n; i++) {
for (int j=0; j < i; j++) {
sum += dist(i, j); // there are duplicates, make sure i skip
}
}
return (double)sum / (double)( ((n*(n-1)) / 2) );
}
我目前的情况是最好的。注意我只想找到j和i之间的距离,而不是同时找到所有的距离(内存不够,会在m=20 d=1 000 000时测试)
private int dist(int i, int j) {
int dist = 0;
for (int link : in_neighbours[j]) {
System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
System.out.print(" - yes!");
dist = 1;
}
}
return dist;
}
所以我询问“更新鲜”(ofc 此时图表已完成)节点 i 是否直接链接到其任何较老的伙伴,如果是,则距离为 1 跳。
如果节点向后遍历,是我还是“最短”路径将始终是第一个找到的路径?
我如何检查它是否不是 1,即基本情况之后的“else”?我的数学很弱请温柔:) 任何提示如何利用链接已排序这一事实?
这不是家庭作业或我试图欺骗的东西,这与代码本身无关,这必须是一个有用的工具,“学习”一路走来。
这是一个图的外观 nodeID,out links,in links for m=7 n=13,(注意 0 个周期就是图的初始化方式):
0 | 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 3 4 5 6 6 7 8 9
1 | 0 0 0 0 0 0 0 | 2 2 3 4 5 5 8 12
2 | 0 0 0 0 0 1 1 | 3 3 3 3 3 4 4 4 6 7 8 10
3 | 0 1 2 2 2 2 2 | 4 4 5 5 6 6 7 11
4 | 0 1 2 2 2 3 3 | 5 5 6 8 9 10
5 | 0 1 1 3 3 4 4 | 6 7 8 9 9 11 12
6 | 0 0 2 3 3 4 5 | 7 7 7 8 9 9 12
7 | 0 2 3 5 6 6 6 | 8 9 10 11 11 12
8 | 0 1 2 4 5 6 7 | 10 10 10 11 12
9 | 0 4 5 5 6 6 7 | 10 11 11
10 | 2 4 7 8 8 8 9 | 12 12
11 | 3 5 7 7 8 9 9 |
12 | 1 5 6 7 8 10 10 |
抱歉,阅读了令人痛苦的长篇文章。 编辑:方法中的代码错误,这是我现在认为正确的。
dist nr2 的修改,试试看有没有路径:
private int dist(int i, int j) {
int dist = 0, c = 0, count = 0;
boolean linkExists = false;
for (int link : in_neighbours[j]) {
//System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
//System.out.print(" - yes!");
dist = 1; // there is a direct link
} else {
while ( c < j ) {
// if there's a path from 0 up to j, check if 'i' links to a node which eventually links to 'j'
if (out_neighbours[i].contains(c) &&
(out_neighbours[c].contains(link) || in_neighbours[c].contains(link) )) {
count++; // yes. and this is one node we had to step through to get closer
linkExists = true;
} else {
linkExists = false; // unreachable, the path was interrupted somewhere on the way
break;
}
c++;
}
if (linkExists) {
dist = count-1; // as 2 nodes are linked with 1 edge
} else {
dist = 0; // no path was found
}
}
}
return dist;
}
【问题讨论】:
-
两个问题:为什么你认为路径A->B->C的距离=1?而且,为什么在传入/传出结构中有重复项?这与最短路径搜索无关。
-
好的,现在我看到你只计算路径中的跳数(即路径的内部节点),所以我的一个问题得到了回答......
-
重复,因为添加链接的方式其中一种方法是幂律,所以如果一个节点有更多链接到它,包括重复,它仍然“更受欢迎”。是否应该在搜索开始之前消除重复项?
标签: java graph path directed-acyclic-graphs