实验三 贪心算法

实验三 贪心算法

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

优先队列等

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;
        }
    }
}

输入

运行

输出

相关推荐
小超人诞生日记1 小时前
C++ 智能指针的使用及其原理详解
c++·算法
AiNightVision4 小时前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
牧羊人.3335 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
小郎君6586 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7776 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
東隅已逝,桑榆非晚7 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
专注仿真7 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
FII工业富联科技服务7 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
≮傷£≯√7 小时前
httpserver_QNetWorkClient
算法