深度优先算法(DFS)遍历有向无环图计算最优路径
来源:互联网 发布:k歌之王65首歌名知乎 编辑:程序博客网 时间:2024/06/14 13:48
遍历有向无环图,寻找最优路径:
1、假设我们从A点走到B点,可以经过不同的地方,分别用1,2,3,4,5,6表示,A用0表示,B用7表示,从一个地方到另一个地方,中间的路好走的程度用w表示,w越大表示越好走,因此我们可以建立数学模型如下图1所示:
图1
2、根据数学模型,我们判断这是一个有向无环图遍历问题,有向无环图遍历有两种方法,(1)、广度优先(BFS)、(2)、深度优先(DFS)而我们需要的结果是从A到B那个路径的w值最大,即输出结果是路径:0->1->3->7,权值1+3+7=11。最后我们只需要选出权值和最大的路径即可,DFS正好适合这种输出结果,而且时间复杂度为O(V+E)。java代码实现如下:
3、创建有向无环图节点
package answer.graph.model;
import java.util.ArrayList;
import java.util.List;
/**
* 节点
* @authorwillWang
* @Date 2017-11-23
*/
public class GraphNode {
public List<GraphEdge>edgeList = null;
private Stringlabel = "";
public GraphNode(Stringlabel) {
this.label =label;
if (edgeList ==null) {
edgeList = new ArrayList<GraphEdge>();
}
}
/**
* 给节点添加边
* @authorwillWang
* @date 2017-11-23
* @param edge
*/
public void addEdgeList(GraphEdge edge) {
edgeList.add(edge);
}
/**
* 获取节点标签
* @authorwillWang
* @date 2017-11-23
* @return
*/
public String getLabel() {
returnlabel;
}
}
4、创建有向无环图的边
package answer.graph.model;
/**
* 创建有向无环图边
* @author willWang
*
*/
public class GraphEdge {
//左侧节点
private GraphNodenodeLeft;
//右侧节点
private GraphNodenodeRight;
//权重
private int weight;
/**
* 初始化边
* @authorwwy
* @date 2017-11-23
* @param nodeLeft
* @param nodeRight
* @param weight
*/
public GraphEdge(GraphNodenodeLeft, GraphNode nodeRight, int weight) {
this.nodeLeft =nodeLeft;
this.nodeRight =nodeRight;
this.weight =weight;
}
public GraphNode getNodeLeft() {
returnnodeLeft;
}
public GraphNode getNodeRight() {
returnnodeRight;
}
public int getWeight() {
returnweight;
}
}
5、根据设计初始化有向无环图
package answer.graph.model;
import java.util.ArrayList;
import java.util.List;
/**
* 按照设计图构造有向无环图
* @author willWang
* @Date 2017-11-23
*/
public class MyGraph {
private List<GraphNode>nodes = null;
public void initGraph(intn) {
if (nodes ==null) {
nodes = new ArrayList<GraphNode>();
}
GraphNode node = null;
for (inti = 0; i < n; i++) {
node = new GraphNode(String.valueOf(i));
nodes.add(node);
}
}
public void initGraph(intn, booleanb) {
initGraph(n);
GraphEdge edge01 = new GraphEdge(nodes.get(0),nodes.get(1), 1);
GraphEdge edge02 = new GraphEdge(nodes.get(0),nodes.get(2), 2);
GraphEdge edge13 = new GraphEdge(nodes.get(1),nodes.get(3), 3);
GraphEdge edge14 = new GraphEdge(nodes.get(1),nodes.get(4), 4);
GraphEdge edge25 = new GraphEdge(nodes.get(2),nodes.get(5), 5);
GraphEdge edge26 = new GraphEdge(nodes.get(2),nodes.get(6), 6);
GraphEdge edge37 = new GraphEdge(nodes.get(3),nodes.get(7), 7);
GraphEdge edge47 = new GraphEdge(nodes.get(4),nodes.get(7), 8);
GraphEdge edge57 = new GraphEdge(nodes.get(5),nodes.get(7), 9);
GraphEdge edge67 = new GraphEdge(nodes.get(6),nodes.get(7), 10);
nodes.get(0).addEdgeList(edge01);
nodes.get(0).addEdgeList(edge02);
nodes.get(1).addEdgeList(edge13);
nodes.get(1).addEdgeList(edge14);
nodes.get(2).addEdgeList(edge25);
nodes.get(2).addEdgeList(edge26);
nodes.get(3).addEdgeList(edge37);
nodes.get(4).addEdgeList(edge47);
nodes.get(5).addEdgeList(edge57);
nodes.get(6).addEdgeList(edge67);
}
public void initGraph() {
initGraph(8, false);
}
public List<GraphNode> getGraphNodes() {
returnnodes;
}
}
6、重点来了,根据深度优先算法遍历有向无环图,并计算出最优路径
package answer.graph.traversing;
import java.util.List;
import answer.graph.model.GraphEdge;
import answer.graph.model.GraphNode;
/**
* 采用深度优先算法获取最佳路径
* @authorwwy
* @Date 2017-11-23
*/
public class DFSGetBestPath {
private int tempWeight = 0;
int maxWeight = 0;
String result = "";
private StringBufferwsb = new StringBuffer();
private StringBufferlsb = new StringBuffer();
public String getResult() {
returnresult;
}
/**
* 采用深度优先算法递归遍历有向无环图
* @param node
* @param visited
* @return
*/
public GraphNode searchTraversing(GraphNodenode,List<GraphNode> visited) {
// 如果已经查看过该节点,返回该节点
if (visited.contains(node)) {
returnnode;
}
visited.add(node);
//添加节点示例
if(lsb.length() > 0){
lsb.append("->");
}
lsb.append(node.getLabel());
// System.out.println("节点:" + node.getLabel());
if(node.edgeList.size() > 0){
for (inti = 0; i < node.edgeList.size(); i++) {
GraphEdge gEdge =node.edgeList.get(i);
intweight = gEdge.getWeight();
//计算当前路径权重
tempWeight += weight;
//添加权重示例
if(wsb.length() > 0){
wsb.append("+");
}
wsb.append(weight);
GraphNode nextNode = searchTraversing(gEdge.getNodeRight(),visited);
if(nextNode.getLabel() !=null && nextNode.getLabel() != ""){
//减去退出路径的权重
tempWeight -=weight;
//删除退出路径的权重示例
if(wsb.length() <= 1){
wsb.delete(wsb.length()-1,wsb.length());
}else{
wsb.delete(wsb.length()-2,wsb.length());
}
//删除退出路径的节点示例
if(lsb.length() <= 1){
lsb.delete(lsb.length()-1,lsb.length());
}else{
lsb.delete(lsb.length()-3,lsb.length());
}
}
//删除当前节点,为遍历其他路径上的节点做准备
visited.remove(nextNode);
}
}else{
if(maxWeight <tempWeight){
maxWeight = tempWeight;//更细最大权重
//更新最有路径结果
result = maxWeight+"(最优路径是:"+lsb.toString()+"权重之和是:"+wsb.toString()+"="+maxWeight+")";
}
}
returnnode;
}
}
7、测试代码
public class Main {
private static MyGraph graph =null;
/**
* 初始化有向无环图
* @author willWang
* @date 2017-11-23
*/
private static void initGraph() {
if (graph ==null) {
graph = new MyGraph();
}
graph.initGraph();
}
public static void main(String[] args) {
//初始化有向无环图
initGraph();
List<GraphNode> visited =new ArrayList<GraphNode>();
System.out.println("深度优先算法");
graph.getGraphNodes().get(0)
DFSGetBestPath mdfs = new DFSGetBestPath();
GraphNode result =mdfs.searchTraversing(graph.getGraphNodes().get(0),visited);
System.out.println(mdfs.getResult());
}
}
8、输出结果:
起点:
0
输出:18(最优路径是:0->2->6->7权重之和是:2+6+10=18)
源码下载地址:http://download.csdn.net/download/wwy1219787539/10135173
- 深度优先算法(DFS)遍历有向无环图计算最优路径
- 【算法】图的深度优先遍历(有向)
- 【算法导论】有向图的深度优先搜索遍历
- DFS(深度优先搜索)弊端:不一定是最优路径
- 【算法导论】图的深度优先搜索遍历(DFS)
- 算法学习:图的深度优先遍历(DFS)
- 算法基础——DFS(深度优先遍历)
- DFS深度优先遍历算法简单分析
- 深度优先遍历DFS
- DFS-深度优先遍历
- DFS深度优先遍历
- 深度优先遍历(DFS)
- DFS 深度优先遍历
- 深度优先遍历!!DFS
- DFS 深度优先遍历
- 深度优先遍历DFS
- 算法复习 - 广度优先遍历、深度优先遍历(BFS、DFS)
- 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)
- 【Scikit-Learn 中文文档】半监督学习
- 106张图为证,配置SSLVPN服务
- Action的三种访问方式(八)
- 私有云落地解决方案之openstack高可用(pike版本)-环境配置
- 13. Roman to Integer题目和答案详解
- 深度优先算法(DFS)遍历有向无环图计算最优路径
- 1.0-springboot的java配置方式
- 给键盘按键带上音效
- 中介者模式
- JavaScript学习笔记——对象和数组(下)
- 一步步点亮LED
- 【Scikit-Learn 中文文档】概率校准
- 73. Set Matrix Zeroes
- CDN内容分发网络(上)