拓扑排序-减治法
问题描述
考虑五门必修课的一个集合{C1, C2, C3, C4, C5},一个在职的学生必须在某个阶段修完这几门课程。可以按照任何次序学习这些课程,只要满足下面这些条件:
- C1和C2没有任何先决条件;
- 修完C1 和C2才能修C3;
- 修完C3 才能修C4;
- 修完C3、C4才能修C5;
- 这个学生每个学期只能修一门课程。
若用一个图来建模,它的顶点代表课程,有向边表示先决条件,该问题为:是否可以按照这种次序列出它的顶点,使得对于图中每一条边来说,边的起始顶点总是排在边的结束顶点之前。
这个问题称为拓扑排序。
如果有向图具有一个有向的回路,该问题是无解的。因此,为了使得拓扑排序成为可能,问题中的图必须是一个无环有向图。
拓扑排序-减治原理
基于减(减一)治技术的一个直接实现:重复以下过程:
- 在余下的有向图中求出一个源,它是一个没有输入边的顶点;
- 然后把该源和所有从它出发的边都删除。(如果有多个这样的源,可以任意选择一个;如果这样的源不存在,算法停止,因为该问题是无解的)
- 顶点被删除的次序就是拓扑排序的一个解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| vector<int> tuopu1(vector<vector<int>> vec){ vector<int> res; vector<int> in(vec.size(),0); vector<int> flag(vec.size(),0); for(int i=0;i<vec.size();i++){ for(int j=0;j<vec[i].size();j++){ in[vec[i][j]]++; } } for(int i=0;i<vec.size();i++){ int j; for(j=0;j<vec.size();j++){ if(in[j]==0 && flag[j]==0){ flag[j]=1; res.push_back(j); break; } } for(auto a:vec[j]){ in[a]--; } } return res; }
|
拓扑排序-深度搜索
基于深度优先搜索的方法实现
深度优先搜索(或广度优先搜索)整个图,将出度为0的顶点入栈,中途要判断是否会形成环,最后输出栈得到的序列就是该图的一种拓扑排序。
1 2 3 4 5 6 7 8 9 10 11 12
| void tuopu2(vector<vector<int>> &vec,stack<int> &st,vector<int> &flag,int node){ for(int i=0;i<vec[node].size();i++){ if(flag[vec[node][i]]==0){ tuopu2(vec,st,flag,vec[node][i]); } } if(flag[node]==0){ st.push(node); flag[node]=1; } }
|
2 深度学习算子
问题描述
一般深度学习网络有若干算子组成,假设一个深度学习网络模型是一个有向无环图。若算子A依赖算子B的输出,则晋档算子B执行完成后才能执行算子A,没有依赖关系的算子可以并行执行。已知每个算子的执行时间,请计算运行整个网络所需要的的最小执行时间。
- 不考虑算子之间的传输时间
- 第一个算子为输入算子且仅有一个输入算子
- 算子的索引从0开始
输入描述
N+1行。N为算子的总个数,第一行输入N,N<100.第j行输入代表索引为j-2的算子的属性。包括算子的时间和算子的后继算子。
实例
问题分析
- 图问题
- 拓扑排序
- 深度搜索
策略选择
- 深度优先搜索
- 记录最长的路径
算法设计
算法分析
时间复杂度 O(n*v)
空间复杂度 O(n)
算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| int dfs(vector<vector<int>> &vec,vector<int> &cost,int node,int c){ int max_cost=c+cost[node]; for(int i=0;i<vec[node].size();i++){ max_cost = max(max_cost,dfs(vec,cost,vec[node][i],c+cost[node])); } return max_cost; } int main(){ string input="4\nsoftmax 10 1 2\nrelu 5\nconv1 1 3 1\nsoftmax 2"; istringstream cin(input); int N ; cin>>N; cout<<N<<endl; vector<int> cost(N,0); vector<vector<int>> vec(N,vector<int>()); cin.ignore(); for(int i=0;i<N;i++){ string line; getline(cin,line,'\n'); istringstream is(line); string name; is>>name; is>>cost[i]; int next; while(is>>next){ vec[i].push_back(next); } cout<<name<<":"<<cost[i]<<endl; } cout<<"result:"<<dfs(vec,cost,0,0)<<endl;
vector<int> res = tuopu1(vec); for(auto a:res){ cout<<a<<" "; } cout<<endl;
vector<int> flag(vec.size(),0); stack<int> st; tuopu2(vec,st,flag,0); vector<int> res2; while(!st.empty()){ cout<<st.top()<<" "; res2.push_back(st.top()); st.pop(); } cout<<endl;
}
|