我正在编写一个C程序来寻找传递性。在2D数组中,如果adj[0][1] = 1
和adj[1][2] = 1
,我想将adj[0][2]
标记为1
。这应该适用于矩阵中的任何传递关系。
请帮我一些代码。
adj_matrix[j1][j2]=1;
for(i=0;i<26;i++)
{
if (adj_matrix[i][j1])
adj_matrix[i][j2]=1;
}
for(i=0;i<26;i++)
{
if(adj_matrix[j2][i])
{
adj_matrix[j1][i]=1;
}
}
答案 0 :(得分:1)
我相信这会奏效:
reachable_matrix = adj_matrix
length_of_path = 1
while(length_of_path < (N - 1)) {
for(i = 0; i < N; ++i) {
for(j = 0; j < N; ++j) {
tmp_matrix[i][j] = 0;
for(k = 0; k < N; ++k) {
tmp_matrix[i][j] ||= reachable_matrix[i][k] && reachable_matrix[k][j]; // Can I reach from i to j through k?
}
}
}
reachable_matrix = tmp_matrix;
length_of_path *= 2;
}
正如理查德评论的那样,这相当于计算图的可穿越性。
您可以将adj_matrix[i][j]
视为一个数字,说明从i
到j
的长度为1的路径有多少。然后adj_matrix ** l
(那是l
的幂的邻接矩阵)告诉你在任意两个节点之间至少l
有多少条长度路径。
我的代码中的内部循环(使用变量i,j和k循环)基本上是reachable_matrix
乘以reachable_matrix
并将其存储在tmp_matrix
中,而不是添加和乘法我使用逻辑或和,因为我们对确切的数字不感兴趣,只对它的真值有兴趣。
外环保持平方reachable_matrix
,而它所引发的功率(我们检查的路径长度)小于N - 1
。停在N - 1
就足够了,因为如果你有一个这个长度的路径,那就意味着你正在访问图中的所有节点。具有更多步骤的路径必须包含循环。另一方面,我不完全执行二进制求幂以保持简单(我认为效率会低一些,但我不确定)并且因为尝试更长的路径不会造成任何伤害。
总体而言,该算法具有复杂度O(log(N)* N ** 3)。
答案 1 :(得分:1)
你想要的是一个&#34;传递闭包算法&#34;
Floyd-Warshall Algorithm是其中之一的一个很好的例子,尽管还有很多(很多)其他的例如Johnson's Algorithm。快速搜索Google学术搜索将指向您了解其他一些来源和更多技术说明。
Floyd-Warshall算法的原始形式(找到每个连接点之间的最短路径)的代码是:
int dist[N][N]; // For some N
int i, j, k;
// Input data into dist, where dist[i][j] is the distance from i to j.
// If the nodes are unconnected, dist[i][j] should be infinity
for ( k = 0; k < N; k++ )
for ( i = 0; i < N; i++ )
for ( j = 0; j < N; j++ )
dist[i][j] = min( dist[i][j], dist[i][k] + dist[k][j] );
为您的使用场景修改此代码会给出:
int dist[N][N]; // For some N
int i, j, k;
// Input data into dist, where dist[i][j] is the distance from i to j.
// If the nodes are unconnected, dist[i][j] should be infinity
for ( k = 0; k < N; k++ )
for ( i = 0; i < N; i++ )
for ( j = 0; j < N; j++ )
if(dist[i][k] && dist[k][j])
dist[i][j] = 1;
请注意这里的下标顺序。按此顺序的下标符合动态编程的标准,确保路径逐步改进并始终是最佳的。
时间复杂度为O(N ^ 3)。
答案 2 :(得分:0)
如果这是正确的,请告诉我。
for(i=0;i<26;i++)
for(j=0;j<26;j++)
for(k=0;k<26;k++)
if(adj_matrix[i][j] && adj_matrix[j][k])
adj_matrix[i][k]=1;