1

I have two vectors of objects that I need to make a tree structure from them. Let's assume we have vector <obj> parents and vector <obj> leaves. Therefore, each element of vector <obj> parents has several leaves that sits at the end of the tree. What I am doing is defining Vertex properties and Edges properties as below, and then define a bidirectional graph:

struct VertexData
{
    std::string obj_name; // concatenation of labels
    std::string obj_class_num;
    int num;
    vector <int> segments_list;
    bool is_leaf=false;
};

struct EdgeData
{
    std::string edge_name;
    double confidence;
};

typedef boost::adjacency_list<boost::vecS, boost::vecS,
        boost::bidirectionalS,
        VertexData,
        boost::property<boost::edge_weight_t, double, EdgeData> > Graph;

Graph graph;
  1. First approach: looping through the vector <obj> leaves, for each member, I find the parent and make an edge. Then assign properties to the edge and vertices. But then for next leaf, I should check if already it has a parent in the tree or I should add a new vertex for its parent.

  2. Second approach: another thing that I tried, was looping through the vector <obj> parents, and for each element try to make its leaves. But I am not sure what is the correct way to do this. Here is a link: adding custom vertices to a boost graph that I try to do the same but with iterations.

Code added for 1st approach:

vector <class1> parents; // this has some objects of type class1
vector <class2> leaves; // this has some objects of type class2

/// declare the graph
typedef boost::adjacency_list<boost::vecS, boost::vecS,
        boost::bidirectionalS,
        VertexData,
        boost::property<boost::edge_weight_t, double, EdgeData> > Graph;

/// instantiate the graph
Graph graph;

typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef boost::graph_traits<Graph>::edge_descriptor edge_t;
vector<vertex_t> obj_vertices;
vector<string>   parents_labels_v;
bool parent_exist=false;


/// loop through leaves and make edges with associated parent
for (auto leaf: leaves) {

    int leaf_nr = leaf.Number;

    vertex_t v = boost::add_vertex(graph); // this is the leaf vertex
    graph[v].num     = leaf_nr;         // leaf number
    graph[v].is_leaf = true;
    /// access the parent label by leaf number
    string label1 = parents[leaf_nr].label;

    /// check if the parent already exist, using its label
    if(std::find(parents_labels_v.begin(), parents_labels_v.end(), label1)
       != parents_labels_v.end()){
        parent_exist = true;
    }else{
        parents_labels_v.push_back(label1);
    }

    if(parent_exist) {
        // find already_exist parent vertex to make the edge
        vertex_t u = ???  here i have problem
        // Create an edge connecting those two vertices
        edge_t e; bool b;
        boost::tie(e,b) = boost::add_edge(u,v,graph);
    } else{
        // if parent-vertex there is not, add it to the graph
        vertex_t u = boost::add_vertex(graph); // this is the parent vertex
        graph[u].obj_name = label1;
        graph[u].segments_list.push_back(leaf_nr);
        obj_vertices.push_back(u);

        // Create an edge connecting those two vertices
        edge_t e; bool b;
        boost::tie(e,b) = boost::add_edge(u,v,graph);
    }

}
Bruce
  • 415
  • 2
  • 19
  • Can you replace the prose description with CODE. The description confuses "members"/"elements" and "children" in multiple ways. Also I don't think "I have 3 vectors" is even true, after trying to understand your description. – sehe Aug 15 '17 at 11:42
  • I edited the question, and made it simpler to be clear. However, the code is just the test, I am not sure if this is an elegant way to do this. I think the 2nd approach makes more sense, but I don't know how to add leave vertices iteratively. – Bruce Aug 15 '17 at 13:39

0 Answers0