Перечисление всех путей от корня к листу с учетом dfs-порядка в направленном ациклическом графе - PullRequest
0 голосов
/ 08 декабря 2018

Учитывая следующий график:

enter image description here

использование boost дает следующее перечисление dfs графика:

order of discovery:  0  1  2  3  4  5  6 
order of finish:  2  3  1  0  6  5  4 

Код, который производит это:

бгл.ч

#pragma once
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/range/irange.hpp>
#include <boost/pending/indirect_cmp.hpp>

using namespace boost;

typedef adjacency_list_traits<vecS, vecS, directedS> Traits;

typedef adjacency_list<
    vecS, vecS, directedS,

    property<
        vertex_name_t, std::string,
        property<vertex_index_t, int,
        property<vertex_color_t, boost::default_color_type,
        property<vertex_distance_t, double,
        property<vertex_predecessor_t, Traits::edge_descriptor> 
    > > > >,

    property<
        edge_index_t, int,
        property<edge_capacity_t, double,
        property<edge_weight_t, double,
        property<edge_residual_capacity_t, double,
        property<edge_reverse_t, Traits::edge_descriptor>
    > > > > >
    Graph;

typedef graph_traits < Graph >::vertices_size_type size_type;

template < typename TimeMap > class dfs_time_visitor:public default_dfs_visitor {
  typedef typename property_traits < TimeMap >::value_type T;
public:
  dfs_time_visitor(TimeMap dmap, TimeMap fmap, T & t)
:  m_dtimemap(dmap), m_ftimemap(fmap), m_time(t) {
  }
  template < typename Vertex, typename Graph >
    void discover_vertex(Vertex u, const Graph & g) const
  {
    put(m_dtimemap, u, m_time++);
  }
  template < typename Vertex, typename Graph >
    void finish_vertex(Vertex u, const Graph & g) const
  {
    put(m_ftimemap, u, m_time++);
  }
  TimeMap m_dtimemap;
  TimeMap m_ftimemap;
  T & m_time;
};

typedef
    iterator_property_map<std::vector<size_type>::iterator,
                          property_map<Graph, vertex_index_t>::const_type>
    time_pm_type;

class Dfsgraph{
public:
    void addvertex();
    void addedge(int f, int t);
    void rundfs();
private:
    Graph g;
    std::vector < size_type > dtime;
    std::vector < size_type > ftime;
};

бгл.cpp

#include "bgl.h"
#include <stdio.h>//for printf

void Dfsgraph::addvertex(){
    add_vertex(g);
    dtime.push_back(0);
    ftime.push_back(0);
}

void Dfsgraph::addedge(int f, int to){
    add_edge(f, to, g);
}

void Dfsgraph::rundfs(){
  time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
  time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g));
  size_type t = 0;
  dfs_time_visitor < time_pm_type >vis(dtime_pm, ftime_pm, t);

  depth_first_search(g, visitor(vis));

  // use std::sort to order the vertices by their discover time
  std::vector < size_type > discover_order(num_vertices(g));
  integer_range < size_type > r(0, num_vertices(g));
  std::copy(r.begin(), r.end(), discover_order.begin());
  std::sort(discover_order.begin(), discover_order.end(),
            indirect_cmp < time_pm_type, std::less < size_type > >(dtime_pm));
  printf("order of discovery: ");
  int i;
  for (i = 0; i < num_vertices(g); ++i)
    printf(" %d ", discover_order[i]);

  std::vector < size_type > finish_order(num_vertices(g));
  std::copy(r.begin(), r.end(), finish_order.begin());
  std::sort(finish_order.begin(), finish_order.end(),indirect_cmp < time_pm_type, std::less < size_type > >(ftime_pm));
  printf("\norder of finish: ");
  for (i = 0; i < num_vertices(g); ++i)
    printf(" %d ", finish_order[i]);
  printf("\n");

}

int main(){
    Dfsgraph g;
    for(int nd = 0; nd < 7; nd++)
        g.addvertex();
    g.addedge(0,1); 
    g.addedge(1,2);
    g.addedge(1,3);
    g.addedge(4,5);
    g.addedge(5,3);
    g.addedge(5,6);

    g.rundfs();

    return 0;

}

Я хотел бы перечислить все полные пути от корневых узлов (тех, у которых нет входящей дуги) до соответствующих конечных узлов (тех, у которых нет исходящей дуги).То есть я бы хотел перечислить:

0->1->2
0->1->3
4->5->3
4->5->6

Q1.Возможно ли это с помощью готовых библиотечных функций, предлагаемых boost?

Q2.Если нет, каковы эффективные способы сделать это с нуля?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...