Chinaunix首页 | 论坛 | 博客
  • 博客访问: 127303
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -15
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-03 22:22
个人简介

小楼一夜听春雨

文章分类
文章存档

2017年(1)

2016年(2)

2015年(5)

2014年(21)

2013年(5)

2012年(7)

2010年(6)

2009年(2)

我的朋友

分类: Java

2010-10-31 23:08:37

/*
 * @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

阅读(1826) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~