深度优先算法(DFS)遍历有向无环图计算最优路径

遍历有向无环图,寻找最优路径:

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;

 

/**

 * 节点

 * @author willWang

 * @Date 2017-11-23

 */

public class GraphNode {

 

    public List<GraphEdge> edgeList = null;

   

    private String label = "";

   

    public GraphNode(String label) {

       this.label = label;

       if (edgeList == null) {

           edgeList = new ArrayList<GraphEdge>();

       }

    }

   

    /**

     * 给节点添加边

     * @author willWang

     * @date 2017-11-23

     * @param edge

     */

    public void addEdgeList(GraphEdge edge) {

       edgeList.add(edge);

    }

   

    /**

     * 获取节点标签

     * @author willWang

     * @date 2017-11-23

     * @return

     */

    public String getLabel() {

       return label;

    }

}

         4、创建有向无环图的边

package answer.graph.model;

 

/**

 * 创建有向无环图边

 * @author willWang

 *

 */

public class GraphEdge {

 

    //左侧节点

    private GraphNode nodeLeft;

    //右侧节点

    private GraphNode nodeRight;

    //权重

    private int weight;

 

    /**

     * 初始化边

     * @author wwy

     * @date 2017-11-23

     * @param nodeLeft

     * @param nodeRight

     * @param weight

     */

    public GraphEdge(GraphNode nodeLeft, GraphNode nodeRight, int weight) {

       this.nodeLeft = nodeLeft;

       this.nodeRight = nodeRight;

       this.weight = weight;

    }

 

    public GraphNode getNodeLeft() {

       return nodeLeft;

    }

 

    public GraphNode getNodeRight() {

       return nodeRight;

    }

   

    public int getWeight() {

       return weight;

    }

}

    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(int n) {

       if (nodes == null) {

           nodes = new ArrayList<GraphNode>();

       }

      

       GraphNode node = null;

       for (int i = 0; i < n; i++) {

           node = new GraphNode(String.valueOf(i));

           nodes.add(node);

       }

    }

   

    public void initGraph(int n, boolean b) {

       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() {

       return nodes;

    }

}

         6、重点来了,根据深度优先算法遍历有向无环图,并计算出最优路径

package answer.graph.traversing;

 

import java.util.List;

 

import answer.graph.model.GraphEdge;

import answer.graph.model.GraphNode;

 

/**

 * 采用深度优先算法获取最佳路径

 * @author wwy

 * @Date 2017-11-23

 */

public class DFSGetBestPath {

   

    private int tempWeight = 0;

    int maxWeight = 0;

    String result = "";

    private StringBuffer wsb = new StringBuffer();

    private StringBuffer lsb = new StringBuffer();

   

    public String getResult() {

       return result;

    }

 

    /**

     * 采用深度优先算法递归遍历有向无环图

     * @param node

     * @param visited

     * @return

     */

    public GraphNode searchTraversing(GraphNode node,List<GraphNode> visited) {

       // 如果已经查看过该节点,返回该节点

       if (visited.contains(node)) {

           return node;

       }

      

       visited.add(node);

       //添加节点示例

       if(lsb.length() > 0){

           lsb.append("->");

       }

       lsb.append(node.getLabel());

//     System.out.println("节点:" + node.getLabel());

       if(node.edgeList.size() > 0){

           for (int i = 0; i < node.edgeList.size(); i++) {

              GraphEdge gEdge = node.edgeList.get(i);

              int weight = 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+"";

           }

       }

       return node;

    }

}

    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值