waysun一路阳光

不轻易服输,不轻言放弃.--心是梦的舞台,心有多大,舞台有多大。踏踏实实做事,认认真真做人。

  BlogJava :: 首页 :: 新随笔 :: 联系 ::  :: 管理 ::
  167 随笔 :: 1 文章 :: 64 评论 :: 0 Trackbacks

来源:http://blog.chinaunix.net/u1/50399/showart_408864.html

/*
 * @title:关键路径
 * @input: 有向带权图,图以邻接表形式表示,头结点只存储该顶点的度,后继结点存储顶点及权值
 * @output: 所有可能关键路径的并集path,path[i][0]及path[i][1]代表边的顶点,path[i][2]代表权值
 */

import java.util.*;
public class CriticalPathTest
{  
   public static void main(String[] args)
   {
       int[][] graph={{0, 1,6, 2,4, 3,5,},{1, 4,1,},{1, 4,1},{1, 5,2,},
       {2, 6,9, 7,7,},{1, 7,4,},{1, 8,2,},{2, 8,4,},{2,},};
       int[][] path;

       CriticalPath criticalPath=new CriticalPath();
       criticalPath.input(graph);
       path=criticalPath.getPath();
       for(int i=0; i<criticalPath.getLength(); i++){
           System.out.println("边:" + path[i][0]+ "-" + path[i][1] +" 权:"+ path[i][2]);
       }
   }
}

class CriticalPath
{
    private int[][] graph;
    private int[][] path;
    int len;
    
    void input(int[][] graph)
    {
        this.graph=graph;
        path=new int[graph.length-1][];
        len=0;
        calculate();
    }

    void calculate()
    {
        int[] ve=new int[graph.length];  //事件的最发生时间
        Stack stack1=new Stack();
        Stack stack2=new Stack();
        int i,j,v;
        for(int t : ve) t=0;
        stack1.push(0);
        while(stack1.empty()!=true){
            v=(Integer)stack1.pop();
            for(i=1; i<graph[v].length; i=i+2){
                j=graph[v][i];
                if((--graph[j][0])==0){
                    stack1.push(j);
                }
                if(ve[v]+graph[v][i+1]>ve[j]){
                    ve[j]=ve[v]+graph[v][i+1];
                }
            }
            stack2.push(v);
        }

        int[] vl=new int[graph.length];  //事件的最迟生时间
        for(i=0; i<graph.length; i++) vl[i]=1000;
        vl[graph.length-1]=ve[graph.length-1];
        while(stack2.empty()!=true){
            v=(Integer)stack2.pop();
            for(i=1; i<graph[v].length; i=i+2){
                j=graph[v][i];
                if(vl[j]-graph[v][i+1]<vl[v]){
                    vl[v]=vl[j]-graph[v][i+1];
                }
            }
        }

        for(v=0; v<graph.length-1; v++){ //求关键路径的所有边
            for(i=1; i<graph[v].length; i=i+2){
                j=graph[v][i];
                if(ve[v]==(vl[j]-graph[v][i+1])){
                    int[][] p={{v, j,graph[v][i+1],},};
                    path[len++]=p[0];
                }
            }
        }
    }
    
    int[][] getPath()
    {
        return path;
    }
    
    int getLength()
    {
        return len;
    }
}

结果如下:

边:0-1 权:6
边:1-4 权:1
边:4-6 权:9
边:4-7 权:7
边:6-8 权:2
边:7-8 权:4

易知关键路径有两条:

0-1-4-6-8 及 0-1-4-7-8

posted on 2009-04-15 22:22 weesun一米阳光 阅读(513) 评论(0)  编辑  收藏 所属分类: JAVA源码总结备用

只有注册用户登录后才能发表评论。


网站导航: