现实生活中,我们常常遇到一些涉及到图的问题;比如一个视频网站如何分配网络服务器,才能使得资源成本最小化;几个城市之间要修路,如何规划才能使得成本最小。另外现在是五一,有几个城市路线规划,在考虑路费时间等因素条件下,如何规划旅游路线。这些的种种问题,都可以化为图规划问题。前两个即最小生成树问题,后面一个即最短路径问题。
- 最小生成树
最小生成树,即对于一个加权图,如何规划路线,使得图中每个节点都能够连通,且权重成本最小(没有环型结构)
典型算法:Prim和Kruskal
- Prim算法,请参照《算法4》p399图例
每次对已访问的节点所连接的外部边进行排序,找到最短的边作为下一个边,进行连接。(重点是已访问)
- Kruskal
与Prim算法稍微有点区别。Kruskal算法首先将所有的权重边进行排序,然后对排序的遍历连接,直到所有的边都简历连接关系。(所有的边,不仅仅是已访问)
- 最短路径问题
对于一个加权图,对于同种的节点A和B,规划一个路线,使得从A到B的路线最短,有时候,这里的成本还会考虑其他因素,都作为权重计算。
典型算法;BFS,DFS(广度优先搜索和深度优先搜索);Dijkstra、拓扑排序、bellman、floyd、A*算法
Dijkstra
Dijkstra思想类似于A*算法:graph[src][d]=graph[src][v] + graph[v][d];其中src为起点,V为已访问节点,d为待访问节点(即相邻的节点)
Floyd
Floyd思想类似化学催化剂原理,即Dis(i,k) + Dis(k,j) < Dis(i,j);A直接生成C成本需要100分钟,但是A生成B再生成C总成本:A到B加上B到C可能只有10+20=30分钟,所以,三次遍历整个路径,将所以可以使用催化剂缩短的路径更改,并保存最短路径队列
Ford
Bellman-Ford算法可以非常好的解决带有负权的最短路径问题,什么是负权?如果两个顶点之间的距离为正数,那这个距离成为正权。反之,如果一个顶点到一个顶点的距离为负数,那这个距离就称为负权。Bellman-Ford和Dijkstra 相似,都是采用‘松弛’的方法来寻找最短的距离(为细看,解析保留)
1 | def prim(graph, root): |