JAVA关键路径

关键路径需要拓扑排序算法。对AOV网进行拓扑排序的基本思路是:从AOV网中选择一个入度为0的顶点,然后删除此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止。

拓扑排序主要是为解决一个工程问题能否顺利进行的问题,但有时我们还需要解决工程需要的最短时间问题。在AOV网的基础上,我们引入一个新概念AOE网:在一个表示工程的带权有向图中用顶点表示事件,用有向边代表活动,用边上的权值代表活动持续时间。它具有明显的工程特性。如在某个顶点代表的事件发生后,从该顶点出发的活动才能开始。只有在进入某顶点的活动都已经结束,该顶点代表的事件才能发生。

尽管AOE网和AOV网都是用来对工程建模的,但他们还有很大的不同,主要是体现在AOV网顶点表示活动的网,它只描述活动之间的制约关系,而AOE网是用边表示活动的网,边上的权值表示活动持续的时间。因此,AOE网是建立在活动之间制约关系没有矛盾的基础上,再来分析完成整个工程至少需要多少时间,或者缩短完成工程所需要的时间,应该加快那些活动等问题。

  1. 事件最早发生的时间 ve[k]: 是指从开始到顶点Vk的最大路径长度。这个长度决定了所有从顶点Vk发出的活动能够开工的最早时间

  ve[1]=0

ve[k] = max{ve[j] + len<vj,vk>} (<vj,vk> ∈ p[k] ) p[k] 表示所有到达vk的有向边集合  通过循环来替换max。

        2.事件最迟发生时间 vl[k] :是指在不推迟整个工期的前提下,事件vk允许的最晚发生时间。

  vl[n]=ve[n]

vl[k] = min{vl[j] - len<vk,vj>} (<vk,vj> ∈ s[k] ) s[k] 表示所有从vk发出的有向边集合

代码讲解:

	// 最短路径
	public boolean[] criticalPath() {
		// 还有一个值来节省简单的计算
		int tempValue;
		
		// 第一步 tempInDegrees数组只要是有边,值为1.
		int[] tempInDegrees = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			for (int j = 0; j < numNodes; j++) {
				if (weightMatrix.getValue(i, j)!=-1) {
					tempInDegrees[j]++;
				} // Of if
			} // Of for j
		} // Of for i
		System.out.println("In-degree of nodes: "+Arrays.toString(tempInDegrees));
		
		// 第二步,拓扑排序
		int[] tempEarliestTimeArray = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			// 这个结点不能被移除
			if (tempInDegrees[i]>0) {
				continue;
			} // Of if
			
			System.out.println("Removing: " + i);
			
			for (int j = 0; j < numNodes; j++) {
				if (weightMatrix.getValue(i, j)!=-1) {
					tempValue = tempEarliestTimeArray[i] + weightMatrix.getValue(i, j);
					if (tempEarliestTimeArray[j]<tempValue) {
						tempEarliestTimeArray[j] = tempValue;
					} // Of if
					tempInDegrees[j]--;
				} // Of if
			} // Of for j
		} // Of for i
		System.out.println("Earlest start time: " + Arrays.toString(tempEarliestTimeArray));
		
		// 第三步 每个点的出度
		int[] tempOutDegrees = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			for (int j = 0; j < numNodes; j++) {
				if (weightMatrix.getValue(i, j)!=-1) {
					tempOutDegrees[i]++;
				} // Of if
			} // Of for j
		} // Of for i
		System.out.println("Out-degree of nodes;"+Arrays.toString(tempOutDegrees));
		
		// 第四步 逆序拓扑排序
		int[] tempLatesTimeArray = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			tempLatesTimeArray[i] = tempEarliestTimeArray[numNodes-1];
		} // Of for i
		
		for (int i = numNodes-1; i>=0; i--) {
			// 不能被移除的结点
			if (tempOutDegrees[i]>0) {
				continue;
			} // Of if
			System.out.println("Removing "+i);
			
			for (int j = 0; j < numNodes; j++) {
				if (weightMatrix.getValue(i, j)!=-1) {
					tempValue = tempLatesTimeArray[i] - weightMatrix.getValue(j, i);
					if (tempLatesTimeArray[j]>tempValue) {
						tempLatesTimeArray[j] = tempValue;
					} // Of if
					tempOutDegrees[j]--;
					System.out.println("The out-degree of " + j + " decreases by 1.");
				} // Of if
			} // Of for j
		} // Of for i
		System.out.println("Latest start time: "+Arrays.toString(tempLatesTimeArray));
		
		boolean[] resultCriticalArray = new boolean[numNodes];
		for (int i = 0; i < numNodes; i++) {
			if (tempEarliestTimeArray[i]==tempLatesTimeArray[i]) {
				resultCriticalArray[i] = true;
			} // Of if
		} // Of for i
		System.out.println();
		
		return resultCriticalArray;
	} // Of criticalPath
	
	// 程序入口
	public static void main(String args[]) {
		Net tempNet0 = new Net(3);
		System.out.println(tempNet0);

		int[][] tempMatrix1 = { { 0, 9, 3, 6 }, { 5, 0, 2, 4 }, { 3, 2, 0, 1 }, { 2, 8, 7, 0 } };
		Net tempNet1 = new Net(tempMatrix1);
		System.out.println(tempNet1);

		// Dijkstra
		tempNet1.dijkstra(1);

		// An undirected net is required.
		int[][] tempMatrix2 = { { 0, 7, MAX_DISTANCE, 5, MAX_DISTANCE }, { 7, 0, 8, 9, 7 },
				{ MAX_DISTANCE, 8, 0, MAX_DISTANCE, 5 }, { 5, 9, MAX_DISTANCE, 0, 15, },
				{ MAX_DISTANCE, 7, 5, 15, 0 } };
		Net tempNet2 = new Net(tempMatrix2);
		tempNet2.prim();

		// A directed net without loop is required.
		// Node cannot reach itself. It is indicated by -1.
		int[][] tempMatrix3 = { { -1, 3, 2, -1, -1, -1 }, { -1, -1, -1, 2, 3, -1 },
				{ -1, -1, -1, 4, -1, 3 }, { -1, -1, -1, -1, -1, 2 }, { -1, -1, -1, -1, -1, 1 },
				{ -1, -1, -1, -1, -1, -1 } };

		Net tempNet3 = new Net(tempMatrix3);
		System.out.println("-------critical path");
		tempNet3.criticalPath();
	}// Of main

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值