Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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_Dijkstra_Boost Graph_Boost Property Map - Fatal编程技术网

C++ 每边上有权重表的Dijkstra图

C++ 每边上有权重表的Dijkstra图,c++,boost,dijkstra,boost-graph,boost-property-map,C++,Boost,Dijkstra,Boost Graph,Boost Property Map,我有一个boost图,每个边都有多重权重(想象一下一天中每小时有一组权重)。这些权重值中的每一个都存储在propretyEdge类中: class propretyEdge { std::map<std::string,double> weights; // Date indexed } 这将使用 weights[date] 图的每条边的值 我一遍又一遍地阅读文档,但我无法清楚地了解我必须做什么。我当然需要写这样的东西,但我不知道该怎么开始: boost::dijkst

我有一个boost图,每个边都有多重权重(想象一下一天中每小时有一组权重)。这些权重值中的每一个都存储在propretyEdge类中:

class propretyEdge {
    std::map<std::string,double> weights; // Date indexed 
}
这将使用

weights[date]
图的每条边的值

我一遍又一遍地阅读文档,但我无法清楚地了解我必须做什么。我当然需要写这样的东西,但我不知道该怎么开始:

boost::dijkstra_shortest_paths (
    (*graph_m), 
    vertex_origin_num_l,
    // weight_map (get (edge_weight, (*graph_m)))
    // predecessor_map(boost::make_iterator_property_map(predecessors.begin(), get(boost::vertex_index, (*graph_m)))).
    // distance_map(boost::make_iterator_property_map(distances.begin (), get(vertex_index,(*graph_m) )))
    predecessor_map(predecessorMap).
    distance_map(distanceMap)
);
谢谢你的帮助

编辑

多亏了它的精彩,我才能够在MacOS和Ubuntu上做我想做的事情

但当我们试图在VisualStudio2012上编译这段代码时,VS似乎不太擅长理解boost的指针函数。所以我们修改了Sehe的部分:

auto dated_weight_f = [&](Graph::edge_descriptor ed) {
    return g[ed].weights.at(date);
};

auto dated_weight_map = make_function_property_map<Graph::edge_descriptor, double>(dated_weight_f);
auto-dated_-weight_-f=[&](图形::边描述符ed){
返回g[ed]。重量。在(日期);
};
自动日期权重映射=生成函数属性映射(日期权重f);
作者:

class日期为\u重量\u f{
公众:
日期权重(图*图,标准::字符串日期){
图m=图p;
日期m=日期p;
}
typedef双结果_类型;
结果类型运算符()(边)常量{
return(*graph_m)[edge_p].weights.at(date_m);
}
私人:
图*图m;
std::字符串日期;
};
const auto dated_weight_map=make_函数_属性_map(dated_weight_f(graph_m,date_l));

它的优点是不使用指针函数。

因为这个问题显然不是很清楚,我会解释的

您真正需要的是一个自定义的
weight\u map
参数,它是“有状态的”,可以为给定的日期选择特定的值

您可以根据自己的意愿将其复杂化,因此您甚至可以在给定未知日期的情况下对权重进行插值/外推,但为了演示的目的,让我们保持简单

让我们(大致)如上所述定义图形类型:

struct propretyEdge {
    std::map<std::string, double> weights; // Date indexed 
};

using Graph = adjacency_list<vecS, vecS, directedS, no_property, propretyEdge>;
现在如何实现Dijkstra(…)?从文档示例中收集,您可以执行以下操作

void Dijkstra(std::string const& date, Graph const& g, int vertex_origin_num_l = 0) {

    // magic postponed ...

    std::vector<Graph::vertex_descriptor> p(num_vertices(g));
    std::vector<double>                   d(num_vertices(g));
    std::vector<default_color_type>       color_map(num_vertices(g));

    boost::typed_identity_property_map<Graph::vertex_descriptor> vid; // T* property maps were deprecated

    dijkstra_shortest_paths(g, vertex_origin_num_l,
            weight_map(dated_weight_map).
            predecessor_map(make_iterator_property_map(p.data(),   vid)).
            distance_map(make_iterator_property_map(d.data(),      vid)).
            color_map(make_iterator_property_map(color_map.data(), vid))
        );
瞧,完成了 我希望到目前为止,问题中的对应关系以及相关问题的答案都是清楚的。剩下要做的就是在一张漂亮的图片中发布完整的现场样本和结果:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间boost;
结构专有页{
std::映射权重;//日期索引
};
使用图形=邻接列表;
void Dijkstra(std::string const&date,Graph const&g,int vertex\u origin\u num\u l=0){
自动标注日期的权重f=[&](图形::边描述符ed){
返回g[ed]。重量。在(日期);
};
自动日期权重映射=生成函数属性映射(日期权重f);
向量p(顶点数(g));
向量d(顶点数(g));
向量颜色映射(顶点数(g));
boost::typed_identity_property_map vid;//T*属性映射已弃用
dijkstra_最短路径(g,顶点,原点,
重量图(注明日期的重量图)。
前置映射(生成迭代器属性映射(p.data(),vid))。
距离映射(生成迭代器属性映射(d.data(),vid))。
颜色映射(生成迭代器属性映射(color\u map.data(),vid))
);

std::cout@Sehe这根本不是重复的。@Erowlin我想如果你用了实际的论点,那会有点好。我的论点在链接的答案中。我想你知道这个问题的更好答案吗?我很高兴邀请你发布它。@Erowlin无论如何,为了更清楚地说明这个问题是如何关联的,我已经发布了我可以问一下,是什么让你如此自信地说这不是一个复制品?(如果我不得不猜测是因为缺少“dijkstra”这个词的话?)。很抱歉没有解释。在另一个问题中遗漏的是您发布的清晰解释。谢谢。我认为太多的问题被标记为“重复”,而没有太多解释。@Erowlin在这种情况下,我真的认为这是有道理的,因为问题是相同的(每个边都有多个权重)答案也是:)在我看来,如果人们不把事情说清楚,他们往往会对好的建议嗤之以鼻。(这对提问者和回答者都有伤害)。我现在不介意。我得到了一个很好的答案,我可以在将来重复使用:)我不知道该如何感谢你!事实上,另一个问题中的回答非常接近我想要的,但老实说,我错过了你在回答中非常清楚地解释的几个步骤。非常感谢!我实现了我想要的,你的代码w非常清楚。“塞伊有没有想过要写一本BGL书?”我想买一本。“我想我会做第一个:”(这不利于我的GROK图形理论。不过我还是做了一些GROK C++)。我是GROK C++的几个人之一。我已经编程了一年,几乎不懂它。TBH,我觉得很多人都会做GRK C++。
struct propretyEdge {
    std::map<std::string, double> weights; // Date indexed 
};

using Graph = adjacency_list<vecS, vecS, directedS, no_property, propretyEdge>;
int main() {
    Graph g;
    std::mt19937 prng { std::random_device{}() };
    generate_random_graph(g, 8, 12, prng);

    uniform_real<double> weight_dist(10,42);
    for (auto e : make_iterator_range(edges(g)))
        for (auto&& date : { "2014-01-01", "2014-02-01", "2014-03-01" })
            g[e].weights[date] = weight_dist(prng);
    for (std::string const& date : { "2014-01-01", "2014-02-01", "2014-03-01" }) {
        Dijkstra(date, g, 0);
    }
}
void Dijkstra(std::string const& date, Graph const& g, int vertex_origin_num_l = 0) {

    // magic postponed ...

    std::vector<Graph::vertex_descriptor> p(num_vertices(g));
    std::vector<double>                   d(num_vertices(g));
    std::vector<default_color_type>       color_map(num_vertices(g));

    boost::typed_identity_property_map<Graph::vertex_descriptor> vid; // T* property maps were deprecated

    dijkstra_shortest_paths(g, vertex_origin_num_l,
            weight_map(dated_weight_map).
            predecessor_map(make_iterator_property_map(p.data(),   vid)).
            distance_map(make_iterator_property_map(d.data(),      vid)).
            color_map(make_iterator_property_map(color_map.data(), vid))
        );
auto dated_weight_f = [&](Graph::edge_descriptor ed) {
    return g[ed].weights.at(date);
};

auto dated_weight_map = make_function_property_map<Graph::edge_descriptor, double>(dated_weight_f);
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/property_map/property_map_iterator.hpp>

#include <random>
#include <boost/graph/random.hpp>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <fstream>

using namespace boost;

struct propretyEdge {
    std::map<std::string, double> weights; // Date indexed 
};

using Graph = adjacency_list<vecS, vecS, directedS, no_property, propretyEdge>;

void Dijkstra(std::string const& date, Graph const& g, int vertex_origin_num_l = 0) {

    auto dated_weight_f = [&](Graph::edge_descriptor ed) {
        return g[ed].weights.at(date);
    };

    auto dated_weight_map = make_function_property_map<Graph::edge_descriptor, double>(dated_weight_f);

    std::vector<Graph::vertex_descriptor> p(num_vertices(g));
    std::vector<double>                   d(num_vertices(g));
    std::vector<default_color_type>       color_map(num_vertices(g));

    boost::typed_identity_property_map<Graph::vertex_descriptor> vid; // T* property maps were deprecated

    dijkstra_shortest_paths(g, vertex_origin_num_l,
            weight_map(dated_weight_map).
            predecessor_map(make_iterator_property_map(p.data(),   vid)).
            distance_map(make_iterator_property_map(d.data(),      vid)).
            color_map(make_iterator_property_map(color_map.data(), vid))
        );

    std::cout << "distances and parents for '" + date + "':" << std::endl;
    for (auto vd : make_iterator_range(vertices(g)))
    {
        std::cout << "distance(" << vd << ") = " << d[vd] << ", ";
        std::cout << "parent(" << vd << ") = " << p[vd] << std::endl;
    }
    std::cout << std::endl;

    std::ofstream dot_file("dijkstra-eg-" + date + ".dot");

    dot_file << "digraph D {\n"
        "  rankdir=LR\n"
        "  size=\"6,4\"\n"
        "  ratio=\"fill\"\n"
        "  graph[label=\"shortest path on " + date + "\"];\n"
        "  edge[style=\"bold\"]\n" 
        "  node[shape=\"circle\"]\n";

    for (auto ed : make_iterator_range(edges(g))) {
        auto u = source(ed, g),
            v = target(ed, g);

        dot_file 
            << u << " -> " << v << "[label=\"" << get(dated_weight_map, ed) << "\""
            << (p[v] == u?", color=\"black\"" : ", color=\"grey\"")
            << "]";
    }
    dot_file << "}";
}

int main() {
    Graph g;
    std::mt19937 prng { std::random_device{}() };
    generate_random_graph(g, 8, 12, prng);

    uniform_real<double> weight_dist(10,42);
    for (auto e : make_iterator_range(edges(g)))
        for (auto&& date : { "2014-01-01", "2014-02-01", "2014-03-01" })
            g[e].weights[date] = weight_dist(prng);

    for (std::string const& date : { "2014-01-01", "2014-02-01", "2014-03-01" }) {
        Dijkstra(date, g, 0);
    }

}