美文网首页
算法课 实验7

算法课 实验7

作者: KEEEPer | 来源:发表于2017-11-20 22:10 被阅读11次

实验问题描述:

加权无向图最短路径查找,从一点到另外一点的最小路径,比如从成都到北京,途中有好多城市,如何规划路线,能够使总共的路线最短,如何使总共的费用最低

实验步骤(采用Dijkstra算法):

  • 加权有向图的实现

下面代码是加权有向图的边的数据结构

package DiEdge; //java的包管理

public class DiEdge {
    private int from;
    private int to;
    private double weight;

    public DiEdge(int from, int to, double weight) {
        this.from = from;
        
    }
}

有向的也会比无向的简单一些,因为两个顶点有明显的前后顺序。

下面是加权有向图的实现,加权图的生成

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class EdgeWeightedDiGraph<Item> {
    private int vertexNum; //顶点的个数
    private int edgeNum;   //边的个数
    // 不是领接表,是以单个顶点为中心向四周发散的一种数据结构
    private List<List<DiEdge>> adj;
    // 顶点信息,是一个列表,所有的列表信息都会呈现在这个list中
    private List<Item> vertexInfo; 

    //一下提供3种构造方法
    public EdgeWeightedDiGraph(List<Item> vertexInfo) {
        this.vertexInfo = vertexInfo;
        this.vertexNum = vertexInfo.size();
        adj = new ArrayList<>();
        for (int i = 0; i < vertexNum; i++) {
            adj.add(new LinkedList<>());
        }      
    }

    public EdgeWeightedDiGraph(List<Item> vertexInfo, int[][] edges, double[] weight) {
        this(vertexInfo);
        for (int i = 0; i < edges.length; i++) {
            Didge edge = new DiEdge(edges[i][0], edges[i][1], weight[i]);
            addDiEdge(edge);
        }
    }

    public EdgeWeightedDiGraph(int vertexNum) {
        this.vertexNum = vertexNum;
        adj = new ArrayList<>();
        for (int i = 0; i < vertexNum; i++) {
            adj.add(new LinkedList<>());
        }
    }

    public void addEdge(DiEdge edge) {
        adj.get(edge.from()).add(edge);
        edgeNum++;
    }

    //返回与某个顶点为中心的所有的边
    //*v* 是顶点的编号
    public Iterable<DiEdge> adj(int v) {
        return adj.get(v);
    }

    public List<DiEdge> edges() {
        List<DiEdge> edges = new LinkedList<>();
        for (int i = 0; i < vertexNum; i++) {
            for (DiEdge e : adj(i)) {
                edges.add(e);
            }
        }
        return edges;
    }

    public int vertexNum() {
        return vertexNum;
    }

    public int edgeNum() {
        return edgeNum;
    }

    public Item getVertexInfo(int i) {
        return vertexInfo.get(i);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(vertexNum).append("个顶点, ").append(edgeNum).append("条边。\n");
        for (int i = 0; i < vertexNum; i++) {
            sb.append(i).append(": ").append(adj.get(i)).append("\n");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        List<String> vertexInfo = List.of("v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7");
        int[][] edges = {{4, 5}, {5, 4}, {4, 7}, {5, 7}, {7, 5}, {5, 1}, {0, 4}, {0, 2},
                {7, 3}, {1, 3}, {2, 7}, {6, 2}, {3, 6}, {6, 0}, {6, 4}};

        double[] weight = {0.35, 0.35, 0.37, 0.28, 0.28, 0.32, 0.38, 0.26, 0.39, 0.29,
                0.34, 0.40, 0.52, 0.58, 0.93};

        EdgeWeightedDiGraph<String> graph = new EdgeWeightedDiGraph<>(vertexInfo, edges, weight);

        System.out.println("该图的邻接表为\n"+graph);
        System.out.println("该图的所有边:"+ graph.edges());

    }
}

Dijkstra算法的实现

import java.util.*;

public class Dijkstra {
    private DiEdge[] edgeTo;
    private double[] distTo;
    private Map<Integer, Double> minDist;

    public Dijkstra(EdgeWeightedDiGraph<?> graph, int s) {
        edgeTo = new DiEdge[graph.vertexNum()];
        distTo = new double[graph.vertexNum()];
        minDist = new HashMap<>();

        for (int i = 0; i < graph.vertexNum(); i++) {
            distTo[i] = Double.POSITIVE_INFINITY; // 1.0 / 0.0为INFINITY
        }
        // 到起点距离为0
        distTo[s] = 0.0;
        relax(graph, s);
        while (!minDist.isEmpty()) {
            relax(graph, delMin());
        }
    }

    private int delMin() {
        Set<Map.Entry<Integer, Double>> entries = minDist.entrySet();
        Map.Entry<Integer, Double> min = entries.stream().min(Comparator.comparing(Map.Entry::getValue)).get();
        int key = min.getKey();
        minDist.remove(key);
        return key;
    }

    private void relax(EdgeWeightedDiGraph<?> graph, int v) {
        for (DiEdge edge : graph.adj(v)) {
            int w = edge.to();
            if (distTo[v] + edge.weight() < distTo[w]) {
                distTo[w] = distTo[v] + edge.weight();
                edgeTo[w] = edge;
                if (minDist.containsKey(w)) {
                    minDist.replace(w, distTo[w]);
                    System.out.println(w);

                } else {
                    minDist.put(w, distTo[w]);
                }
            }
        }
    }

    public double distTo(int v) {
        return distTo[v];
    }

    public boolean hasPathTo(int v) {
        return distTo[v] != Double.POSITIVE_INFINITY;
    }

    public Iterable<DiEdge> pathTo(int v) {
        if (hasPathTo(v)) {
            LinkedList<DiEdge> path = new LinkedList<>();
            for (DiEdge edge = edgeTo[v]; edge != null; edge = edgeTo[edge.from()]) {
                path.push(edge);
            }
            return path;
        }
        return null;
    }

    public static void main(String[] args) {
        List<String> vertexInfo = List.of("v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7");
        int[][] edges = {{4, 5}, {5, 4}, {4, 7}, {5, 7}, {7, 5}, {5, 1}, {0, 4}, {0, 2},
                {7, 3}, {1, 3}, {2, 7}, {6, 2}, {3, 6}, {6, 0}, {6, 4}};

        double[] weight = {0.35, 0.35, 0.37, 0.28, 0.28, 0.32, 0.38, 0.26, 0.39, 0.29,
                0.34, 0.40, 0.52, 0.58, 0.93};

        EdgeWeightedDiGraph<String> graph = new EdgeWeightedDiGraph<String>(vertexInfo, edges, weight);
        Dijkstra dijkstra = new Dijkstra(graph, 0);
        for (int i = 0; i < graph.vertexNum(); i++) {
            System.out.print("0 to " + i + ": ");
            System.out.print("(" + dijkstra.distTo(i) + ") ");
            System.out.println(dijkstra.pathTo(i));
        }
    }
}

相关文章

  • 算法课 实验7

    实验问题描述: 加权无向图最短路径查找,从一点到另外一点的最小路径,比如从成都到北京,途中有好多城市,如何规划路线...

  • 基于SARSA算法的自主寻路绕障

    机器智能实验课自选实验设计说明 选题 在Secondlife上模拟基于SARSA算法的自主寻路绕障 算法介绍 强化...

  • 算法课 实验4

    1.任务编排问题 任务编排问题取自算法导论上的一种解法,如果希望获得最多的任务数量的话,比方说有一个任务集合{S1...

  • 算法课 实验6

    参考文献 实验问题描述 一个汽车公司在有2条装配线的工厂内生产汽车,每条装配线有n个装配站,不同装配线上对应的装配...

  • 算法课 实验 3

    实验报告 1. 归并排序的(非递归)实现 实验讨论以及实验代码 (1)将两个相邻的有序序列归并成一个有序序列,称为...

  • 2017-11-07

    实验楼的SQL基础练习前四个实验。over 计划:实验楼的下四个SQL实验。 计划:七月算法一节课。

  • 冒泡算法demon

    写一个冒泡算法。重温下算法课。 [1, 2, 3, 4, 5, 6, 7, 8, 9]

  • 2019-10-28

    算法的上机实验

  • DES算法实现

    实验目标 完成一个DES 算法的详细设计,内容包括: 算法概述; 总体结构; 数据结构。 实验概述 算法原理 DE...

  • 密码学第二次实验报告:RSA算法

    实验题目 RSA算法 实验目的 了解公钥算法基本原理和RSA算法的原理。了解RSA算法在数据加密和数字签名中的应用...

网友评论

      本文标题:算法课 实验7

      本文链接:https://www.haomeiwen.com/subject/ayxbvxtx.html