确定传递关系

时间:2012-12-08 05:52:41

标签: c algorithm adjacency-matrix

我正在编写一个C程序来寻找传递性。在2D数组中,如果adj[0][1] = 1adj[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;
        }
    }   

3 个答案:

答案 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]视为一个数字,说明从ij的长度为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;