Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 推进Dijkstra代码不工作?_C++_Boost_Graph_Dijkstra - Fatal编程技术网

C++ 推进Dijkstra代码不工作?

C++ 推进Dijkstra代码不工作?,c++,boost,graph,dijkstra,C++,Boost,Graph,Dijkstra,我试图使用输入文件中的顶点和边创建一个图,然后使用boost dijkstra算法找到最短路径。到目前为止,我正在使用此代码读取输入文件,如下所示 Vertices: A,B,C,D,E Edges: (A, B, 3) (B, C, 4) (C, D, 5) (A, E, 6) (C, E, 2) 代码 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 使用名称空间boost; 使用名称空间std; int main(){ 输入重

我试图使用输入文件中的顶点和边创建一个图,然后使用boost dijkstra算法找到最短路径。到目前为止,我正在使用此代码读取输入文件,如下所示

Vertices:
A,B,C,D,E
Edges:
(A, B, 3)
(B, C, 4)
(C, D, 5)
(A, E, 6)
(C, E, 2)
代码

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间boost;
使用名称空间std;
int main(){
输入重量;
typedef boost::属性权重属性;
typedef boost::property name属性;
typedef boost::property索引属性;
typedef boost::邻接列表Graph;
typedef boost::graph_traits::顶点描述符顶点;
typedef boost::property_map::type IndexMap;
typedef boost::property_map::type NameMap;
typedef boost::迭代器属性映射<顶点*,索引映射,顶点,顶点&>前置映射;
typedef boost::迭代器属性映射DistanceMap;
图g;
typedef boost::标记器
标记器;
std::map-Vmap;
//初始化图形和变量
顶点u;
顶点v;
字符分隔符sep(“,”);
字符串filename=“”;
字符串行=”;
字符串v1=“”;
字符串v2=“”;
fsf;
重量=0;
//提示用户输入文件名
std::cout>filename;
//打开文件并将顶点和边添加到图形g
f、 打开(文件名);
getline(f,line);//忽略第一行“顶点”:
getline(f,line);
标记器标记(第行,sep);//标记第二行“Location1,Location2…”
for(tokenizer::iterator tok_iter=tokens.begin();
tok_iter!=tokens.end();++tok_iter){
Vmap[*tok_iter]=添加_顶点(*tok_iter,g);//对于每个标记,将值添加为图g中的顶点
}
getline(f,line);//跳过下一行“边”:
而(!f.eof()){
getline(f,line);
line=line.substr(1,line.size()-2);//通过创建不带第一个和最后一个字符的子字符串来删除括号
标记器标记(行,sep);//标记字符串
for(tokenizer::iterator tok_iter=tokens.begin();
tok_iter!=tokens.end();++tok_iter)
{
if(距离(tokens.begin(),tok_iter)=0)//将第一个标记“位置1”设置为u
{
v1=*tok_iter;
}
if(距离(tokens.begin(),tok_iter)=1)//将第二个标记“位置2”设置为v
{
v2=*tok_iter;
}
if(distance(tokens.begin(),tok_iter)=2)//将第三个标记“IntegerWeightValue”设置为权重
{
重量=stoi(*tok_iter);
}
}
add_边(Vmap[v1],Vmap[v2],weight,g);//将从位置1到位置2的加权边添加到图g中
}
cout>v1;
cout>v2;
u=Vmap[v1];
v=Vmap[v2];
//为Dijkstra创造东西
std::vector Preferences(num_顶点(g));//用于存储父对象
std::向量距离(num_顶点(g));//用于存储距离
IndexMap IndexMap=boost::get(boost::顶点索引,g);
前置映射前置映射(&前置[0],indexMap);
距离映射距离映射(&距离[0],索引映射);
//计算从v0到所有顶点的最短路径,并将输出存储在前导和距离中
//boost::dijkstra_最短路径(g,v0,boost::前置映射(前置映射)。距离映射(distanceMap));
//这与上面的行完全相同-这是“命名参数”的概念-您可以传递
//按任意顺序绘制地图和距离地图。
boost::dijkstra_最短路径(g,u,boost::距离映射(distanceMap)。前置映射(predecessorMap));

std::cout我无法用示例代码解析您的输入:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 1) > this->size() (which is 0)
#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;
}
我怀疑首先应该归咎于读取图形的代码,因为当我用我理解的东西替换它时:

//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
    }
}

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 1) > this->size() (which is 0)
#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
//#包括
//#包括
//#包括
//#包括
//#包括
输入重量;
typedef boost::属性权重属性;
typedef boost::property name属性;
typedef boost::邻接列表图;
typedef boost::graph_traits::vertex_描述符顶点;
typedef boost::property_map::type IndexMap;
typedef boost::property_map::type NameMap;
typedef boost::迭代器属性映射前置映射;
typedef boost::迭代器_属性_映射距离映射;
typedef std::map VertexMap;
#包括
#包括
BOOST_FUSION_DEFINE_STRUCT((解析),edgedef,(std::string,s)(std::string,t)(Weight,Weight))
int main(){
图g;
顶点映射Vmap;
{
//提示用户输入文件名
std::string filename=“”;
std::cout>filename;
//打开文件并将顶点和边添加到图形g
使用名称空间boost::spirit::qi;
std::fstream f(文件名);
f>>标准::noskipws;
std::矢量名称;
std::向量defs;
如果(f>>短语匹配(
“顶点:”>>下线>>+alnum%,“>>下线>>
“边缘:”>>eol>>
(“(“>>+alnum>>”、“>>+alnum>>”、“>>int_>>”))%eol,
空白、名称、定义)
{
用于(自动和控制:名称)
Vmap[c]=add_vertex(c,g);//对于每个标记,将值作为顶点添加到图g中
用于(自动和定义:定义)
{

没有自我包含的样本。没有样本输入。我以前的回答对你有帮助吗?我要去吗