- 算法设计与分析
- 家
- 算法基础知识
- DAA - 简介
- DAA - 算法分析
- DAA-分析方法
- 渐近符号和先验分析
- 时间复杂度
- 马斯特定理
- DAA - 空间复杂性
- 分而治之
- DAA-分而治之
- DAA - 最大最小问题
- DAA-归并排序
- DAA-二分查找
- 施特拉森矩阵乘法
- 唐叶算法
- 河内塔
- 贪心算法
- DAA-贪婪法
- 旅行商问题
- Prim 的最小生成树
- 克鲁斯卡尔的最小生成树
- Dijkstra 的最短路径算法
- 地图着色算法
- DAA-分数背包
- DAA - 带截止日期的作业排序
- DAA - 最佳合并模式
- 动态规划
- DAA-动态规划
- 矩阵链乘法
- 弗洛伊德·沃歇尔算法
- DAA - 0-1 背包
- 最长公共子序列
- 旅行商问题| 动态规划
- 随机算法
- 随机算法
- 随机快速排序
- 卡格的最低削减
- 费舍尔-耶茨洗牌
- 近似算法
- 近似算法
- 顶点覆盖问题
- 设置封面问题
- 旅行推销员近似算法
- 排序技巧
- DAA-快速排序
- DAA-冒泡排序
- DAA——插入排序
- DAA-选择排序
- DAA——希尔排序
- DAA-堆排序
- DAA——桶排序
- DAA——计数排序
- DAA - 基数排序
- 搜索技巧
- 搜索技术介绍
- DAA - 线性搜索
- DAA-二分查找
- DAA - 插值搜索
- DAA - 跳转搜索
- DAA - 指数搜索
- DAA - 斐波那契搜索
- DAA - 子列表搜索
- DAA-哈希表
- 图论
- DAA-最短路径
- DAA - 多级图
- 最优成本二叉搜索树
- 堆算法
- DAA-二叉堆
- DAA-插入法
- DAA-Heapify 方法
- DAA-提取方法
- 复杂性理论
- 确定性计算与非确定性计算
- DAA-最大派系
- DAA - 顶点覆盖
- DAA - P 级和 NP 级
- DAA-库克定理
- NP 硬课程和 NP 完全课程
- DAA - 爬山算法
- DAA 有用资源
- DAA - 快速指南
- DAA - 有用的资源
- DAA - 讨论
设计与分析多级图
多级图G = (V, E)是一个有向图,其中顶点被划分为k个(其中k > 1)个不相交子集S = {s 1 ,s 2 ,…,s k }使得边(u, v)在 E 中,则 对于分区中的某些子集u Є s i和v Є s 1 + 1且 | s 1 | = | s k | = 1。
顶点s Є s 1称为源,顶点t Є s k称为汇。
G通常被假设为加权图。在此图中,边(i, j)的成本由c(i, j)表示。因此,从源s到汇t的路径成本是该路径中每条边的成本之和。
多级图问题是寻找从源s到汇t 的成本最小的路径。
例子
考虑以下示例来理解多级图的概念。
根据公式,我们必须使用以下步骤计算成本(i,j)
步骤 1:成本 (K-2, j)
本步骤中,选择三个节点(节点4、5、6)作为j。因此,我们有三个选项来选择这一步的最小成本。
成本(3, 4) = 最小值 {c(4, 7) + 成本(7, 9),c(4, 8) + 成本(8, 9)} = 7
成本(3, 5) = 最小值 {c(5, 7) + 成本(7, 9),c(5, 8) + 成本(8, 9)} = 5
成本(3, 6) = 最小值{c(6, 7) + 成本(7, 9),c(6, 8) + 成本(8, 9)} = 5
步骤 2:成本 (K-3, j)
选择两个节点作为 j,因为在阶段 k - 3 = 2 有两个节点 2 和 3。因此,值 i = 2 并且 j = 2 和 3。
成本(2, 2) = 最小值{c(2, 4) + 成本(4, 8) + 成本(8, 9),c(2, 6) +
成本(6, 8) + 成本(8, 9)} = 8
成本(2, 3) = {c(3, 4) + 成本(4, 8) + 成本(8, 9), c(3, 5) + 成本(5, 8)+ 成本(8, 9), c(3, 6) + 成本(6, 8) + 成本(8, 9)} = 10
步骤 3:成本(K-4,j)
成本 (1, 1) = {c(1, 2) + 成本(2, 6) + 成本(6, 8) + 成本(8, 9), c(1, 3) + 成本(3, 5) +成本(5, 8) + 成本(8, 9))} = 12
c(1, 3) + 成本(3, 6) + 成本(6, 8 + 成本(8, 9))} = 13
因此,具有最小成本的路径是1→ 3→ 5→ 8→ 9。
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <limits.h> // Function to find the minimum cost path in the multistage graph typedef struct { int *path; int length; } Result; Result multistage_graph(int graph[][2], int num_edges, int num_vertices, int stages[][3], int num_stages) { // Initialize the lists to store the minimum costs and the next vertex in the path for each vertex int *min_costs = (int *)malloc(num_vertices * sizeof(int)); int *next_vertex = (int *)malloc(num_vertices * sizeof(int)); for (int i = 0; i < num_vertices; i++) { min_costs[i] = INT_MAX; next_vertex[i] = -1; } // Initialize the minimum cost for the sink vertex to 0 min_costs[num_vertices - 1] = 0; // Traverse the graph in reverse order starting from the second-last stage for (int i = num_stages - 2; i >= 0; i--) { for (int j = 0; j < num_vertices; j++) { if (stages[i][0] == j || stages[i][1] == j || stages[i][2] == j) { for (int k = 0; k < num_edges; k++) { if (graph[k][0] == j) { int neighbor = graph[k][1]; int cost = graph[k][2] + min_costs[neighbor]; if (cost < min_costs[j]) { // Update the minimum cost and next vertex for the current vertex min_costs[j] = cost; next_vertex[j] = neighbor; } } } } } } // Reconstruct the minimum cost path from source to sink int *path = (int *)malloc(num_vertices * sizeof(int)); int current_vertex = 0; // Start from the source vertex int path_length = 0; while (current_vertex != -1) { path[path_length++] = current_vertex; current_vertex = next_vertex[current_vertex]; } // Free the dynamically allocated memory for min_costs and next_vertex free(min_costs); free(next_vertex); // Store the result in a Result structure Result result; result.path = path; result.length = path_length; return result; } int main() { // Define the multistage graph represented as an adjacency list int graph[][2] = { {0, 1}, {0, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 5}, {4, 5}, {5, 6}, {6, 7}, {7, 8} }; int num_edges = sizeof(graph) / sizeof(graph[0]); // Define the stages of the multistage graph int stages[][3] = { {8}, // Sink stage {6, 7}, // Stage K-1 {3, 4, 5}, // Stage K-2 {1, 2} // Source stage }; int num_stages = sizeof(stages) / sizeof(stages[0]); int num_vertices = 9; // Total number of vertices in the graph // Find the minimum cost path and cost using the multistage_graph function Result result = multistage_graph(graph, num_edges, num_vertices, stages, num_stages); // Print the result printf("Minimum cost path: "); for (int i = 0; i < result.length; i++) { printf("%d ", result.path[i]); } printf("\nMinimum cost: %d\n", result.path[result.length - 1]); // Free the dynamically allocated memory for the path free(result.path); return 0; }
输出
Minimum cost path: 0 2 Minimum cost: 2
#include <iostream> #include <vector> #include <unordered_map> #include <limits> // Function to find the minimum cost path in the multistage graph std::pair<std::vector<int>, int> multistage_graph(std::unordered_map<int, std::unordered_map<int, int>>& graph, std::vector<std::vector<int>>& stages) { int num_stages = stages.size(); int num_vertices = graph.size(); // Initialize the lists to store the minimum costs and the next vertex in the path for each vertex std::vector<int> min_costs(num_vertices, std::numeric_limits<int>::max()); std::vector<int> next_vertex(num_vertices, -1); // Initialize the minimum cost for the sink vertex to 0 min_costs[num_vertices - 1] = 0; // Traverse the graph in reverse order starting from the second-last stage for (int i = num_stages - 2; i >= 0; i--) { for (int vertex : stages[i]) { for (auto neighbor : graph[vertex]) { int cost = neighbor.second + min_costs[neighbor.first]; if (cost < min_costs[vertex]) { // Update the minimum cost and next vertex for the current vertex min_costs[vertex] = cost; next_vertex[vertex] = neighbor.first; } } } } // Reconstruct the minimum cost path from source to sink std::vector<int> path; int current_vertex = 0; // Start from the source vertex while (current_vertex != -1) { path.push_back(current_vertex); current_vertex = next_vertex[current_vertex]; } // Return the path and the minimum cost as a pair return std::make_pair(path, min_costs[0]); } int main() { // Define the multistage graph represented as an adjacency map std::unordered_map<int, std::unordered_map<int, int>> graph = { {0, {{1, 2}, {2, 3}}}, {1, {{3, 5}, {4, 2}}}, {2, {{3, 4}, {4, 1}}}, {3, {{5, 6}}}, {4, {{5, 3}}}, {5, {{6, 1}}}, {6, {{7, 1}}}, {7, {{8, 1}}}, {8, {}} }; // Define the stages of the multistage graph std::vector<std::vector<int>> stages = { {8}, // Sink stage {6, 7}, // Stage K-1 {3, 4, 5}, // Stage K-2 {1, 2} // Source stage }; // Find the minimum cost path and cost using the multistage_graph function auto result = multistage_graph(graph, stages); // Print the result std::cout << "Minimum cost path: "; for (int vertex : result.first) { std::cout << vertex << " "; } std::cout << std::endl; std::cout << "Minimum cost: " << result.second << std::endl; return 0; }
输出
Minimum cost path: 0 Minimum cost: 2147483647
import java.util.*; public class Main { // Function to find the minimum cost path in the multistage graph static class Result { List<Integer> path; int cost; Result(List<Integer> path, int cost) { this.path = path; this.cost = cost; } } static Result multistage_graph(HashMap<Integer, HashMap<Integer, Integer>> graph, List<List<Integer>> stages) { int num_stages = stages.size(); int num_vertices = graph.size(); // Initialize the lists to store the minimum costs and the next vertex in the path for each vertex List<Integer> min_costs = new ArrayList<>(Collections.nCopies(num_vertices, Integer.MAX_VALUE)); List<Integer> next_vertex = new ArrayList<>(Collections.nCopies(num_vertices, -1)); // Initialize the minimum cost for the sink vertex to 0 min_costs.set(num_vertices - 1, 0); // Traverse the graph in reverse order starting from the second-last stage for (int i = num_stages - 2; i >= 0; i--) { for (int vertex : stages.get(i)) { for (Map.Entry<Integer, Integer> neighbor : graph.get(vertex).entrySet()) { int cost = neighbor.getValue() + min_costs.get(neighbor.getKey()); if (cost < min_costs.get(vertex)) { // Update the minimum cost and next vertex for the current vertex min_costs.set(vertex, cost); next_vertex.set(vertex, neighbor.getKey()); } } } } // Reconstruct the minimum cost path from source to sink List<Integer> path = new ArrayList<>(); int current_vertex = 0; // Start from the source vertex while (current_vertex != -1) { path.add(current_vertex); current_vertex = next_vertex.get(current_vertex); } // Return the path and the minimum cost as a Result object return new Result(path, min_costs.get(0)); } public static void main(String[] args) { // Define the multistage graph represented as an adjacency map HashMap<Integer, HashMap<Integer, Integer>> graph = new HashMap<>(); graph.put(0, new HashMap<>()); graph.get(0).put(1, 2); graph.get(0).put(2, 3); graph.put(1, new HashMap<>()); graph.get(1).put(3, 5); graph.get(1).put(4, 2); graph.put(2, new HashMap<>()); graph.get(2).put(3, 4); graph.get(2).put(4, 1); graph.put(3, new HashMap<>()); graph.get(3).put(5, 6); graph.put(4, new HashMap<>()); graph.get(4).put(5, 3); graph.put(5, new HashMap<>()); graph.get(5).put(6, 1); graph.put(6, new HashMap<>()); graph.get(6).put(7, 1); graph.put(7, new HashMap<>()); graph.get(7).put(8, 1); graph.put(8, new HashMap<>()); // Define the stages of the multistage graph List<List<Integer>> stages = new ArrayList<>(); stages.add(Collections.singletonList(8)); // Sink stage stages.add(Arrays.asList(6, 7)); // Stage K-1 stages.add(Arrays.asList(3, 4, 5)); // Stage K-2 stages.add(Arrays.asList(1, 2)); // Source stage // Find the minimum cost path and cost using the multistage_graph function Result result = multistage_graph(graph, stages); // Print the result System.out.print("Minimum cost path: "); for (int vertex : result.path) { System.out.print(vertex + " \n"); } System.out.println(); System.out.println("Minimum cost: " + result.cost); } }
输出
Minimum cost path: 0 Minimum cost: 2147483647s
def multistage_graph(graph, stages): num_stages = len(stages) num_vertices = len(graph) # Create a list to store the minimum costs for each vertex min_costs = [float('inf')] * num_vertices # Create a list to store the next vertex in the path for each vertex next_vertex = [None] * num_vertices # Initialize the minimum cost for the sink vertex min_costs[-1] = 0 # Traverse the graph in reverse order for i in range(num_stages - 2, -1, -1): for vertex in stages[i]: # Calculate the minimum cost and next vertex for the current vertex for neighbor in graph[vertex]: cost = graph[vertex][neighbor] + min_costs[neighbor] if cost < min_costs[vertex]: min_costs[vertex] = cost next_vertex[vertex] = neighbor # Reconstruct the minimum cost path path = [] current_vertex = 0 # Start from the source vertex while current_vertex is not None: path.append(current_vertex) current_vertex = next_vertex[current_vertex] return path, min_costs[0] # Example usage: if __name__ == "__main__": # The multistage graph represented as an adjacency dictionary graph = { 0: {1: 2, 2: 3}, 1: {3: 5, 4: 2}, 2: {3: 4, 4: 1}, 3: {5: 6}, 4: {5: 3}, 5: {6: 1}, 6: {7: 1}, 7: {8: 1}, 8: {} } # Define the stages of the multistage graph stages = [ [8], # Sink stage [6, 7], # Stage K-1 [3, 4, 5], # Stage K-2 [1, 2] # Source stage ] path, min_cost = multistage_graph(graph, stages) print("Minimum cost path:", path) print("Minimum cost:", min_cost)
输出
Minimum cost path: [0] Minimum cost: inf