- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直在尝试在 C++11 中实现 Dijkstra 算法以处理任意大小的矩阵。具体来说,我有兴趣解决有关欧拉计划的第 83 题。
我似乎总是遇到这样一种情况,即与当前节点相邻的每个节点都已被访问过,如果我正确理解算法,这种情况永远不会发生。
我试过在调试器中四处寻找,并且我已经多次重新阅读代码,但我不知道我哪里出错了。
这是我到目前为止所做的:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <set>
#include <tuple>
#include <cstdint>
#include <cinttypes>
typedef std::tuple<size_t, size_t> Index;
std::ostream& operator<<(std::ostream& os, Index i)
{
os << "(" << std::get<0>(i) << ", " << std::get<1>(i) << ")";
return os;
}
template<typename T>
class Matrix
{
public:
Matrix(size_t i, size_t j):
n(i),
m(j),
xs(i * j)
{}
Matrix(size_t n, size_t m, const std::string& path):
n(n),
m(m),
xs(n * m)
{
std::ifstream mat_in {path};
char c;
for (size_t i = 0; i < n; ++i) {
for (size_t j = 0; j < m - 1; ++j) {
mat_in >> (*this)(i,j);
mat_in >> c;
}
mat_in >> (*this)(i,m - 1);
}
}
T& operator()(size_t i, size_t j)
{
return xs[n * i + j];
}
T& operator()(Index i)
{
return xs[n * std::get<0>(i) + std::get<1>(i)];
}
T operator()(Index i) const
{
return xs[n * std::get<0>(i) + std::get<1>(i)];
}
std::vector<Index> surrounding(Index ind) const
{
size_t i = std::get<0>(ind);
size_t j = std::get<1>(ind);
std::vector<Index> is;
if (i > 0)
is.push_back(Index(i - 1, j));
if (i < n - 1)
is.push_back(Index(i + 1, j));
if (j > 0)
is.push_back(Index(i, j - 1));
if (j < m - 1)
is.push_back(Index(i, j + 1));
return is;
}
size_t rows() const { return n; }
size_t cols() const { return m; }
private:
size_t n;
size_t m;
std::vector<T> xs;
};
/* Finds the minimum sum of the weights of the nodes along a path from 1,1 to n,m using Dijkstra's algorithm modified for matrices */
int64_t shortest_path(const Matrix<int>& m)
{
Index origin(0,0);
Index current { m.rows() - 1, m.cols() - 1 };
Matrix<int64_t> nodes(m.rows(), m.cols());
std::set<Index> in_path;
for (size_t i = 0; i < m.rows(); ++i)
for (size_t j = 0; j < m.cols(); ++j)
nodes(i,j) = INTMAX_MAX;
nodes(current) = m(current);
while (1) {
auto is = m.surrounding(current);
Index next = origin;
for (auto i : is) {
if (in_path.find(i) == in_path.end()) {
nodes(i) = std::min(nodes(i), nodes(current) + m(i));
if (nodes(i) < nodes(next))
next = i;
}
}
in_path.insert(current);
current = next;
if (current == origin)
return nodes(current);
}
}
int64_t at(const Matrix<int64_t>& m, const Index& i) { return m(i); }
int at(const Matrix<int>& m, const Index& i) { return m(i); }
int main()
{
Matrix<int> m(80,80,"mat.txt");
printf("%" PRIi64 "\n", shortest_path(m));
return 0;
}
最佳答案
你没有正确理解算法。没有什么能阻止你陷入死胡同。只要还有其他您尚未探索的选项,就将其标记为死胡同并继续前进。
顺便说一句,我同意评论员的说法,他们认为您使解决方案过于复杂了。创建一个“到这里的成本”矩阵并有一个点队列来探索路径就足够了。将总成本矩阵初始化为 NOT_VISITED 的值,-1 会起作用。对于每个点,您都会查看邻居。如果邻居尚未访问过,或者您只是找到了更便宜的路径,则调整成本矩阵并将该点添加到队列中。
继续前进,直到队列为空。然后您就可以保证在任何地方都以最低的成本。
A* 比这种朴素的方法更有效,但我刚才描述的方法足以解决问题。
关于c++ - 矩阵的 Dijkstra 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27093935/
谁能告诉我这个 Dijkstra 算法中优先级队列的空间复杂度。请注意,这里可以将一个顶点添加到队列中不止一次。但是,由于访问集,它不会被处理超过一次。这就是为什么我想知道队列的最大大小可以达到的原因
为什么我们不能将 Dijkstra 算法应用于具有负权重的图? 最佳答案 如果每次从 C 到 D 旅行都得到报酬,那么找到从 A 到 B 的最便宜的路径意味着什么? 如果两个节点之间存在负权重,则“最
我正在阅读 工作中的程序员 . 我在 Donald Knuth 的采访中看到了这一段。 Seibel: It seems a lot of the people I’ve talked to had
我一整天都在努力理解 Dijkstra 算法并实现,但没有取得任何重大成果。我有一个城市及其距离的矩阵。我想做的是给定一个起点和一个终点,找到城市之间的最短路径。 示例: __0__ __1
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
一 问题描述 小明为位置1,求他到其他各顶点的距离。 二 实现 package graph.dijkstra; import java.util.Scanner; import java.util.
一 问题背景 在现实生活中,很多问题都可以转化为图来解决问题。例如,计算地图中两点之间的最短距离、网络最小成本布线,以及工程进度控制,等等。这些问题都涉及最小路径的求解。 二 Dijkstra 算法
谁能告诉我这个程序的错误在哪里,这真的很有帮助,我尽力解决了这个问题,这段代码只通过了两个测试用例给定一个无向图和一个起始节点,确定从起始节点到图中所有其他节点的最短路径的长度。如果一个节点不可到达,
除了 Dijkstra 之外,还有其他方法可以计算接近完整图的最短路径吗?我有大约 8,000 个节点和大约 1800 万条边。我已经完成了线程 "a to b on map"并决定使用 Dijkst
我知道 Dijkstra 的算法、Floyd-Warshall 算法和 Bellman-Ford 算法,用于查找图中 2 个顶点之间的最便宜路径。 但是当所有边的成本都相同时,最便宜的路径是边数最少的
我的问题如下:根据不同的消息来源,Dijkstra 算法只不过是 Uniform Cost Search 的一种变体。我们知道 Dijkstra 的算法会找到源和所有目的地(单源)之间的最短路径。但是
所以我的问题是我有一个带有 的有向图 G非负 边长度,我希望找到两个节点 u 和 v 之间的最短路径,以便它们只通过图中的一个标记节点。 如果我们没有涉及标记节点的条件,这个问题可以使用 Dijkst
对于使用最小堆优先级队列的 Dijkstra 实现,我将其设置为查找网络上不存在的站,以便它必须检查所有内容。我的问题是由于整体时间复杂度 O(V + E log V) ,为什么网络查找到一个站点的最
我试图找出是否可以使用 Dijkstra 算法来找到有向无环路径中的最长路径。我知道由于负成本循环,不可能在一般图中找到 Dijkstra 的最长路径。但我认为它应该在 DAG 中工作。通过谷歌我发现
我正在研究 Dijkstra 算法,我真的需要找到所有可能的最短路径,而不仅仅是一条。我正在使用邻接矩阵并应用 Dijkstra 算法,我可以找到最短路径。但是我需要以最低成本找到所有路径,我的意思是
我正在尝试创建 Dijkstra 寻路的实现,除了我要求它创建一条在同一位置开始和结束的路线之外,它似乎工作得很好。 JSFiddle:http://jsfiddle.net/Lt6b4ecr/ 我需
我们可以使用负权重的 Dijkstra 算法吗? 停止! 在您认为“大声笑,您可以在两点之间无休止地跳跃并获得无限便宜的路径”之前,我更多地考虑的是单向路径。 对此的应用程序将是一个带有点的山地地形。
我认为 Dijkstra 算法是确定的,因此,如果您选择相同的起始顶点,您将得到相同的结果(到每个其他顶点的距离相同)。但我不认为它是确定性的(它为每个操作定义了以下操作),因为这意味着它不必首先搜索
我找到了this code使用 Dijkstra 算法来查找加权图中两个节点之间的最短路径。我看到的是代码没有跟踪访问过的节点。但是它对于我尝试过的所有输入都适用。我添加了一行代码来跟踪访问过的节点。
我将 Dijkstra 算法 的 C++ 实现转换为 Java。当我运行 Java 代码时,我没有得到预期的输出 我的 C++ 代码的预期: Minimum distance for source v
我是一名优秀的程序员,十分优秀!