文章目录
- 1.AOE图:
- 2.AOE图邻接链表存储结构:
- 3.代码实现
- 3.1.实体及参数初始化
- 3.2.代码实现
- 3.3.输出
1.AOE图:
2.AOE图邻接链表存储结构:
3.代码实现
3.1.实体及参数初始化
//邻接表的链表节点
@Data
public class LinkedNode {//邻接链表顶点编号private int nodeNum;//头节点到当前链表节点的 弧上的权值private int weight;//当前链表节点指向的下一个链表节点private LinkedNode nextLinkedNode;}
//邻接表中头节点
@Data
public class HeadNode {//节点编号private int nodeNum;//指向的下一个链表节点private LinkedNode nextLinkedNode;}
//AOE网络 图
@Data
public class AoeGraph {//顶点数量private int verticesNum ;//边数量private int edgeNum;//图的邻接表的 头结点集合private HeadNode[] headNode;}
将AOE图及其邻接链表的关系转化成实体:
//AOE图的邻接链表的初始化static LinkedNode v0_2 = new LinkedNode(2,30,null);static LinkedNode v0_1 = new LinkedNode(1,10,v0_2);static HeadNode v0 = new HeadNode(0,v0_1);static LinkedNode v1_5 = new LinkedNode(5,50,null);static LinkedNode v1_3 = new LinkedNode(3,30,v1_5);static HeadNode v1 = new HeadNode(1,v1_3);static LinkedNode v2_5 = new LinkedNode(5,20,null);static LinkedNode v2_4 = new LinkedNode(4,30,v2_5);static HeadNode v2 = new HeadNode(2,v2_4);static HeadNode v3= new HeadNode(3,null);static LinkedNode v4_3 = new LinkedNode(3,10,null);static HeadNode v4 = new HeadNode(4,v4_3);static LinkedNode v5_3 = new LinkedNode(3,20,null);static HeadNode v5 = new HeadNode(5,v5_3);//邻接链表的头节点集合static HeadNode[] headNodeArr = new HeadNode[]{v0,v1,v2,v3,v4,v5};//AOE图static AoeGraph aoeGraph = new AoeGraph(6,8,headNodeArr);
3.2.代码实现
public static void main(String[] args) {int length = criticalPathCalc(aoeGraph);System.out.println("length : "+length);}public static int criticalPathCalc(AoeGraph aoeGraph){int verticesNum = aoeGraph.getVerticesNum();//图的 顶点数量HeadNode[] headNodeArr = aoeGraph.getHeadNode(); //图的邻接表的 头结点集合int [] inDegree = new int[verticesNum]; //记录每个顶点的 实时入度 (初始化后,默认每位都是0)int [] weightSum = new int[verticesNum];//记录从开始顶点到 当前顶点的 实时最大权值 (初始化后,默认每位都是0)ConcurrentLinkedQueue<HeadNode> inDegreeZero = new ConcurrentLinkedQueue<>();//记录入度为0 的顶点 int nodeNum =0 ; //节点的编号//计算每个节点的入度for (int i = 0; i < headNodeArr.length; i++) {HeadNode headNode = headNodeArr[i];//当前操作的邻接邻接链表头节点LinkedNode linkedNode = headNode.getNextLinkedNode();//当前头节点的指向的 邻接节点;while (null!=linkedNode){inDegree[linkedNode.getNodeNum()]++;//指向的 邻接节点的 入度加1linkedNode = linkedNode.getNextLinkedNode();//指针指向 头节点的下一个邻接节点}}//将入度为0 的节点 放入队列for (int i = 0; i < inDegree.length; i++) {if(0==inDegree[i]){inDegreeZero.add(headNodeArr[i]);//将入度为0 的节点放入队列}}//只要队列不为空,就不断弹出入度为0的节点。相当于在图中擦去入度为0的节点及其相关边while (!inDegreeZero.isEmpty()){HeadNode headNode = inDegreeZero.poll();//弹出 入度为0的 节点 作为 =》头节点(相当于擦去入度为0的节点)System.out.println(headNode.getNodeNum());//输出拓扑序列LinkedNode nextLinkedNode = headNode.getNextLinkedNode();//头节点指向的 =》 链表节点while (null!=nextLinkedNode){nodeNum = nextLinkedNode.getNodeNum();//当前头节点指向的 链表节点的 编号inDegree[nodeNum]--;//链表节点入度减1 (相当于擦去入度为0的节点到其指向的链表节点之前的弧)if(0==inDegree[nodeNum]){inDegreeZero.add(headNodeArr[nodeNum]);//如果当前链表节点入度=0,放入队列(准备循环把入度为0的它也擦掉)}//开始节点到当前链表节点的累加权值 < 当前头节点到当前链表节点的弧线权值 + 开始节点到当前头节点的累加权值if(weightSum[nodeNum] < nextLinkedNode.getWeight()+ weightSum[headNode.getNodeNum()]){//开始节点到当前链表节点的最大权值 = 上诉比较的最大值weightSum[nodeNum] = nextLinkedNode.getWeight() + weightSum[headNode.getNodeNum()];}nextLinkedNode = nextLinkedNode.getNextLinkedNode();//获取头节点的下一个链表节点}}return weightSum[nodeNum];//}
3.3.输出
0
1
2
4
5
3
length : 80