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 vertices;
// 边集合
private List edges;
// 邻接表
private Map> adjacencyList;
// 构造函数
public Graph() {
this.vertices = new HashSet<>();
this.edges = new ArrayList<>();
this.adjacencyList = new HashMap<>();
}
// 获取顶点集合
public Set getVertices() {
return vertices;
}
// 获取指定顶点的边集合
// 获取某个顶点的边列表
public List 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 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 findOptimalPath(Graph graph, int source, int destination, int budget) {
// 调用 findShortestPath 方法获取初始路径
List 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 findShortestPath(Graph graph, int source, int destination) {
// 优先队列用于最小距离优先
PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(nd -> nd.distance));
// 记录节点到起点的距离
Map distance = new HashMap<>();
// 记录节点的父节点
Map 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 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 optimalPath = AstreaAlgorithm.findOptimalPath(graph, source, destination, budget);
// 打印最优路径
System.out.println("Optimal Path: " + optimalPath);
}
}