算法分析-加权有向图

加权有向边代码:

package com.chenqing.test.digraph;

/**
 * @author 陈沁
 * 加权有向图的边
 */
public class DirectEdge {
    private Double weight;
    private int from;
    private int to;

    public DirectEdge(Double weight, int from, int to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }

    public Double getWeight() {
        return weight;
    }

    public int getFrom() {
        return from;
    }

    public int getTo() {
        return to;
    }
}

加权有向图代码:

package com.chenqing.test.digraph;

import com.chenqing.test.linearList.queue.Queue;


/**
 * @author 陈沁
 * 加权有向图
 */
public class EdgeWeightedDirectGraph {
    private final int v;
    private int e;
    private Queue<DirectEdge>[] edgeQueue;

    public EdgeWeightedDirectGraph(int v) {
        this.v = v;
        this.e = 0;
        this.edgeQueue = new Queue[v];
        for (int i = 0; i < v; i++) {
            this.edgeQueue[i] = new Queue<DirectEdge>();
        }
    }

    public int getV(){
        return v;
    }

    public int getE(){
        return e;
    }

    public void addEdge(DirectEdge edge){
        int from = edge.getFrom();
        this.edgeQueue[from].enqueue(edge);
        e++;
    }

    public Queue<DirectEdge> adj(int v){
        return edgeQueue[v];
    }

    public Queue<DirectEdge> edges(){
        Queue<DirectEdge> edges = new Queue<>();
        for (int i = 0; i < v; i++) {
            for (DirectEdge edge : edgeQueue[i]) {
                edges.enqueue(edge);
            }

        }
        return edges;
    }
}

Dijkstra算法:

package com.chenqing.test.digraph;

import com.chenqing.test.linearList.queue.IndexMinPriorityxQueue;
import com.chenqing.test.linearList.queue.Queue;

/**
 * @author 陈沁
 * 使用Dijkstra实现最短路径
 */
public class DijkstraSP {
    private DirectEdge[] edgeTo; //索引代表顶点,值代表从顶点s到当前顶点的最短路径上的最后一条边
    private Double[] distTo; //索引代表顶点,值代表从顶点s到当前顶点的最短路径的总权重
    private IndexMinPriorityxQueue<Double> indexMinPriorityxQueue; //存放树中顶点与非树中顶点之间的有效横切边

    public DijkstraSP(EdgeWeightedDirectGraph graph, int s) {
        this.edgeTo = new DirectEdge[graph.getV()];
        this.distTo = new Double[graph.getV()];
        this.indexMinPriorityxQueue = new IndexMinPriorityxQueue<>(graph.getV());
        for (int i = 0; i < this.distTo.length; i++) {
            this.distTo[i] = Double.POSITIVE_INFINITY;
        }
        this.distTo[0] = 0.0;
        this.indexMinPriorityxQueue.insert(0, 0.0);
        while (!this.indexMinPriorityxQueue.isEmpty()){
            int minIndex = this.indexMinPriorityxQueue.delMin();
            this.relax(graph, minIndex);
        }
    }

    /**
     * 松驰图中的v顶点
     * @param graph
     * @param v
     */
    private void relax(EdgeWeightedDirectGraph graph, int v){
        Queue<DirectEdge> adj = graph.adj(v);
        for (DirectEdge edge : adj) {
            int to = edge.getTo();
            if(distTo(v) + edge.getWeight() < distTo(to)){
                distTo[to] = distTo[v] + edge.getWeight();
                edgeTo[to] = edge;
                if(indexMinPriorityxQueue.contains(to)){
                    indexMinPriorityxQueue.changeItem(to, distTo(to));
                }else{
                    indexMinPriorityxQueue.insert(to, distTo(to));
                }
            }
        }
    }

    /**
     * 获得顶点s到v最短路径的总权重
     * @param v
     * @return
     */
    public double distTo(int v){
        return distTo[v];
    }

    public boolean hasPath(int v){
        return distTo[v] < Double.POSITIVE_INFINITY;
    }

    public Queue<DirectEdge> edges(int v){
        Queue<DirectEdge> directEdges = new Queue<>();
        if(!this.hasPath(v)){
            return null;
        }
        while (true){
            DirectEdge edge = this.edgeTo[v];
            if(edge == null){
                break;
            }
            directEdges.enqueue(edge);
            int from = edge.getFrom();
            v = from;
        }
        return directEdges;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值