1

次のコードは、boost ファミリー ツリーの例から抜粋したものです。

サブグラフを削除する簡単な方法を探しています

enum family { Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N };
int main()
{
  using namespace boost;
  const char *name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda",
    "Margaret", "Benjamin"
  };

  adjacency_list <> g(N);
  add_edge(Jeanie, Debbie, g);
  add_edge(Jeanie, Rick, g);
  add_edge(Jeanie, John, g);
  add_edge(Debbie, Amanda, g);
  add_edge(Rick, Margaret, g);
  add_edge(John, Benjamin, g);

  // some code

  // Rick and his family left - I want to remove them from the chart

  return 0;
}
4

1 に答える 1

1

この例では実行できません。Enum ファミリは、グラフの頂点コンテナーのインデックスです。したがって、リックを削除すると、ジョンはリックになります。

ただし、グラフの定義が列挙型の値を使用するように変更された場合、解決策は次のようになります。

enum family { Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N };
const char *name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda",
                       "Margaret", "Benjamin"
                     };
typedef boost::adjacency_list <boost::vecS
                             , boost::vecS
                             , boost::bidirectionalS
                             , family> Graph;

struct VisitorBFS : public boost::default_bfs_visitor {
    VisitorBFS(
        std::vector<boost::graph_traits<Graph>::vertex_descriptor>& container
    )
    : container(container) {}

    template <class Vertex, class Graph>
    void discover_vertex(const Vertex& v, const Graph& g) const
    {
        container.push_back(v);
    }

    std::vector<boost::graph_traits<Graph>::vertex_descriptor>& container;
};

void printFamily(const Graph& g)
{
    using namespace boost;
    graph_traits <Graph>::vertex_iterator i, end;
    graph_traits <Graph>::adjacency_iterator ai, a_end;

    for (boost::tie(i, end) = vertices(g); i != end; ++i) {
        std::cout << name[g[*i]];
        boost::tie(ai, a_end) = adjacent_vertices(*i, g);
        if (ai == a_end)
            std::cout << " has no children";
        else
            std::cout << " is the parent of ";
        for (; ai != a_end; ++ai) {
            std::cout << name[g[*ai]];
            if (boost::next(ai) != a_end)
                std::cout << ", ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    using namespace boost;

    Graph g;
    add_vertex(Jeanie, g);
    add_vertex(Debbie, g);
    add_vertex(Rick, g);
    add_vertex(John, g);
    add_vertex(Amanda, g);
    add_vertex(Margaret, g);
    add_vertex(Benjamin, g);

    add_edge(Jeanie, Debbie, g);
    add_edge(Jeanie, Rick, g);
    add_edge(Jeanie, John, g);
    add_edge(Debbie, Amanda, g);
    add_edge(Rick, Margaret, g);
    add_edge(John, Benjamin, g);

    printFamily(g);

    // Rick and his family left - I want to remove them from the chart

    // First, find a subgraph from vertex Rick. Algorithm breadth_first_search
    // also goes through the start vertex, so Rick is included in result.
    std::vector<graph_traits<Graph>::vertex_descriptor> vertexes;
    breadth_first_search(g, Rick, visitor(VisitorBFS(vertexes)));

    // Then remove incoming edges because they are not removed automatically
    // along with vertexes, then remove vertexes. 
    for (std::vector<graph_traits<Graph>::vertex_descriptor>::iterator it = vertexes.begin(); it != vertexes.end();  ++it) {
        clear_in_edges(*it, g);
        remove_vertex(*it, g);
    }

    printFamily(g); 

    return 0;
}
于 2016-06-24T15:01:28.927 に答える