为了发现具有权重大于或等于1的最小边的路径,我们可以使用稍作修改的Dijkstra算法。首先,我们将源节点的权重设为1,将其他节点的权重设为无穷大。在算法执行过程中,我们不再更新距离,而是更新权重的乘积。这样可以确保选择具有最小权重的路径。通过在每一步选择权重最小的节点,我们迭代地发现最短路径,直到达到目标节点。最后,沿着这条路径的权重乘积将是最小的,满足给定的条件。
修改后的Dijkstra算法,带有加权乘积
修改的Bellman-Ford算法,带有加权乘积
在修改后的Dijkstra算法中,我们首先将源节点的权重设置为无穷大,将所有其他节点的权重也设置为无穷大。在执行计算的过程中,我们不是用所有权重来更新距离,而是用到目前为止遇到的权重的乘积来更新它们。在每一步中,我们选择具有最小权重的节点,并以相同的方式更新其相邻节点的权重。这个过程一直持续到达目标节点。最终,沿着这条路径的权重乘积将表示最小可能值,满足权重大于或等于1的条件。
将所有中心权重初始化为无限大,除了源中心,其权重设置为0。
创建一个清除集合来跟踪已删除的节点。
当存在未访问的节点时,
选择未访问节点中权重最小的中心。
将所选中心标记为已访问。
对于每个未访问的相邻枢纽:
计算当前中心节点的权重和与之相连的边的权重。
如果计算出的项小于相邻中心的权重,则用计算出的乘积替换其权重。
重复步骤3,直到目标中心消失或所有中心都被访问。
目标中心的重量反映了从源头到目标点沿途最小的物品重量。
#include <bits/stdc++.h> using namespace std; // Function to return the smallest product of edges double modifiedDijkstra(int source, int destination, vector<vector<pair<int, double> > > graph) { // If the source is equal to the destination if (source == destination) return 0; // Initialize the priority queue set<pair<double, int>> pq; pq.insert({1, source}); // Visited array bool visited[graph.size()] = {0}; // While the priority queue is not empty while (!pq.empty()) { // Current node int current = pq.begin()->second; // Current product of weights double product = pq.begin()->first; // Pop the top-most element pq.erase(pq.begin()); // If already visited, continue if (visited[current]) continue; // Mark the node as visited visited[current] = true; // If it is a destination node if (current == destination) return product; // Traverse the neighbors of the current node for (auto neighbor : graph[current]) { int neighborNode = neighbor.first; double weight = neighbor.second; // Calculate the product of weights double newProduct = product * weight; // Insert the new product and neighbor into the priority queue pq.insert({newProduct, neighborNode}); } } // If no path exists return -1; } // Function to add an edge to the graph void addEdge(vector<vector<pair<int, double>>>& graph, int u, int v, double weight) { graph[u].push_back({v, weight}); } // Function to print the graph void printGraph(const vector<vector<pair<int, double>>>& graph) { for (int i = 1; i < graph.size(); i++) { cout << "Node " << i << ": "; for (auto neighbor : graph[i]) { cout << "(" << neighbor.first << ", " << neighbor.second << ") "; } cout << endl; } } // Driver code int main() { int numNodes = 3; // Graph as adjacency list vector<vector<pair<int, double>>> graph(numNodes + 1); // Input edges addEdge(graph, 1, 3, 9); addEdge(graph, 2, 3, 1); addEdge(graph, 1, 2, 5); // Source and destination int source = 1, destination = 3; // Modified Dijkstra double smallestProduct = modifiedDijkstra(source, destination, graph); // Print the result cout << "Smallest product of weights: " << smallestProduct << endl; // Print the graph cout << "Graph: " << endl; printGraph(graph); return 0; }
Smallest product of weights: 5 Graph: Node 1: (3, 9) (2, 5) Node 2: (3, 1) Node 3:
在带有加权对象的调整后的Bellman-Ford算法中,我们通过将源中心的负载设置为1,将所有其他中心的负载设置为无穷大来开始。在每个循环中,通过比较当前节点的权重和连接它们到目标中心的边的负载来解开所有边。如果计算得到的权重比目标中心的负载小,我们将其权重增加计算得到的权重。重复这个过程V-1次,其中V是中心的总数,以确保考虑到所有可能的路径。目标中心的权重表示从源到目标的路径上最小的权重。
除了源中心之外,所有其他中心的权重应为无穷大。
重复执行上述步骤 V−1 次,其中 V 是节点的总数:
对于图表中的每条边,计算当前中心的项目权重以及与它们相连的边的权重。
如果计算出的物品小于目标中心的重量,则用计算出的乘积升级其重量。
经过V−1个周期,所有中心节点的权重将被确定。
在计算过程中,如果图表中存在负权重循环,将会区分出一个额外的循环。如果在此过程中有任何权重被修正,这表明存在一个负权重循环的存在。
目标中心的重量反映了从源头到目标点沿途最小的物品重量。
贪婪着色算法基于可用颜色和邻居顶点使用的颜色,以贪婪的方式为顶点分配颜色。虽然它可能不总是使用最少数量的颜色来完成图表着色,但它提供了一种快速高效的顶点着色方法。
#include <iostream> #include <vector> #include <limits> struct Edge { int source, destination; double weight; }; // Function to find the smallest product of weights using the modified Bellman-Ford algorithm double findSmallestProduct(int numNodes, int source, int destination, std::vector<Edge>& edges) { std::vector<double> weights(numNodes, std::numeric_limits<double>::infinity()); weights[source] = 1; for (int i = 1; i < numNodes; i++) { for (const auto& edge : edges) { double newWeight = weights[edge.source] * edge.weight; if (newWeight < weights[edge.destination]) { weights[edge.destination] = newWeight; } } } for (const auto& edge : edges) { double newWeight = weights[edge.source] * edge.weight; if (newWeight < weights[edge.destination]) { return -1.0; // Negative-weight cycle detected } } return weights[destination]; } int main() { int numNodes = 4; std::vector<Edge> edges = { {0, 1, 2.0}, {1, 2, 0.5}, {2, 3, 1.5}, {0, 3, 1.2}, {1, 3, 0.8} }; int source = 0, destination = 3; double smallestProduct = findSmallestProduct(numNodes, source, destination, edges); if (smallestProduct < std::numeric_limits<double>::infinity()) { std::cout << "The smallest product of weights along the path from node " << source << " to node " << destination << " is: " << smallestProduct << std::endl; } else { std::cout << "A negative-weight cycle is detected. No valid path exists." << std::endl; } return 0; }
The smallest product of weights along the path from node 0 to node 3 is: 1.2
本文阐明了如何找到具有权重大于或等于1的最小边的路径。它介绍了两个算法,即改进的Dijkstra算法和改进的Bellman-Ford算法,用于解决这个问题。改进的Dijkstra算法在每一步选择具有最小权重的节点,而改进的Bellman-Ford算法迭代地解开边以更新权重。文章提供了这两个算法在C语言中的实现,并用测试输入说明了它们的使用。输出结果是从源节点到目标节点的路径上的最小权重。
以上是具有权重大于等于1的边的最小乘积路径的详细内容。更多信息请关注PHP中文网其他相关文章!