- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用输入文件中的顶点和边来创建图形,然后使用 boost dijkstra 算法找到最短路径。到目前为止,我正在使用这段代码来读取看起来像这样的输入文件
Vertices:
A,B,C,D,E
Edges:
(A, B, 3)
(B, C, 4)
(C, D, 5)
(A, E, 6)
(C, E, 2)
代码
#include <boost/config.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/properties.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/tokenizer.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
using namespace boost;
using namespace std;
int main(){
typedef int Weight;
typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
typedef boost::property<boost::vertex_name_t, std::string> NameProperty;
typedef boost::property<boost::vertex_index_t, int> IndexProperty;
typedef boost::adjacency_list < boost::listS, boost::vecS, boost::undirectedS,
NameProperty, WeightProperty > Graph;
typedef boost::graph_traits < Graph >::vertex_descriptor Vertex;
typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap;
typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap;
typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap;
typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap;
Graph g;
typedef boost::tokenizer < boost::char_separator<char> >
tokenizer;
std::map<std::string, Vertex> Vmap;
//Initializes a graph and variables
Vertex u;
Vertex v;
char_separator<char> sep(",");
string filename = "";
string line = "";
string v1 = "";
string v2 = "";
fstream f;
Weight weight = 0;
//Prompts the user for the file name
std::cout << "Please enter the name of the text file: ";
std::cin >> filename;
//Opens the file and adds vertices and edges to graph g
f.open(filename);
getline(f, line); //Ignores first line "Vertices:"
getline(f, line);
tokenizer tokens(line, sep); //Tokenizes the second line "Location1, Location2 ..."
for (tokenizer::iterator tok_iter = tokens.begin();
tok_iter != tokens.end(); ++tok_iter) {
Vmap[*tok_iter] = add_vertex(*tok_iter, g); //For each token, add the value as a vertex in Graph g
}
getline(f, line); //Skip next line "Edges: "
while (!f.eof()){
getline(f, line);
line = line.substr(1, line.size() - 2); //Removes parentheses by creating a substring without the first and last char
tokenizer tokens(line, sep); //Tokenizes the string
for (tokenizer::iterator tok_iter = tokens.begin();
tok_iter != tokens.end(); ++tok_iter)
{
if (distance(tokens.begin(), tok_iter) == 0) //Sets first token "Location 1" to u
{
v1 = *tok_iter;
}
if (distance(tokens.begin(), tok_iter) == 1) //Sets second token "Location 2" to v
{
v2 = *tok_iter;
}
if (distance(tokens.begin(), tok_iter) == 2) //Sets third token "IntegerWeightValue" to weight
{
weight = stoi(*tok_iter);
}
}
add_edge(Vmap[v1], Vmap[v2], weight, g); //Adds weighted edge from Location 1 to Location 2 to Graph g
}
cout << "Please enter the starting node: ";
cin >> v1;
cout << "Please enter the ending node: ";
cin >> v2;
u = Vmap[v1];
v = Vmap[v2];
// Create things for Dijkstra
std::vector<Vertex> predecessors(num_vertices(g)); // To store parents
std::vector<Weight> distances(num_vertices(g)); // To store distances
IndexMap indexMap = boost::get(boost::vertex_index, g);
PredecessorMap predecessorMap(&predecessors[0], indexMap);
DistanceMap distanceMap(&distances[0], indexMap);
// Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances
// boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap).distance_map(distanceMap));
// This is exactly the same as the above line - it is the idea of "named parameters" - you can pass the
// prdecessor map and the distance map in any order.
boost::dijkstra_shortest_paths(g, u, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
std::cout << "distances and parents:" << std::endl;
NameMap nameMap = boost::get(boost::vertex_name, g);
BGL_FORALL_VERTICES(s, g, Graph)
{
std::cout << "distance(" << nameMap[u] << ", " << nameMap[s] << ") = " << distanceMap[s] << ", ";
std::cout << "predecessor(" << nameMap[s] << ") = " << nameMap[predecessorMap[s]] << std::endl;
}
// Extract a shortest path
std::cout << std::endl;
typedef std::vector<Graph::edge_descriptor> PathType;
PathType path;
// We want to start at the destination and work our way back to the source
for (Vertex p = predecessorMap[v]; // Start by setting 'u' to the destintaion node's predecessor
p != u; // Keep tracking the path until we get to the source
v = p, p = predecessorMap[v]) // Set the current vertex to the current predecessor, and the predecessor to one level up
{
std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(p, v, g);
Graph::edge_descriptor edge = edgePair.first;
path.push_back(edge);
}
// Write shortest path
std::cout << "Shortest path from " << v1 << " to " << v2 << std::endl;
float totalDistance = 0;
for (PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator != path.rend(); ++pathIterator)
{
std::cout << nameMap[boost::source(*pathIterator, g)] << " -> " << nameMap[boost::target(*pathIterator, g)]
<< " = " << boost::get(boost::edge_weight, g, *pathIterator) << std::endl;
}
std::cout << std::endl;
std::cout << "Distance: " << distanceMap[Vmap[v2]] << std::endl;
system("pause");
return 0;
}
最佳答案
我无法使用您的示例代码解析您的输入: Live On Coliru
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 1) > this->size() (which is 0)
我怀疑图形读取代码首先是罪魁祸首,因为当我用我理解的东西替换它时¹:
//Opens the file and adds vertices and edges to graph g
using namespace boost::spirit::qi;
std::fstream f(filename);
f >> std::noskipws;
std::vector<std::string> names;
std::vector<parsing::edgedef> defs;
if (f >> phrase_match(
"Vertices:" >> eol >> +alnum % ',' >> eol >>
"Edges:" >> eol >>
('(' >> +alnum >> ',' >> +alnum >> ',' >> int_ >> ')') % eol,
blank, names, defs))
{
for(auto& c : names)
Vmap[c] = add_vertex(c, g); // For each token, add the value as a vertex in Graph g
for(auto& def : defs)
{
std::cout << def.s << " -> " << def.t << " (" << def.weight << ")\n";
add_edge(Vmap[def.s], Vmap[def.t], def.weight, g); // Adds weighted edge from Location 1 to Location 2 to Graph g
}
}
一切似乎都按预期工作。除了解析(我还没有尝试修复)之外,我看不出程序逻辑有任何问题,所以我希望这对您有所帮助。
下面的程序打印 A->{C-E} 搜索的以下输出(总结输出):
Shortest path from A to A Distance : 0
Shortest path from A to B Distance : 3
Shortest path from A to C B -> C = 4 Distance : 7
Shortest path from A to D B -> C = 4 C -> D = 5 Distance : 12
Shortest path from A to E Distance : 6
#include <boost/fusion/adapted/struct.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_match.hpp>
//#include <boost/graph/graph_traits.hpp>
//#include <boost/graph/prim_minimum_spanning_tree.hpp>
//#include <boost/graph/properties.hpp>
//#include <boost/property_map/property_map.hpp>
//#include <boost/tokenizer.hpp>
typedef int Weight;
typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
typedef boost::property<boost::vertex_name_t, std::string> NameProperty;
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, NameProperty, WeightProperty> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexMap;
typedef boost::property_map<Graph, boost::vertex_name_t>::type NameMap;
typedef boost::iterator_property_map<Vertex*, IndexMap, Vertex, Vertex&> PredecessorMap;
typedef boost::iterator_property_map<int*, IndexMap, int, int&> DistanceMap;
typedef std::map<std::string, Vertex> VertexMap;
#include <iostream>
#include <fstream>
BOOST_FUSION_DEFINE_STRUCT((parsing), edgedef, (std::string,s)(std::string,t)(Weight,weight))
int main() {
Graph g;
VertexMap Vmap;
{
//Prompts the user for the file name
std::string filename = "";
std::cout << "Please enter the name of the text file: ";
std::cin >> filename;
//Opens the file and adds vertices and edges to graph g
using namespace boost::spirit::qi;
std::fstream f(filename);
f >> std::noskipws;
std::vector<std::string> names;
std::vector<parsing::edgedef> defs;
if (f >> phrase_match(
"Vertices:" >> eol >> +alnum % ',' >> eol >>
"Edges:" >> eol >>
('(' >> +alnum >> ',' >> +alnum >> ',' >> int_ >> ')') % eol,
blank, names, defs))
{
for(auto& c : names)
Vmap[c] = add_vertex(c, g); // For each token, add the value as a vertex in Graph g
for(auto& def : defs)
{
std::cout << def.s << " -> " << def.t << " (" << def.weight << ")\n";
add_edge(Vmap[def.s], Vmap[def.t], def.weight, g); // Adds weighted edge from Location 1 to Location 2 to Graph g
}
}
}
//Prompts user for starting and ending node
std::string v1 = "";
std::string v2 = "";
std::cout << "Please enter the starting node: ";
std::cin >> v1;
std::cout << "Please enter the ending node: ";
std::cin >> v2;
std::cout << "From " << v1 << " to " << v2 << "; num_vertices: " << num_vertices(g) << "\n";
auto const srce_vertex = Vmap[v1];
auto dest_vertex = Vmap[v2];
// Create things for Dijkstra
std::vector<Vertex> predecessors(num_vertices(g)); // To store parents
std::vector<Weight> distances(num_vertices(g)); // To store distances
IndexMap indexMap = boost::get(boost::vertex_index, g);
PredecessorMap predecessorMap(&predecessors[0], indexMap);
DistanceMap distanceMap(&distances[0], indexMap);
// Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances
// boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap).distance_map(distanceMap));
// This is exactly the same as the above line - it is the idea of "named parameters" - you can pass the
// prdecessor map and the distance map in any order.
boost::dijkstra_shortest_paths(g, srce_vertex, boost::distance_map(distanceMap).predecessor_map(predecessorMap));
std::cout << "distances and parents:" << std::endl;
NameMap nameMap = boost::get(boost::vertex_name, g);
BGL_FORALL_VERTICES(curr_vertex, g, Graph)
{
std::cout << "distance(" << nameMap[srce_vertex] << ", " << nameMap[curr_vertex] << ") = " << distanceMap[curr_vertex] << ", ";
std::cout << "predecessor(" << nameMap[curr_vertex] << ") = " << nameMap[predecessorMap[curr_vertex]] << std::endl;
}
// Extract a shortest path
std::cout << std::endl;
typedef std::vector<Graph::edge_descriptor> PathType;
PathType path;
// We want to start at the destination and work our way back to the source
for (Vertex curr_vertex = predecessorMap[dest_vertex]; // Start by setting 'srce_vertex' to the destination node's predecessor
curr_vertex != srce_vertex; // Keep tracking the path until we get to the source
dest_vertex = curr_vertex, curr_vertex = predecessorMap[dest_vertex]) // Set the current vertex to the current predecessor, and the predecessor to one level up
{
std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(curr_vertex, dest_vertex, g);
Graph::edge_descriptor edge = edgePair.first;
path.push_back(edge);
}
// Write shortest path
std::cout << "Shortest path from " << v1 << " to " << v2 << std::endl;
float totalDistance = 0;
for (PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator != path.rend(); ++pathIterator)
{
std::cout << nameMap[boost::source(*pathIterator, g)] << " -> " << nameMap[boost::target(*pathIterator, g)]
<< " = " << boost::get(boost::edge_weight, g, *pathIterator) << std::endl;
}
std::cout << std::endl;
std::cout << "Distance: " << distanceMap[Vmap[v2]] << std::endl;
}
¹(抱歉,我意识到您理解我的解析的能力可能与我现在对您的解析代码的理解相匹配;不过这是关于测试的:))
关于c++ - Boost Dijkstra 代码不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27455776/
谁能告诉我这个 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
我是一名优秀的程序员,十分优秀!