zoukankan      html  css  js  c++  java
  • 【拓扑排序】车间作业调度

    1.DFS(深度优先搜索)

    深度优先搜索算法(Depth-First-Search),是搜索算法的一种。它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。

    深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆数据结构来辅助实现 DFS 算法。

    深度优先遍历图算法步骤:

      1.  访问顶点v;

      2.  依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

      3.  若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

      上述描述可能比较抽象,举个实例:

      DFS 在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1;再从 w1 出发,访问与 w1 邻 接但还没有访问过的顶点 w2;然后再从 w2 出发,进行类似的访问,… 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。

      接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。

    2.BFS (广度优先搜索)

    广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。简单的说,BFS 是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。一般用队列数据结构来辅助实现 BFS 算法。

      算法步骤:

      1.  首先将根节点放入队列中。

      2.  从队列中取出第一个节点,并检验它是否为目标。

      • 如果找到目标,则结束搜寻并回传结果。
      • 否则将它所有尚未检验过的直接子节点加入队列中。

      3.  若队列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。

      4.  重复步骤2。

    3.拓扑排序

      算法思想:

      1、在AOV网络中选一个没有直接前驱的顶点, 并输出之;

      2、从图中删去该顶点, 同时删去所有它发出的有向边;

      3、重复以上步骤, 直到

      ◆ 全部顶点均已输出,拓扑有序序列形成,拓扑排序完成;

      ◆ 或者图中还有未输出的顶点,但已跳出处理循环。这说明图中还剩下一些顶点,它们都有直接前驱,再也找不到没有前驱的顶点了。这时AOV网络中必定存在有向环。

    4.深度优先或广度优先遍历的方法进行拓扑排序。

    应用有:

      1、判断一个有向图是否存在回路,为求有向图的最长路径。

      2、排队

     

    下面举一个排队的例子:

    题目要求如上图

    程序如下:

     1 #include<iostream>
     2 #include<queue>
     3 #include<stack>
     4 using namespace std;
     5 void breadth_sort(int **neighbors,int count,queue<int>&topological_order);
     6 void depth_sort(int **neighbors,int count,stack<int>&topological_order);
     7 void recursive_depth_sort(int **neighbors,int v,bool *visited,stack<int>&topological_order);
     8 int main()
     9 {//为了测试宽度与深度,本程序两种排序同时输出
    10     int number,com;
    11     int task_number;
    12     int **array;
    13     int *b;
    14     queue<int>breadth_order;
    15     stack<int>depth_order;
    16     cin>>task_number;
    17     for(int i=0;i<task_number;i++)//题目要求的任务数
    18     {
    19         cin>>number>>com;
    20         array=new int*[number+1];
    21         b=new int[number+1];
    22         for(int k=0;k<=number;k++)
    23         {
    24             array[k]=new int[number+1];
    25             b[k]=0;                   
    26         }    
    27         for(int m=0;m<=number;m++)
    28         for(int n=0;n<=number;n++)//矩阵初始化
    29             array[m][n]=0;
    30         for(int j=0;j<com;j++)
    31         {
    32             int p,q;
    33             cin>>p>>q;
    34             array[p][b[p]]=q;  //添加后继
    35             b[p]++;       //添加一个后继,值+1
    36         }    
    37         breadth_sort(array,number,breadth_order);//广度排序
    38         while(breadth_order.size()!=NULL)
    39             {
    40                 cout<<breadth_order.front()<<' ';
    41                 breadth_order.pop();
    42             }
    43         cout<<endl;
    44         depth_sort(array,number,depth_order);//深度排序
    45         while(depth_order.size()!=NULL)
    46             {
    47                 cout<<depth_order.top()<<' ';
    48                 depth_order.pop();
    49             }
    50         cout<<endl;
    51     }
    52     return 0;
    53 }    
    54 void breadth_sort(int **neighbors,int count,queue<int>&topological_order)
    55 {//广度优先排序,无前驱的先输出,用了队列
    56     int v;
    57     int *predecessor_count=new int[count+1];
    58     for(v=1;v<=count;v++)predecessor_count[v]=0;
    59     for(v=1;v<=count;v++)
    60         for(int i=0;neighbors[v][i]!=0;i++){        
    61             predecessor_count[neighbors[v][i]]++;
    62         }
    63     queue<int>ready_to_process;
    64     for(v=1;v<=count;v++)
    65         if(predecessor_count[v]==0)
    66             ready_to_process.push(v);
    67         while(!ready_to_process.empty()){
    68             v=ready_to_process.front();
    69             topological_order.push(v);
    70             for(int j=0;neighbors[v][j]!=0;j++){            
    71                 predecessor_count[neighbors[v][j]]--;
    72                 if(predecessor_count[neighbors[v][j]]==0)
    73                     ready_to_process.push(neighbors[v][j]);
    74             }
    75             ready_to_process.pop();
    76         }
    77 }
    78 void depth_sort(int **neighbors,int count,stack<int>&topological_order)
    79 {//深度优先排序,无前驱的先输出,用了堆栈
    80     bool *visited=new bool[count+1];
    81     int v;
    82     for(v=1;v<=count;v++)visited[v]=false;
    83     for(v=1;v<=count;v++)
    84         if(!visited[v])
    85             recursive_depth_sort(neighbors,v,visited,topological_order);
    86 }
    87 
    88 void recursive_depth_sort(int **neighbors,int v,bool *visited,stack<int>&topological_order)
    89 {
    90     visited[v]=true;
    91     for(int i=0;neighbors[v][i]!=0;i++){
    92     
    93         if(!visited[neighbors[v][i]])
    94             recursive_depth_sort(neighbors,neighbors[v][i],visited,topological_order);
    95     }
    96     topological_order.push(v);
    97 }
  • 相关阅读:
    2021NUAA暑假集训 Day3 题解
    2021NUAA暑假集训 Day2 题解
    2021NUAA暑期模拟赛部分题解
    CodeForces 1038D Slime
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 10689 Yet another Number Sequence
    HDU 4549 M斐波那契数列
    HDU 4990 Reading comprehension
    CodeForces 450B Jzzhu and Sequences
  • 原文地址:https://www.cnblogs.com/tenderwx/p/5535100.html
Copyright © 2011-2022 走看看