【拓扑排序】车间作业调度

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 }

 

posted @ 2016-05-27 16:29  隅子酱  阅读(1090)  评论(0)    收藏  举报