[英]How to calculate the shortest path between two vertices in Graph with given parameters?
[英]How to check graph connectivity between two vertices
我正在尝试实现一种遗传算法,以找到一组边缘,将其移除会断开图形连接。 更具体地说,我使用的是由顶点和边组成的有向无环图。 每个边缘都有成本或重量。 遗传算法生成大量集合C(即在两个顶点之间选择一些边)。 现在我的问题是检查这组边是否表示切割组或断开图形。 然后,遗传算法正在寻找切割集中包含的最小边成本总和。
因此,我使用了一种叫做“连通图测试”的方法来测试连通性,该方法摘自《图算法和优化的Java库》一书。 这对我不起作用,因为它仅扫描顶点的邻居。
public static boolean isConnected(Individual ind)
{
int n= Settings.numOfNodes;
int m= Settings.numOfEdges-ind.cutSet.size();
int nodei[]= new int[m+1];
int nodej[]= new int[m+1];
int tempi[]= new int[m];
int tempj[]= new int[m];
int[] temp= (int[])Settings.nodei.clone();
for(int edg:ind.cutSet)
temp[edg]= -1;
int count=0;
for(int i=0; i<Settings.numOfEdges; i++)
{
if(temp[i]!=-1)
{
tempi[count]=Settings.nodei[i];
tempj[count]=Settings.nodej[i];
count++;
}
}
nodei[0]=0;
nodej[0]=0;
for(int i=0; i<tempi.length;i++)
{
nodei[i+1]=tempi[i];
nodej[i+1]=tempj[i];
}
int i,j,k,r,connect;
int neighbor[] = new int[m + m + 1];
int degree[] = new int[n + 1];
int index[] = new int[n + 2];
int aux1[] = new int[n + 1];
int aux2[] = new int[n + 1];
for (i=1; i<=n; i++)
degree[i] = 0;
for (j=1; j<=m; j++) {
degree[nodei[j]]++;
degree[nodej[j]]++;
}
index[1] = 1;
for (i=1; i<=n; i++) {
index[i+1] = index[i] + degree[i];
degree[i] = 0;
}
for (j=1; j<=m; j++) {
neighbor[index[nodei[j]] + degree[nodei[j]]] = nodej[j];
degree[nodei[j]]++;
neighbor[index[nodej[j]] + degree[nodej[j]]] = nodei[j];
degree[nodej[j]]++;
}
for (i=2; i<=n; i++)
aux1[i] = 1;
aux1[1] = 0;
connect = 1;
aux2[1] = 1;
k = 1;
while (true) {
i = aux2[k];
k--;
for (j=index[i]; j<=index[i+1]-1; j++) {
r = neighbor[j];
if (aux1[r] != 0) {
connect++;
if (connect == n) {
connect /= n;
if (connect == 1) return true;
return false;
}
aux1[r] = 0;
k++;
aux2[k] = r;
}
}
if (k == 0) {
connect /= n;
if (connect == 1) return true;
return false;
}
}
}
给定以下有向无环图:
number of vertices = 4
number of edges = 5
1->2
1->3
1->4
2->4
3->4
如果我们移除以下边缘:
1->2
1->3
2->4
然后,该方法返回该图已断开连接,而它们之间仍然存在路径:
1->4
我正在寻找一种算法或方法来检查是否删除了某些边缘,该图仍连接在起始顶点和目标顶点之间。 换句话说,图在这两个顶点之间仍然存在其他路径。
一个有效集合的示例,该集合在删除时未连接图形:
1->2
1->3
1->4
要么
2->4
1->4
3->4
拜托,我对解决这个问题有任何想法或想法。
谢谢
您的图是有向无环的,因此您可以进行预处理并找到Paths = { (u,v) | there is a path from u to v }
Paths = { (u,v) | there is a path from u to v }
。
删除/添加每个边(u,v)
您所需要做的就是相应地重置Paths
。 请注意,对于每个v'
,当且仅当存在u'
使得(u,u')
仍是图形中的边,而(u',v')
位于in时, (u,v')
在Paths
中Paths
。
不要忘记在u
的每个父母上递归地调用Paths
修改。
尽管在最坏的情况下此解决方案并不比BFS更好,但在一般情况下则应更好-因为您无需在每次更改后都浏览整个图形。
编辑:示例
例如,在您的图形中, Path={(1,2),(1,3),(1,4),(2,4),(3,4)}
-存在一条通向所有顶点的路径“前进”顶点,从2到3除外。
现在,如果删除边(1,4)
则会得到Path={(1,2),(1,3),(1,4),(2,4),(3,4)}
请注意(1,4)
仍在其中,因为在Path
有一条边(1,2)和(2,4)。
现在删除(2,4)
,它将得到: Path={(1,2),(1,3),(1,4),(3,4)}
。 同样, (1,4)
仍在,因为(1,3)
仍是边,而(3,4)
在Path
。
现在移除(3,4)
。 3
到4
没有剩余路径,因此将(3,4)
删除。 现在,递归修改3
的所有父母。 由于1
是3
的父对象,请对其进行调用,您会发现不再有边(1,u)
使得(u,4)
仍在路径中,因此我们将其从Path
删除,结果得到Path={(1,2),(1,3)}
。
我将从删除所有边缘开始 ,然后添加边缘,而不是删除它们。 您只能添加不使图形连接的边。 使用这种方法,您尝试使添加的边的值最大化,而不是使删除的边最小化。
这样- 确保您的解决方案是可行的 ,并且该图的确未连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.