最短路径算法 java实现 - Dijkstra

本文介绍了一种名为 SFP 的最短路径算法实现。该算法适用于无向图且权重为正的情况,通过维护 open 和 closed 集合来逐步找到从起点到其他各点的最短路径。open 集合存放待处理节点,closed 集合存放已处理节点,同时使用 dist 结构记录最短距离,ps 结构记录所有边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

限制:
1. 权值为正
2. 无向

算法思想:
1. 三个结构:open集合,closed集合,dist和ps。open保存还没有被的处理节点,closed保存已经处理的节点,dist保持各个节点到目标节点的最短距离,ps保持所有的边。
初始:只有目标节点到目标节点的距离是0,其余是无穷大。
2. 从open集合里面找到距离最短的节点v,放到closed
3. 找到这个节点v的所有到邻居的邻接边,并且从ps去掉这些边
4. 根据这些邻接边,更新dist。更新方法是:如果通过v到达邻居n的距离更短,则更新邻居n的距离为:dist[n]=dist[v]+p(v,n).cost
5. 重复2-4步,直到open集合为空

public class SFP {
    private class Path{
        int n1;
        int n2;
        int cost;
        public Path(int n1, int n2, int cost){
            this.n1 = n1;
            this.n2 = n2;
            this.cost = cost;
        }
    }
    private Path[] paths={new Path(1,2,6),
            new Path(1,3,3),
            new Path(2,3,2),
            new Path(2,4,5),
            new Path(3,4,3),
            new Path(3,5,4),
            new Path(4,5,2),
            new Path(4,6,3),
            new Path(5,6,5),
            };


    int findMinDistNode(Map<Integer,Path> dist, Set<Integer> open){
        int nid=Integer.MAX_VALUE;
        int cost=Integer.MAX_VALUE;

        for(Integer i:open){
            if(cost>dist.get(i).cost){
                nid = i;
                cost = dist.get(nid).cost;
            }
        }
        return nid;
    }
    void start(){
        int start=1; //start point
        Set<Path> ps = new HashSet<>();
        Set<Path> nb = new HashSet<>();
        Set<Integer> closed = new HashSet<Integer>();
        Set<Integer> open = new HashSet<Integer>();  //
        Map<Integer,Path> dist = new HashMap<Integer,Path>();
        for(int i=0;i<paths.length;i++){
            dist.put(paths[i].n1,null);
            dist.put(paths[i].n2,null);
            ps.add(paths[i]);
        }
        for(Map.Entry<Integer, Path> d:dist.entrySet()){
            d.setValue(new Path(Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE));
            open.add(d.getKey());
        }

        dist.get(start).cost = 0;

        while(!open.isEmpty()){
            int v = findMinDistNode(dist, open);
            nb.clear();
            open.remove(v);
            closed.add(v);
            //find all paths to v's neighbor, and remove the paths from ps

            Iterator<Path> iter = ps.iterator();
            for(int i=0;i<ps.size();i++){
                Path p=iter.next();
                if(p.n1==v || p.n2==v){
                    iter.remove();
                    nb.add(p);
                    i--;
                }
            }

            //recaculate dist
            for(Path p:nb){
                int nn=p.n1;
                if(nn==v) nn=p.n2;
                int cost = p.cost+dist.get(v).cost;
                if(cost < dist.get(nn).cost){

                    dist.get(nn).cost = cost;
                    dist.get(nn).n1 = v;
                }
            }//for
        }//while

        //print
        for(Map.Entry<Integer, Path> d:dist.entrySet()){
            System.out.println(String.format("node=%d last=%d spf=%d",d.getKey(),d.getValue().n1,d.getValue().cost));
        }
    }
    public static void main(String args[]){
        SFP sfp=new SFP();
        sfp.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值