美文网首页数据结构与算法
网(一.AOV网与拓扑排序)

网(一.AOV网与拓扑排序)

作者: 腊鸡程序员 | 来源:发表于2019-04-09 16:44 被阅读0次
安允沃
概述:

在现代化管理中,人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子工程被称为活动(Activity),在有向图中若以顶点表示活动,有向边表示活动之间的先后关系,这样的图简称为AOV网。

AOV网

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

简单的说,就是在一个工程中,我们要先做某事,完成后才能做另一件事,比如上图,
我们要先做1和13 ,然后才能做4.
这里的1,13,4就是工程中的活动.
顶点的入度就是活动的先决条件.

我们得到工程的实时路线,就是先做那个活动再做那个活动,直到完工.就得到一组拓扑序列.
如:
13 14 15 5 1 4 8 3 10 11 12 7 9 6 2
是上图的一组拓扑序列
得到这组拓扑序列的算法就是拓扑排序算法

拓扑排序

思路:
1.从AOV网中选择一个没有前趋的顶点(即入度为零),并输出它
2.从网中删除该顶点,并且删除从该顶点发出的全部有向边
3.重复1和2

数据结构:


邻接表

如上图:
我们用邻接表来表示AOV网中的顶点和边
表中每一个元素表示一个活动.
每一个元素有下标,in表示该顶点的入度
data表示顶点的值
first链接的一个链表,表示顶点的出度,链表中的结点有两个属性
first链表中的结点
data:表示改顶点在顶点数组中的下标
next:表示另一个出度顶点

步骤:
首先我们要找出入度为0的顶点,输出
我们将入度为0的顶点全部放入一个栈中.然后依次出栈输出
出栈后要改变顶点所链接的链表中所有元素的入度.

代码:

import org.junit.Test;

public class topologicSort {

    /**
     * 邻接链表结点
     */
    class EdgeNode {
        int data;//存放顶点在顶点数组中的下标
        EdgeNode next;//next结点

        public EdgeNode(int data, EdgeNode next) {
            this.data = data;
            this.next = next;
        }
    }

    /**
     * AOV网中的顶点
     */
    class VertexNode {
        int in;//入度
        int data;//值
        EdgeNode first;//出度领接链表的头结点

        public VertexNode(int in, int data, EdgeNode first) {
            this.in = in;
            this.data = data;
            this.first = first;
        }
    }

    //准备AOV网
    VertexNode[] graphAdjList = new VertexNode[15];

    @Test
    public void test() {
        EdgeNode a = new EdgeNode(3, null);
        EdgeNode a2 = new EdgeNode(2, a);
        EdgeNode a3 = new EdgeNode(1, a2);
        graphAdjList[0] = new VertexNode(0, 1, a3);
        graphAdjList[1] = new VertexNode(2, 2, null);
        EdgeNode b1 = new EdgeNode(9, null);
        EdgeNode b2 = new EdgeNode(8, b1);
        EdgeNode b3 = new EdgeNode(6, b2);
        EdgeNode b4 = new EdgeNode(5, b3);
        graphAdjList[2] = new VertexNode(2, 3, b4);
        EdgeNode c1 = new EdgeNode(7, null);
        EdgeNode c2 = new EdgeNode(9, c1);
        EdgeNode c3 = new EdgeNode(6, c2);
        graphAdjList[3] = new VertexNode(2, 4, c3);
        graphAdjList[4] = new VertexNode(1, 5, null);
        graphAdjList[5] = new VertexNode(1, 6, null);
        graphAdjList[6] = new VertexNode(3, 7, null);
        graphAdjList[7] = new VertexNode(1, 8, null);
        graphAdjList[8] = new VertexNode(1, 9, null);
        EdgeNode d1 = new EdgeNode(10, null);
        EdgeNode d2 = new EdgeNode(6, d1);
        graphAdjList[9] = new VertexNode(2, 10, d2);
        EdgeNode e1 = new EdgeNode(11, null);
        graphAdjList[10] = new VertexNode(1, 11, e1);
        graphAdjList[11] = new VertexNode(1, 12, null);
        EdgeNode f1 = new EdgeNode(3, null);
        EdgeNode f2 = new EdgeNode(13, f1);
        graphAdjList[12] = new VertexNode(0, 13, f2);
        EdgeNode g1 = new EdgeNode(14, null);
        EdgeNode g2 = new EdgeNode(1, g1);
        EdgeNode g3 = new EdgeNode(2, g2);
        graphAdjList[13] = new VertexNode(1, 14, g3);
        EdgeNode h1 = new EdgeNode(4, null);
        graphAdjList[14] = new VertexNode(1, 15, h1);
        topologicalSort();
    }

    private void topologicalSort() {

        //初始化栈,用数组表示,存放顶点在graphAdjList中的下标
        int top = 0;//栈的头指针
        int[] stack = new int[15];
        //找出入度为0的顶点,入栈
        for (int i = 0; i < graphAdjList.length; i++) {
            if (graphAdjList[i].in == 0) {
                stack[++top] = i;//先将top上移一位,因为取出顶点时top会下移,避免取出最后一个顶点时top会为-1.
            }
        }

        while (top != 0) {
            //出栈,输出,修改邻接链表中结点的入度
            int getTop = stack[top--];//取出stack中存放的下标,top下移一位
            System.out.print(graphAdjList[getTop].data + " ");//输出
            for (EdgeNode e = graphAdjList[getTop].first; e != null; e = e.next) {
                int k = e.data;//取出领接链表中结点的值,即该顶点在顶点数组graphAdjList中的下标
                graphAdjList[k].in--;//入度--
                if (graphAdjList[k].in == 0) {//入度为0就入栈
                    stack[++top] = k;
                }
            }
        }
    }

}


相关文章

  • 网(一.AOV网与拓扑排序)

    概述: 在现代化管理中,人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子...

  • 数据结构第二季 Day09 图 拓扑排序、最小生成树、prim算

    一、 拓扑排序(TopologicalSort) 1、一句话概括什么是 AOV 网?AOV 网必须是有向无环图吗?...

  • AOV网与拓扑排序算法

    主要为AOE网打下基础。AOE网:主要用在如何计算一个工程的完工时间,和优化工程方案减少工程完工时间 1、概念 A...

  • AOV网及拓扑排序

    前天在网上看了一篇博客,觉得写的很不错,小编转载一下,顺便加了点自己的理解。 一、AOV网 有向无环图(Direc...

  • 排序

    拓扑排序(AOV网图): 从AOV网中选择一个没有前驱的顶点(该顶点的入度为0)并输出它; 从王忠删去该顶点,并删...

  • 15-拓扑排序(Topological Sort)

    在研究拓扑排序之前,先来了解一个概念。 AOV网(Activity On Vertex Network) 什么叫A...

  • 图-关键路径

    拓扑排序主要是为解决一个工程能否顺序进行的问题, AOV网是 顶点表示活动的网,它只描述活动之间的 制约 关系; ...

  • 5.6 拓扑排序

    拓扑排序就是将有向无环图(不存在回路的AOV网)的顶点以特定的先后次序排序,所谓特定的先后次序排序是使得所有有向边...

  • 拓扑排序+关键路径

    拓扑排序 有向无环图DAG顶点表示活动的网络AOV网:用DAG图表示一个工程,其顶点表示活动,有向边...

  • 图的应用-拓扑排序与关键路径求解

    拓扑排序 AOV网   在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样有向图为顶点表示...

网友评论

    本文标题:网(一.AOV网与拓扑排序)

    本文链接:https://www.haomeiwen.com/subject/xqfiiqtx.html