【算法导论】有向图的可达矩阵

简介:         有时候,我们关注的不是从一个地点到另一个地点的费用,而是能否从一个顶点到达另一个顶点。因此我们可以假设所有边的权值为单位1,在下面的算法中,我们可以在O(n*n*n)的时间内计算出图中任意两点是否可达,我用可达矩阵来表示有向图中两者是否可达。

        有时候,我们关注的不是从一个地点到另一个地点的费用,而是能否从一个顶点到达另一个顶点。因此我们可以假设所有边的权值为单位1,在下面的算法中,我们可以在O(n*n*n)的时间内计算出图中任意两点是否可达,我用可达矩阵来表示有向图中两者是否可达。如果可以从i到j,则定义tij=1,否则tij=0。因此我们可以得到下式:


我们以下面的有向图进行具体实现:


下图给出了计算所得的每一个T(k)矩阵:


具体程序实现如下:

#include<stdio.h>

#define MAX 10000
#define N 4 //顶点个数

void TransitiveClosure(int dist[N][N],int t[N][N])//寻找可达矩阵
{
	for(int i=0;i<N;i++)//进行遍历
		for(int j=0;j<N;j++)
		{
			if((i==j)||(dist[i][j])==1)//发现可达
				t[i][j]=1;
			else
				t[i][j]=0;
		}

	for(int k=0;k<N;k++)
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++)
				t[i][j]=t[i][j]||(t[i][k]&&t[k][j]);//由文中公式可得
}

void main()
{
	int dist[N][N]={{1,0,0,0},//邻接矩阵
					{0,1,1,1},
					{0,1,1,0},
					{1,0,1,1}};

	int t[N][N]={0};
	TransitiveClosure( dist, t);
	for(int i=0;i<N;i++)
	{
			for(int j=0;j<N;j++)
				printf("%d ",t[i][j]);
			printf("\n");
	}

}

在上面的程序中,我用了逻辑运算来计算可达矩阵,因为在某些计算机上,对单位的值,逻辑操作的执行速度快于对整数字长数据的算术运算操作,其空间要求也比整数要小。


        学过图论的可能知道,一个邻接矩阵A(若边的权值都为单位1)表示两个顶点经过一步的可达情况,Aij表示经过一步,i能到达j的次数。同理A^2表示两个顶点经过两部步的可达情况,Aij表示经过两步,i能到达j的次数,一次类推……。还是以上面的图为例:

A =
     1     0     0     0
     0     1     1     1
     0     1     1     0
     1     0     1     1

A^2=
     1     0     0     0
     1     2     3     2
     0     2     2     1
     2     1     2     1

比如A^2中A12=2,表示从顶点2到顶点3经过两步可以到达的次数为3.注意:自己到达自己可以是任意步!

由相关知识可知,可达矩阵B=A+A^2+A^3+……+A^n ,n为顶点个数。具体的C语言实现比上面的算法要复杂,下面用matlab实现

function P = canget( A )
%计算可达矩阵
%B=A+A^2+A^3+……+A^n   A为邻接矩阵
n=length(A);
P=A;
for i=2:n
    P=P+A^i;
end

P=(P~=0);

结算可以得到相同的结果。由于matlab擅长矩阵运算,因此程序计算十分简单。

注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明


原文:http://blog.csdn.net/tengweitw/article/details/17606743

作者:nineheadedbird


目录
相关文章
|
8月前
|
算法 测试技术 C++
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
|
8月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
73 0
|
8月前
|
算法 测试技术 C#
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
|
13天前
|
算法
|
3月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
114 0
|
3月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
50 4
|
3月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
211 0
|
5月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
61 6
|
8月前
|
算法 测试技术 编译器
【算法 | 实验18】在字符矩阵中查找给定字符串的所有匹配项
题目描述 题目 在字符矩阵中查找给定字符串的所有匹配项 给定一个M×N字符矩阵,以及一个字符串S,找到在矩阵中所有可能的连续字符组成的S的次数。所谓的连续字符,是指一个字符可以和位于其上下左右,左上左下,右上右下8个方向的字符组成字符串。用回溯法求解。
124 1

热门文章

最新文章