多个未加权图上的 Dijkstra 最短路径?
Posted
技术标签:
【中文标题】多个未加权图上的 Dijkstra 最短路径?【英文标题】:Dijkstra shortest path on multiple unweighted graphs? 【发布时间】:2022-01-19 16:45:06 【问题描述】:我正在试图弄清楚如何实现 djiktra 算法来找到 2 个未加权图之间的最短路径。我得到的建议是使用 2 个图,一个用于红色,一个用于蓝色。旅行的成本始终为 1,但要在蓝色时访问红色方块,您需要支付 2 来切换图形。
我主要是在寻找建议和参考有没有人做过类似的事情???
【问题讨论】:
您应该添加一些代码,到目前为止您尝试了什么? 您仍然可以将其建模为一张图。红红边的权重为 1,红蓝边的权重为 3(正常行程为 1,切换颜色为 2) 这不是未加权图。成本是 1 或 2(或者是 1 还是 3,问题没有说清楚)。这应该是应用此成本值的标准 Dijkstra 算法。 _我得到的建议是使用 2 个图表 _ 我建议忽略这个建议。它应该被建模为一个加权图。 【参考方案1】:基于原始图创建一个新的加权图,其中蓝色 -> 红色路径花费 3 而不是 1,然后在其上运行 Dijkstra。
编辑:可能没有必要实际创建新图,您可以直接从原始图获取权重,但首先创建新图可能更容易理解。
顶角如下所示:
A ← 3 → B ← 1 → C ← 1 → D ...
↑ ↑ ↑
1 1 3
↓ ↓ ↓
E ← 3 → F ← 3 → G...
【讨论】:
问题是,如果我通过支付 2 将颜色变为蓝色,我不应该每次在蓝色瓷砖上行走时都必须继续支付 3 是的,只调整改变颜色的边缘的成本 所以我需要在每次颜色变化时不断更改图形权重? 我为您的原始图表的左上角添加了一个示例,希望它更清晰 好吧,你的意思是,只有红色和蓝色连接在一起,成本才应该是 3,否则就是 1【参考方案2】:要创建图形,请使用此伪代码在节点之间添加边
AddEdge( n1, n2 )
SET cost = 1
IF n1color != n2color
SET cost = 3;
graph.AddEdge( n1, n2, cost );
RUN Dijsktra on graph
【讨论】:
【参考方案3】:这只是标准的 Dijkstra。
这不是未加权的图,您需要从一个顶点移动到另一个顶点。从一种颜色切换到另一种颜色只是一个额外的规则,需要额外的费用。
您所需要的只是一个计算两个顶点之间成本的函数,该函数只需查看每个顶点的颜色并适当地增加成本。请参阅:int getCost(Graph const& graph, Point src, Point dst)
下方。
除此之外,它是您应该应用的标准算法。
// Not pure C++
// But left enough work that you have to make an effort
// to complete this.
enum Color Red, Blue;
using Graph = std::vector_like<std::vector_like<Color>>;
using Point = std::pair<int, int>;
int getCost(Graph const& graph, Point src, Point dst)
// Assumes: src and dst are 1 point away from each other.
// This assumes that work is done via
// getListOfPointsReachable() which only gets nodes
// nodes that are adjecent.
//
// Standard movement cost.
int cost = 1;
// Add a cost if switching between blue red.
if (graph[src] != graph[dst])
cost += 2;
return cost;
std::list<Point> getListOfPointsReachable(Graph const& graph, Point src)
// Get a list of points that can be accessed by src.
// All points that are next to the current and return as a list.
// Check if they are out of bounds.
void Dijkstra(Graph const& graph, Point start, Point end)
std::set<Point> visited;
// Boundary: int => Cost
// Point => Point cost applies to.
// Using tuple as it already has the comparison operator defined.
using Boundary = std::tuple<int, Point>;
std:: priority_queue<Boundary> boundary;
// Set up the boundary list with a start.
boundary.emplace(0, start);
while (!boundary.empty())
Boundary next = boundry.top();
boundary.pop();
int cost = std::get<0>(next);
Point nextP = std::get<1>(next);
if (nextP == end)
throw std::runtime_error("Found route to end: Cheapest Route is: " + cost);
if (visited.find(nextP) != std::end(visited))
// we already did this node.
continue;
visited.insert(nextP);
std::list<Point> dests = getListOfPointsReachable(graph, nextP);
for (auto const& dest: dests)
int extraCost = getCost(graph, nextP, dest);
boundary.emplace(extraCost + cost, dest);
throw std::runtime_error("No Route from Start to End");
【讨论】:
以上是关于多个未加权图上的 Dijkstra 最短路径?的主要内容,如果未能解决你的问题,请参考以下文章