java实现AOV网拓扑排序

AOV网(Activity On Vertex Network )

网:带权图。若在带权的有向图中,以顶点表示事件,以边(或者弧)表示活动,弧的权值表示活动的开销,则此带权有向图称为用边表示活动的网,简称:(AOV网(Activity On Vertex Network )。

关键路径

如果用AOV网表示一个工程,那么正常情况下工程只有一个开始点和一个结束点,因此AOV网中只有一个入度为0的点,称为源点;一个出度为0的点,称为汇点。
AOV网具有以下两个性质:
1、只有在某顶点所代表的事情发生后,从该顶点出发的弧所代表的活动才能开始。
2、只有在进入某顶点的各弧所代表的活动都已经结束时,该顶点所代表的事情才能发生。

由于AOV网中的某些活动可以并行进行,所以完成整个工程最短时间是从源点到汇点的最大路径长度。具有最大路径长度的路径称为关键路径,关键路径上的活动称为关键活动。

一个无环的有向图称为有向无环图,在AOV网中不存在有向环(或者称有向回路)

对于给定的AOV网,首先判断网中是否存在环路,只有有向无环图才具有现实意义。检查AOV网中是否存在回路的方法就是拓扑排序。

拓扑排序后,会得到一个有向图的顶点序列。

拓扑排序的实现

1、从网中选择一个没有前驱的顶点(入度为0)并且输出它。
2、从网中删去该顶点,并且删去从该顶点发出的全部有向边
3、重复上述两步,直到剩余的网中不存在没有前驱的顶点为止。

此操作有两种结果: 一、网中全部顶点都被输出,这说明网中不存在有向回路; 二、网中顶点未被全部输出,剩余的顶点均有前驱顶点,这说明网中存在有向回路
代码:

import java.util.Scanner;
import java.util.Stack;

class Node{
	//边表结构体声明
	int ideax;
	Node next;
}
class GraphNode{
	//点集结构体声明
	int in;
	char vertex;
	Node firstedge=null;
}
//图的声明
public class Graph {
	//图的构造函数
    public Graph(int vertexnum,int arcnum){
    	Scanner scanner=new Scanner(System.in);
    	this.vertexnum=vertexnum;
    	this.arcnum=arcnum;
    	System.out.println("输入顶点集:");
    	for(int i=0;i<this.vertexnum;i++) {
    		GraphNode s=new GraphNode();
    		s.vertex=scanner.next().charAt(0);
    		graphNodes[i]=s;
    	}
    	System.out.println("输入边集:");
    	for(int i=0;i<this.arcnum;i++) {
    		char ch1=scanner.next().charAt(0);
    		char ch2=scanner.next().charAt(0);
    		Node s=new Node();
    		s.ideax=getideax(ch2);
    		s=this.graphNodes[getideax(ch1)].firstedge;
    		this.graphNodes[getideax(ch1)].firstedge=s;
    		graphNodes[getideax(ch2)].in++;
    	}	
    }
    public int getideax(char ch) {
    	for(int i=0;i<this.vertexnum;i++) {
    		if(ch==this.graphNodes[i].vertex) {
    			return i;
    		}
    	}
    	return -1;
    }
    //AOV网拓扑排序算法
    public void TopSoft() {
        int count=0;
    	Stack<Integer> stack=new Stack<>();
    	for(int i=0;i<this.vertexnum;i++) {
    		if(this.graphNodes[i].in==0) {
    			stack.push(i);
    		}
    	}
    	while(stack.isEmpty()==false) {
    		Integer i=stack.pop();
    		System.out.print(graphNodes[i].vertex+" ");
    		count++;
    		Node p=this.graphNodes[i].firstedge;
    		while(p!=null) {
    			int j=p.ideax;
    			this.graphNodes[j].in--;
    			if(this.graphNodes[j].in==0)
    				stack.push(j);
    			p=p.next;
    		}
    	}
    	System.out.println();
    	if(count<this.vertexnum)
    		System.out.println("有回路");
    	else
    		System.out.println("无回路");
    }
    //图的顶点个数边的个数声明
	private int vertexnum=50;
	private int arcnum;
	//顶点数组
    private GraphNode[] graphNodes=new GraphNode[vertexnum];	
}

import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	  Scanner scanner=new Scanner(System.in);
	  int vertexnum=scanner.nextInt();
	  int arcnum=scanner.nextInt();
      Graph graph=new Graph(vertexnum, arcnum);
      graph.TopSoft();
	}

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值