迪杰斯特拉算法java实现

 

package newnew;

// Edge 类定义
class Edge {
    int source;
    int destination;
    int weight; // 假设权重代表时间
    int cost;
    int storage;

    // 构造函数
    public Edge(int source, int destination, int weight, int cost, int storage) {
        this.source = source;
        this.destination = destination;
        this.weight = weight;
        this.cost = cost;
        this.storage = storage;
    }

    // 重写 toString 方法
    @Override
    public String toString() {
        return "Edge{" +
                "source=" + source +
                ", destination=" + destination +
                ", weight=" + weight +
                ", cost=" + cost +
                ", storage=" + storage +
                '}';
    }
}

 

package newnew;
import java.util.*;
// Graph 类定义
class Graph {
    // 顶点集合
    private Set<Integer> vertices;
    // 边集合
    private List<Edge> edges;
    // 邻接表
    private Map<Integer, List<Edge>> adjacencyList;

    // 构造函数
    public Graph() {
        this.vertices = new HashSet<>();
        this.edges = new ArrayList<>();
        this.adjacencyList = new HashMap<>();
    }

    // 获取顶点集合
    public Set<Integer> getVertices() {
        return vertices;
    }

    // 获取指定顶点的边集合
    // 获取某个顶点的边列表
    public List<Edge> getEdges(int u) {
        // 使用 getOrDefault 方法获取以顶点 u 为键的邻接表,如果该键不存在,则返回一个空列表
        return adjacencyList.getOrDefault(u, Collections.emptyList());
    }
    // 添加顶点
    public void addVertex(int vertex) {
        // 将顶点添加到图的顶点集合中
        vertices.add(vertex);

        // 在邻接表中以该顶点为键,新建一个空的邻接表(边列表)作为值
        adjacencyList.put(vertex, new ArrayList<>());
    }

    // 添加边
    public void addEdge(int source, int destination, Edge edge) {
        // 将边对象添加到图的边列表中
        edges.add(edge);

        // 获取源顶点对应的邻接表(边列表)
        List<Edge> adjacencyEdges = adjacencyList.get(source);

        // 将边对象添加到源顶点的邻接表中
        adjacencyEdges.add(edge);
    }

    @Override
    public String toString() {
        return "Graph{" +
                "vertices=" + vertices +
                ", edges=" + edges +
                ", adjacencyList=" + adjacencyList +
                '}';
    }
}

 

 

package newnew;
import java.util.*;
// AstreaAlgorithm 类定义
public class AstreaAlgorithm {
static int costs;
    // 寻找最优路径的方法,接收图、起点、终点和预算作为参数
    public static List<Integer> findOptimalPath(Graph graph, int source, int destination, int budget) {

        // 调用 findShortestPath 方法获取初始路径
        List<Integer> path = findShortestPath(graph, source, destination);
        System.out.println(path);

        // 初始化当前节点为起点
        int u = source;
        // 标志是否需要重新计算路径
        boolean recalculatePath = true;

        // 循环直到路径为空或当前节点为终点
        while (!path.isEmpty() && u != destination) {
            // 初始化成本和存储
            int cost = 0, stor = 0;
            int time=0;

            // 遍历当前路径
            for (int i = 0; i < path.size() - 1; i++) {
                int currentVertex = path.get(i);
                int nextVertex = path.get(i + 1);

                // 通过流操作获取当前边
                Edge edge = graph.getEdges(currentVertex).stream()
                        .filter(e -> e.destination == nextVertex)
                        .findFirst()
                        .orElse(null);

                // 如果边存在
                if (edge != null) {
                    // 累加成本和存储
                    cost += edge.cost;
                    stor += edge.storage;
time+=edge.weight;
                    // 如果成本超过预算,移除该边并标记需要重新计算路径
                    if (cost >= budget) {
                        graph.getEdges(currentVertex).remove(edge);
                        recalculatePath = true;
                        u = source;
                        break;
                    } else {
                        u = nextVertex;
                        costs=time;
                    }
                }
            }

            // 如果需要重新计算路径,调用 findShortestPath 方法
            if (recalculatePath) {
                path = findShortestPath(graph, source, destination);
                recalculatePath = false;
                System.out.println("Recalculated Shortest Path: " + path);
            }
        }
        System.out.println("time:"+costs);
        return path;
    }

    // 寻找最短路径的私有方法
    private static List<Integer> findShortestPath(Graph graph, int source, int destination) {
        // 优先队列用于最小距离优先
        PriorityQueue<NodeDistance> pq = new PriorityQueue<>(Comparator.comparingInt(nd -> nd.distance));
        // 记录节点到起点的距离
        Map<Integer, Integer> distance = new HashMap<>();
        // 记录节点的父节点
        Map<Integer, Integer> parent = new HashMap<>();
        // 将起点加入优先队列
        pq.add(new NodeDistance(source, 0));
        // 起点到自身的距离为0
        distance.put(source, 0);
        // 循环直到优先队列为空
        while (!pq.isEmpty()) {
            // 取出距离起点最近的节点
            NodeDistance nodeDistance = pq.poll();
            int current = nodeDistance.node;

            // 如果当前节点是目标节点,重建并返回最短路径
            if (current == destination) {
                List<Integer> path = new ArrayList<>();
                int node = destination;
                // 从目标节点逆向遍历父节点,重建路径
                while (node != source) {
                    path.add(node);
                    node = parent.get(node);
                }
                path.add(source);
                Collections.reverse(path);
                return path;
            }

            // 处理当前节点的邻居节点
            for (Edge edge : graph.getEdges(current)) {
                // 邻居节点的标识
                int neighbor = edge.destination;
                // 新的距离
                int newDistance = distance.getOrDefault(current, Integer.MAX_VALUE) + edge.weight;

                // 如果新的距离比已知的距离小,更新距离和父节点,并将邻居节点加入优先队列
                if (newDistance < distance.getOrDefault(neighbor, Integer.MAX_VALUE)) {
                    distance.put(neighbor, newDistance);
                    parent.put(neighbor, current);
                    pq.add(new NodeDistance(neighbor, newDistance));
                }
            }
        }

        // 如果循环结束仍未找到路径,返回空列表
        return Collections.emptyList();
    }

    // 内部私有类,表示节点和距离的封装
    private static class NodeDistance {
        int node;
        int distance;

        NodeDistance(int node, int distance) {
            this.node = node;
            this.distance = distance;
        }
    }
}
package newnew;

import java.util.List;

// 主类定义
class Main {
    // 主方法
    public static void main(String[] args)
    {
        // 创建图对象
        Graph graph = new Graph();

        // 添加顶点
        graph.addVertex(1);
        graph.addVertex(2);
        graph.addVertex(3);
        graph.addVertex(4);


        // 添加边,包括权重、成本和存储信息
        graph.addEdge(1, 4, new Edge(1, 4, 12, 2, 1));
        graph.addEdge(1, 2, new Edge(1, 2, 10, 2, 1));
        graph.addEdge(2, 4, new Edge(2, 4, 14, 3, 2));
        graph.addEdge(2, 3, new Edge(2, 3, 9, 1, 2));
        graph.addEdge(4, 3, new Edge(4, 3, 3, 3, 2));



        // 设置起点、终点和预算
        int source = 1;
        int destination = 3;
        int budget = 4;
        System.out.println("小狗:"+graph);
        // 调用 AstreaAlgorithm 类中的 findOptimalPath 方法
        List<Integer> optimalPath = AstreaAlgorithm.findOptimalPath(graph, source, destination, budget);
        // 打印最优路径
        System.out.println("Optimal Path: " + optimalPath);
    }
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值