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 }
  • 相关阅读:
    C#使用结构体,输入5个人的学号,姓名,分数,按照成绩高低排列打印出来
    数据库考试试题
    数据库存储系统应用,超市小票系统
    数据库变量与语句
    练习:C#---类(身份证号截取生日、验证邮箱、DateTime)
    Chapter 3. 类---String类、Math类、Datetime类
    练习:C#---for循环(整数和、阶乘、楼梯)
    Chapter 2 C#语句---异常语句
    Chapter 2. C#语句---循环语句
    Chapter 2 C#语句---选择语句
  • 原文地址:https://www.cnblogs.com/tenderwx/p/5535100.html
Copyright © 2011-2022 走看看