狄克斯特拉算法DijKstra Algorithm

广度优先算法适用于计算有向无权图计算最短路径。狄克斯特拉算法是有向加权图计算最小开销的算法,不适用于负权边的情况。

下面是代码示例,起点是start,经过a点权重是6,b点的权重是2,a点到终点fin的权重是1。b点到a点的权重是3,到fin点的权重是5,现在计算从start到fin的最小权重路径。

package com.teriste.algorithm;

import org.apache.commons.collections.MapUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DijKstraAlgorithm {

    //节点关系及权重
    public static Map<String,Map<String,Integer>> graph = new HashMap<>();

    //每个节点的开销,从起点到该节点的开销
    public static Map<String,Integer> cost = new HashMap<>();

    //每个节点的父节点
    public static Map<String,String> parent = new HashMap<>();

    //记录处理过的节点避免重复处理
    //public static List<String> processed = new ArrayList<>();
    static {
        //起点
        Map<String,Integer> start = new HashMap<>();
        //起点到a点的权重
        start.put("a",6);
        //起点到b点的权重
        start.put("b",2);
        graph.put("start",start);
        //a点
        Map<String,Integer> a = new HashMap<>();
        //a到fin点的权重
        a.put("fin",1);
        graph.put("a",a);
        //b点
        Map<String,Integer> b = new HashMap<>();
        //b到a点的权重
        b.put("a",3);
        //b到fin点的权重
        b.put("fin",5);
        graph.put("b",b);
        //fin点是终点
        graph.put("fin",null);
        //-------------------------------
        cost.put("a",6);
        cost.put("b",2);
        //------------------------
        parent.put("a","start");
        parent.put("b","start");
        parent.put("fin",null);
    }

    //遍历输入节点的所有临近节点,
    public void dijKstraCalc(String key){
        Map<String,Integer> start = graph.get(key);
        if (MapUtils.isEmpty(start)){
            return;
        }
        if (MapUtils.isNotEmpty(start)){
            //遍历临近节点
            for(Map.Entry<String,Integer> entry:start.entrySet()){
                if (entry.getValue()==null){
                    return;
                }
                /**
                 * 取出到该临近节点的权重和cost记录的到该临近节点的权重比较,
                 * 取最小权重存入cost,
                 * 并记录到该临近节点的最小权重的节点记录到parent散列表
                 */
                if (null==cost.get(entry.getKey())||entry.getValue()<cost.get(entry.getKey())){
                    cost.put(entry.getKey(),entry.getValue());
                    parent.put(entry.getKey(),key);
                }
                //递归遍历该该节点的临近节点的临近节点直到最后一个节点结束
                dijKstraCalc(entry.getKey());
            }
        }
    }
}

测试:

package com.teriste.algorithm;

import com.alibaba.fastjson.JSON;
import org.junit.Test;

public class DijKstraAlgorithmTest {

    @Test
    public void dijKstraCalcTest(){
        DijKstraAlgorithm algorithm = new DijKstraAlgorithm();
        //输入起点,开始计算
        algorithm.dijKstraCalc("start");
        //节点的父子关系
        System.out.println("parent:"+JSON.toJSONString(DijKstraAlgorithm.parent));
        //到该节点的权重
        System.out.println("cost"+JSON.toJSONString(DijKstraAlgorithm.cost));
    }
}

参考文献:《算法图解》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
狄克斯算法Dijkstra's algorithm)是一种用于解决单源最短路径问题的经典算法。它可以找到从一个顶点到其他所有顶点的最短路径。 以下是狄克斯算法的Java实现: ```java import java.util.*; public class DijkstraAlgorithm { private static final int INF = Integer.MAX_VALUE; public static void dijkstra(int[][] graph, int start) { int n = graph.length; int[] dist = new int[n]; boolean[] visited = new boolean[n]; Arrays.fill(dist, INF); dist[start] = 0; for (int i = 0; i < n - 1; i++) { int minDist = INF; int minIndex = -1; for (int j = 0; j < n; j++) { if (!visited[j] && dist[j] < minDist) { minDist = dist[j]; minIndex = j; } } visited[minIndex] = true; for (int j = 0; j < n; j++) { if (!visited[j] && graph[minIndex][j] != 0 && dist[minIndex] != INF && dist[minIndex] + graph[minIndex][j] < dist[j]) { dist[j] = dist[minIndex] + graph[minIndex][j]; } } } // 打印最短路径 System.out.println("顶点\t最短距离"); for (int i = 0; i < n; i++) { System.out.println(i + "\t" + dist[i]); } } public static void main(String[] args) { int[][] graph = { {0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0} }; dijkstra(graph, 0); } } ``` 这段代码实现了狄克斯算法,通过传入一个邻接矩阵表示的图和起始顶点,计算出从起始顶点到其他所有顶点的最短路径,并打印出最短距离。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值