动态规划——2 Warshall算法

/**
 * Warshall算法<br/>
 * 计算举证传递闭包,就可以看图有没有通路<br/>
 * Rij(k) = Rij(k) | Rik(k-1) && Rkj(k-1)
 * 
 * O(n^3)
 * 
 * @author chenxuegui
 * 
 */
public class Warshall
{
	public static void main(String[] args)
	{
		boolean[][] n = new boolean[][] { { false, true, false, false },
				{ false, false, false, true }, { false, false, false, false },
				{ true, false, true, false } };

		warshall(n);

	}

	/**
	 * 
	 * @param n
	 */
	public static void warshall(boolean[][] n)
	{
		for (int k = 0; k < n.length; k++)
		{

			print(n);
			for (int i = 0; i < n.length; i++)
			{
				//n[i][k]为false则n[i][j]为n[i][j]
				if (n[i][k] != false)
				{
					for (int j = 0; j < n.length; j++)
					{
						n[i][j] = n[i][j] || (n[i][k] && n[k][j]);
					}
				}
			}
		}

		print(n);
	}

	public static void print(boolean[][] n)
	{
		for (int i = 0; i < n.length; i++)
		{
			for (int j = 0; j < n.length; j++)
			{
				if (n[i][j])
				{
					System.out.print("1 ");
				}
				else
				{
					System.out.print("0 ");
				}
			}
			System.out.println();
		}

		System.out.println();
	}
}


### Floyd-Warshall算法动态规划实现原理 #### 算法概述 Floyd-Warshall算法是一种经典的多源最短路径算法,能够有效地找出带权重图中每一对顶点之间的最短距离。该算法特别适合于稠密图,并能处理负权重边的情况,只要不存在负权重环即可[^1]。 #### 动态规划的核心思想 此算法利用动态规划的思想来逐步构建最终的结果矩阵。具体来说,在每次迭代过程中都会考虑一个新的中间节点k作为可能经过的一个点,从而更新当前已知的最佳路径长度。对于每一个顶点对(i, j),如果存在一条经由第k个顶点更优的新路线,则会用这条新路线上两个端点间的总成本替换旧的成本值。 #### 初始化阶段 初始化时设置邻接矩阵`dist[][]`中的元素代表直接相连两结点间的真实代价;而对于未直连者赋予无穷大∞表示不可达状态。另外还需要准备一个辅助性的前驱矩阵`pPath[][]`用来追踪具体的路由信息以便后续重建完整的最短路径链表[^2]。 ```cpp for (int i = 0; i < n; ++i){ for(int j=0;j<n;++j){ dist[i][j]=graph[i][j]; // graph存储初始输入的数据 if(graph[i][j]!=INF && i!=j)pPath[i][j]=i; else pPath[i][j]=-1; } } ``` #### 迭代优化过程 接下来进入核心循环部分,这里采用三重嵌套的方式遍历所有的顶点组合以及潜在中介站点: - 外层循环变量`k`指示正在评估哪个顶点可充当临时跳板; - 中间一层负责选取起点位置`i`; - 内部则针对终点位置`j`做判断并尝试刷新记录。 每当发现借助某个特定编号为`k`的中途站可以使某条既定线路变得更经济实惠时,就立即调整对应项下的数值配对关系。 ```cpp // 主体逻辑:逐轮引入新的候选转接枢纽直至穷尽全部可能性为止 for (int k = 0; k < n; ++k) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if(dist[i][j]>dist[i][k]+dist[k][j]){ dist[i][j]=dist[i][k]+dist[k][j]; pPath[i][j]=pPath[k][j]; } } } } ``` #### 十字交叉法解释 所谓“十字交叉法”是指当我们在纸上手动模拟上述运算流程时所采取的一种直观形象化的手段。想象有一张网格纸上的表格被划分成了许多小格子,每个单元格内填写着相应索引处的距离度量。随着程序执行进度推进,“视线”沿着斜方向划过整个平面形成类似‘X’形状轨迹——即所谓的“十字体”。这种方法有助于理解为什么在每一次加入新的中间节点后都要重新审视之前已经考察过的所有连接情况[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值