Как правильно использовать связанные свойства в boost? - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь изменить конкретную вершину в моем неориентированном графе. По сути, я хочу иметь возможность начать с индекса 1 из 18 и запустить алгоритм, чтобы изменить строку каждого узла из этой вершины. Я читаю на графике из точечного файла. Я смотрел на Bundled Properties на сайте Boost , и это, кажется, прямо вперед. Однако, когда я пытаюсь реализовать это, я получаю Attempt to put a value into a const property map: Aborted (core dumped) ошибку. Поэтому я нахожу это решение , и оно выглядит точно так же, как и мое.

Вот минимальный пример того, что выдает ошибку:

Файл, который я читаю из test.dot:

graph G {
0 [isLeaf=1];
1 [isLeaf=0];
2 [isLeaf=1];
3 [isLeaf=1];
4 [isLeaf=0];
5 [isLeaf=1];
6 [isLeaf=0];
7 [isLeaf=1];
8 [isLeaf=0];
9 [isLeaf=1];
1--3  [time=3.41843];
1--4  [time=1.01826];
4--5  [time=4.2496];
2--6  [time=5.59155];
1--6  [time=9.48199];
6--7  [time=7.72868];
0--8  [time=7.38977];
4--8  [time=6.55225];
8--9  [time=0.0406912];
}

Код, который я запускаю:

#include <iostream>
#include <string>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/graph_utility.hpp>

struct Vertex
{
    bool isLeaf;
    std::string taxon;
};


typedef boost::property<boost::edge_weight_t, double> Edge;
typedef boost::adjacency_list<boost::vecS,boost::vecS, boost::undirectedS, Vertex, Edge> Graph;

int main()
{
    Graph g;

    boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g);  

    boost::dynamic_properties dp;
    dp.property("node_id", get(boost::vertex_index, g));
    dp.property("isLeaf", get(&Vertex::isLeaf, g));
    dp.property("time", weight);

    std::string blah = "Hello";

    std::ifstream dot("test.dot");

    boost::read_graphviz(dot,g,dp);

    g[1].taxon = blah;  
}

В чем причина этой ошибки?

1 Ответ

0 голосов
/ 11 мая 2018

Использование vecS для VertexContainerSelector означает, что у вас есть неявные дескрипторы индекса вершины.Они неявно являются дескриптором вершин интегрального индекса¹, который является интегральным индексом в контейнере вершин.

Таким образом, стандартное свойство vertex_index доступно только для чтения

Мысленный эксперимент: что бы писать в нем означало ?

Если вы изменили свойство вершины vertex_index, должно ли оно физически перемещаться в памяти?Что если он перезаписывает существующую вершину?Как насчет старого местоположения?Контейнер должен быть уплотнен?Но это означает, что присвоение индекса вершины одной вершине потенциально меняет все остальные индексы вершин и т. Д.)

Вы можете обойти это различными способами.Казалось бы, проще всего добавить в комплект Vertex поле, содержащее свойство ID узла, считанное из ввода:

#include <iostream>
#include <string>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/graph_utility.hpp>

struct Vertex {
    int id;
    bool isLeaf;
    std::string taxon;
};


typedef boost::property<boost::edge_weight_t, double> Edge;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge> Graph;

int main()
{
    Graph g;
    boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g);  

    boost::dynamic_properties dp;
    dp.property("node_id", get(&Vertex::id, g));
    dp.property("isLeaf", get(&Vertex::isLeaf, g));
    dp.property("time", weight);

    std::string blah = "Hello";

    std::ifstream dot("test.dot");

    boost::read_graphviz(dot,g,dp);

    g[1].taxon = blah;  
}
...