实验三 贪心算法

实验三 贪心算法

迪杰斯特拉的贪心算法实现

优先队列等

1.实验目的

1、掌握贪心算法的基本要素 :最优子结构性质和贪心选择性质

2、应用优先队列求单源顶点的最短路径Dijkstra算法,掌握贪心算法。

2.实验环境

Java

3.问题描述

给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。

4.复杂度分析

Dijkstra算法的时间复杂度为O((m+n)logn),其中m是边的数量,n是顶点的数量。

5.代码实现

复制代码
package shiyan3_3;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

public class DijkstraAlgorithm {

    public static void main(String[] args) throws IOException {
        runDijkstraAlgorithm("input.txt", "output.txt");
    }

    private static class Result {
        int dist;
        List<Integer> path;

        public Result(int dist, List<Integer> path) {
            this.dist = dist;
            this.path = path;
        }
    }

    public static void runDijkstraAlgorithm(String inputFile, String outputFile) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        String[] input = reader.readLine().split(" ");
        int n = Integer.parseInt(input[0]);
        int m = Integer.parseInt(input[1]);

        List<Edge>[] graph = new List[n + 1];
        for (int i = 1; i <= n; i++) {
            graph[i] = new ArrayList<>();
        }

        for (int i = 0; i < m; i++) {
            input = reader.readLine().split(" ");
            int u = Integer.parseInt(input[0]);
            int v = Integer.parseInt(input[1]);
            int w = Integer.parseInt(input[2]);
            graph[u].add(new Edge(v, w));
        }
        reader.close();

        int s = 1;
        Result[] results = new Result[n + 1];
        PriorityQueue<Node> pq = new PriorityQueue<>();
        for (int i = 1; i <= n; i++) {
            if (i == s) continue;

            int[] dist = new int[n + 1];
            int[] pre = new int[n + 1];
            Arrays.fill(dist, Integer.MAX_VALUE);
            Arrays.fill(pre, -1);

            dist[s] = 0;
            pq.offer(new Node(s, 0));
            while (!pq.isEmpty()) {
                Node curr = pq.poll();
                if (curr.dist != dist[curr.u]) continue;
                for (Edge edge : graph[curr.u]) {
                    int v = edge.v;
                    int weight = edge.weight;
                    if (dist[v] > dist[curr.u] + weight) {
                        dist[v] = dist[curr.u] + weight;
                        pre[v] = curr.u;
                        pq.offer(new Node(v, dist[v]));
                    }
                }
            }

            List<Integer> path = new ArrayList<>();
            if (pre[i] != -1) getPath(i, pre, path);
            if (path.size() > 0) path.add(0, s);
            results[i] = new Result(dist[i], path);
        }

        PrintWriter writer = new PrintWriter(new FileWriter(outputFile));
        writer.println("起点\t终点\t最短路径\t\t\t最短路径长度");
        for (int i = 1; i <= n; i++) {
            if (i == s) continue;
            String res = s + "\t" + i + "\t";
            if (results[i] == null || results[i].path.size() == 0) {
                res += "NA\t\t\tNA";
            } else {
                String path = results[i].path.stream().map(Object::toString).collect(Collectors.joining("->"));
                int padding = 32 - path.length();
                if (padding > 0) path += String.format("%" + padding + "s", "");
                res += path + "\t" + results[i].dist;
            }
            writer.println(res);
        }
        writer.close();
        System.out.println("输出成功!");
    }

    private static void getPath(int u, int[] pre, List<Integer> path) {
        if (u == -1) return;
        getPath(pre[u], pre, path);
        path.add(u);
    }

    private static class Node implements Comparable<Node> {
        int u;
        int dist;

        public Node(int u, int dist) {
            this.u = u;
            this.dist = dist;
        }

        @Override
        public int compareTo(Node other) {
            return Integer.compare(this.dist, other.dist);
        }
    }

    private static class Edge {
        int v;
        int weight;

        public Edge(int v, int weight) {
            this.v = v;
            this.weight = weight;
        }
    }
}

输入

运行

输出

相关推荐
吹什么轩6 小时前
linux系统复习:进程优先级与O(1)调度
java·linux·算法
开开心心就好6 小时前
安卓PDF处理工具,免费无广告零弹窗
android·服务器·开发语言·算法·pdf·ocr
zyl7651 天前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖1 天前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌1 天前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F1 天前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_307779131 天前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang03221 天前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!1 天前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
2501_926978331 天前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作