# HG changeset patch # User deba # Date 1141208730 0 # Node ID d7442141d9efccfae734e03e00accf158735f4a1 # Parent 15fb7a4ea6be613fd42b19c643d1329692666f52 The graph adadptors can be alteration observed. In most cases it uses the adapted graph alteration notifiers. Only special case is now the UndirGraphAdaptor, where we have to proxy the signals from the graph. The SubBidirGraphAdaptor is removed, because it doest not gives more feature than the EdgeSubGraphAdaptor>. The ResGraphAdaptor is based on this composition. diff -r 15fb7a4ea6be -r d7442141d9ef lemon/bits/edge_set_extender.h --- a/lemon/bits/edge_set_extender.h Wed Mar 01 10:17:25 2006 +0000 +++ b/lemon/bits/edge_set_extender.h Wed Mar 01 10:25:30 2006 +0000 @@ -68,6 +68,8 @@ public: + using Parent::getNotifier; + /// \brief Gives back the edge alteration notifier. /// /// Gives back the edge alteration notifier. @@ -322,6 +324,8 @@ mutable UEdgeNotifier uedge_notifier; public: + + using Parent::getNotifier; EdgeNotifier& getNotifier(Edge) const { return edge_notifier; diff -r 15fb7a4ea6be -r d7442141d9ef lemon/bits/graph_extender.h --- a/lemon/bits/graph_extender.h Wed Mar 01 10:17:25 2006 +0000 +++ b/lemon/bits/graph_extender.h Wed Mar 01 10:25:30 2006 +0000 @@ -1568,7 +1568,7 @@ protected: template - class NodeMapBase : public NodeNotifier::ObserverBase { + class NodeMapBase { public: typedef BpUGraphExtender Graph; @@ -1590,21 +1590,10 @@ typedef True ReferenceMapTag; NodeMapBase(const Graph& _g) - : graph(&_g), bNodeMap(_g), aNodeMap(_g) { - NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); - } + : aNodeMap(_g), bNodeMap(_g) {} NodeMapBase(const Graph& _g, const _Value& _v) - : graph(&_g), bNodeMap(_g, _v), - aNodeMap(_g, _v) { - NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); - } + : aNodeMap(_g, _v), bNodeMap(_g, _v) {} - virtual ~NodeMapBase() { - if (NodeNotifier::ObserverBase::attached()) { - NodeNotifier::ObserverBase::detach(); - } - } - ConstReference operator[](const Key& node) const { if (Parent::aNode(node)) { return aNodeMap[node]; @@ -1629,21 +1618,13 @@ } } - protected: - - virtual void add(const Node&) {} - virtual void add(const std::vector&) {} - virtual void erase(const Node&) {} - virtual void erase(const std::vector&) {} - virtual void clear() {} - virtual void build() {} + const Graph* getGraph() const { + return aNodeMap.getGraph(); + } - const Graph* getGraph() const { return graph; } - private: - const Graph* graph; + ANodeMap<_Value> aNodeMap; BNodeMap<_Value> bNodeMap; - ANodeMap<_Value> aNodeMap; }; public: diff -r 15fb7a4ea6be -r d7442141d9ef lemon/graph_adaptor.h --- a/lemon/graph_adaptor.h Wed Mar 01 10:17:25 2006 +0000 +++ b/lemon/graph_adaptor.h Wed Mar 01 10:25:30 2006 +0000 @@ -113,25 +113,45 @@ int id(const Node& v) const { return graph->id(v); } int id(const Edge& e) const { return graph->id(e); } + + int maxNodeId() const { + return graph->maxNodeId(); + } + + int maxEdgeId() const { + return graph->maxEdgeId(); + } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& getNotifier(Node) const { + return graph->getNotifier(Node()); + } + + typedef typename ItemSetTraits::ItemNotifier EdgeNotifier; + + EdgeNotifier& getNotifier(Edge) const { + return graph->getNotifier(Edge()); + } template class NodeMap : public _Graph::template NodeMap<_Value> { public: typedef typename _Graph::template NodeMap<_Value> Parent; - explicit NodeMap(const GraphAdaptorBase<_Graph>& gw) - : Parent(*gw.graph) { } - NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value) - : Parent(*gw.graph, value) { } + explicit NodeMap(const GraphAdaptorBase<_Graph>& ga) + : Parent(*ga.graph) { } + NodeMap(const GraphAdaptorBase<_Graph>& ga, const _Value& value) + : Parent(*ga.graph, value) { } }; template class EdgeMap : public _Graph::template EdgeMap<_Value> { public: typedef typename _Graph::template EdgeMap<_Value> Parent; - explicit EdgeMap(const GraphAdaptorBase<_Graph>& gw) - : Parent(*gw.graph) { } - EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value) - : Parent(*gw.graph, value) { } + explicit EdgeMap(const GraphAdaptorBase<_Graph>& ga) + : Parent(*ga.graph) { } + EdgeMap(const GraphAdaptorBase<_Graph>& ga, const _Value& value) + : Parent(*ga.graph, value) { } }; }; @@ -149,6 +169,17 @@ explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); } }; + /// \brief Just gives back a graph adaptor + /// + /// Just gives back a graph adaptor which + /// should be provide original graph + template + GraphAdaptor + graphAdaptor(const Graph& graph) { + return GraphAdaptor(graph); + } + + template class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> { public: @@ -168,6 +199,13 @@ Node source(const Edge& e) const { return Parent::target(e); } Node target(const Edge& e) const { return Parent::source(e); } + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& source, const Node& target, + const Edge& prev = INVALID) { + return Parent::findEdge(target, source, prev); + } + }; @@ -184,7 +222,7 @@ ///\endcode /// then ///\code - /// RevGraphAdaptor gw(g); + /// RevGraphAdaptor ga(g); ///\endcode ///implements the graph obtained from \c g by /// reversing the orientation of its edges. @@ -202,7 +240,15 @@ explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); } }; - + /// \brief Just gives back a reverse graph adaptor + /// + /// Just gives back a reverse graph adaptor + template + RevGraphAdaptor + revGraphAdaptor(const Graph& graph) { + return RevGraphAdaptor(graph); + } + template class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> { @@ -315,9 +361,21 @@ /// bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } - typedef False FindEdgeTag; typedef False NodeNumTag; typedef False EdgeNumTag; + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& source, const Node& target, + const Edge& prev = INVALID) { + if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) { + return INVALID; + } + Edge edge = Parent::findEdge(source, target, prev); + while (edge != INVALID && !(*edge_filter_map)[edge]) { + edge = Parent::findEdge(source, target, edge); + } + return edge; + } }; template @@ -422,9 +480,21 @@ /// bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } - typedef False FindEdgeTag; typedef False NodeNumTag; typedef False EdgeNumTag; + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& source, const Node& target, + const Edge& prev = INVALID) { + if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) { + return INVALID; + } + Edge edge = Parent::findEdge(source, target, prev); + while (edge != INVALID && !(*edge_filter_map)[edge]) { + edge = Parent::findEdge(source, target, edge); + } + return edge; + } }; /// \brief A graph adaptor for hiding nodes and edges from a graph. @@ -468,11 +538,11 @@ /// nm.set(u, false); /// Graph::EdgeMap em(g, true); /// em.set(e, false); - /// typedef SubGraphAdaptor, Graph::EdgeMap > SubGW; - /// SubGW gw(g, nm, em); - /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl; + /// typedef SubGraphAdaptor, Graph::EdgeMap > SubGA; + /// SubGA ga(g, nm, em); + /// for (SubGA::NodeIt n(ga); n!=INVALID; ++n) std::cout << g.id(n) << std::endl; /// std::cout << ":-)" << std::endl; - /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl; + /// for (SubGA::EdgeIt e(ga); e!=INVALID; ++e) std::cout << g.id(e) << std::endl; ///\endcode /// The output of the above code is the following. ///\code @@ -480,7 +550,7 @@ /// :-) /// 1 ///\endcode - /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to + /// Note that \c n is of type \c SubGA::NodeIt, but it can be converted to /// \c Graph::Node that is why \c g.id(n) can be applied. /// /// For other examples see also the documentation of NodeSubGraphAdaptor and @@ -508,6 +578,41 @@ } }; + /// \brief Just gives back a sub graph adaptor + /// + /// Just gives back a sub graph adaptor + template + SubGraphAdaptor + subGraphAdaptor(const Graph& graph, + NodeFilterMap& nfm, EdgeFilterMap& efm) { + return SubGraphAdaptor + (graph, nfm, efm); + } + + template + SubGraphAdaptor + subGraphAdaptor(const Graph& graph, + NodeFilterMap& nfm, EdgeFilterMap& efm) { + return SubGraphAdaptor + (graph, nfm, efm); + } + + template + SubGraphAdaptor + subGraphAdaptor(const Graph& graph, + NodeFilterMap& nfm, EdgeFilterMap& efm) { + return SubGraphAdaptor + (graph, nfm, efm); + } + + template + SubGraphAdaptor + subGraphAdaptor(const Graph& graph, + NodeFilterMap& nfm, EdgeFilterMap& efm) { + return SubGraphAdaptor(graph, nfm, efm); + } + ///\brief An adaptor for hiding nodes from a graph. @@ -533,6 +638,11 @@ ConstMap > Parent; protected: ConstMap const_true_map; + + NodeSubGraphAdaptor() : const_true_map(true) { + Parent::setEdgeFilterMap(const_true_map); + } + public: NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) : Parent(), const_true_map(true) { @@ -543,6 +653,21 @@ }; + /// \brief Just gives back a node sub graph adaptor + /// + /// Just gives back a node sub graph adaptor + template + NodeSubGraphAdaptor + nodeSubGraphAdaptor(const Graph& graph, NodeFilterMap& nfm) { + return NodeSubGraphAdaptor(graph, nfm); + } + + template + NodeSubGraphAdaptor + nodeSubGraphAdaptor(const Graph& graph, const NodeFilterMap& nfm) { + return NodeSubGraphAdaptor(graph, nfm); + } + ///\brief An adaptor for hiding edges from a graph. /// ///\warning Graph adaptors are in even more experimental state @@ -630,8 +755,8 @@ /// TightEdgeFilter; ///TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length); /// - ///typedef EdgeSubGraphAdaptor SubGW; - ///SubGW gw(g, tight_edge_filter); + ///typedef EdgeSubGraphAdaptor SubGA; + ///SubGA ga(g, tight_edge_filter); ///\endcode ///Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed ///with a max flow algorithm Preflow. @@ -639,8 +764,8 @@ ///ConstMap const_1_map(1); ///Graph::EdgeMap flow(g, 0); /// - ///Preflow, Graph::EdgeMap > - /// preflow(gw, s, t, const_1_map, flow); + ///Preflow, Graph::EdgeMap > + /// preflow(ga, s, t, const_1_map, flow); ///preflow.run(); ///\endcode ///Last, the output is: @@ -688,6 +813,11 @@ EdgeFilterMap, false> Parent; protected: ConstMap const_true_map; + + EdgeSubGraphAdaptor() : const_true_map(true) { + Parent::setNodeFilterMap(const_true_map); + } + public: EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) : Parent(), const_true_map(true) { @@ -697,70 +827,273 @@ } }; - template + /// \brief Just gives back an edge sub graph adaptor + /// + /// Just gives back an edge sub graph adaptor + template + EdgeSubGraphAdaptor + edgeSubGraphAdaptor(const Graph& graph, EdgeFilterMap& efm) { + return EdgeSubGraphAdaptor(graph, efm); + } + + template + EdgeSubGraphAdaptor + edgeSubGraphAdaptor(const Graph& graph, const EdgeFilterMap& efm) { + return EdgeSubGraphAdaptor(graph, efm); + } + + template class UndirGraphAdaptorBase : public UGraphBaseExtender > { public: typedef _Graph Graph; typedef UGraphBaseExtender > Parent; + protected: - UndirGraphAdaptorBase() : Parent() { } + + UndirGraphAdaptorBase() : Parent() {} + public: + typedef typename Parent::UEdge UEdge; typedef typename Parent::Edge Edge; + - template + template class EdgeMap { - protected: - const UndirGraphAdaptorBase<_Graph>* g; - template friend class EdgeMap; - typename _Graph::template EdgeMap forward_map, backward_map; + private: + + typedef typename _Graph::template EdgeMap<_Value> MapImpl; + public: - typedef T Value; + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + + typedef _Value Value; typedef Edge Key; - EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : g(&_g), - forward_map(*(g->graph)), backward_map(*(g->graph)) { } + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : + forward_map(*(_g.graph)), backward_map(*(_g.graph)) {} - EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, T a) : g(&_g), - forward_map(*(g->graph), a), backward_map(*(g->graph), a) { } + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, const Value& a) + : forward_map(*(_g.graph), a), backward_map(*(_g.graph), a) {} - void set(Edge e, T a) { - if (g->direction(e)) + void set(const Edge& e, const Value& a) { + if (Parent::direction(e)) { forward_map.set(e, a); - else - backward_map.set(e, a); + } else { + backward_map.set(e, a); + } } - T operator[](Edge e) const { - if (g->direction(e)) + typename MapTraits::ConstReturnValue operator[](Edge e) const { + if (Parent::direction(e)) { return forward_map[e]; - else + } else { return backward_map[e]; + } } + + typename MapTraits::ReturnValue operator[](Edge e) { + if (Parent::direction(e)) { + return forward_map[e]; + } else { + return backward_map[e]; + } + } + + protected: + + MapImpl forward_map, backward_map; + }; - template - class UEdgeMap { - template friend class UEdgeMap; - typename _Graph::template EdgeMap map; + template + class UEdgeMap : public _Graph::template EdgeMap<_Value> { public: - typedef T Value; - typedef UEdge Key; + + typedef typename _Graph::template EdgeMap<_Value> Parent; + + UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) + : Parent(*(g.graph)) {} + + UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, const _Value& a) + : Parent(*(g.graph), a) {} - UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) : - map(*(g.graph)) { } + }; + + }; - UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, T a) : - map(*(g.graph), a) { } + template + class UndirGraphAdaptorBase< + _Graph, typename enable_if< + typename _Graph::EdgeNotifier::Notifier>::type > + : public UGraphBaseExtender > { + public: + + typedef _Graph Graph; + typedef UGraphBaseExtender > Parent; + + protected: + + UndirGraphAdaptorBase() + : Parent(), edge_notifier(), edge_notifier_proxy(edge_notifier) {} + + void setGraph(_Graph& graph) { + Parent::setGraph(graph); + edge_notifier_proxy.setUEdgeNotifier(graph.getNotifier(UEdge())); + } + + public: + + ~UndirGraphAdaptorBase() { + getNotifier(Edge()).clear(); + } + + + typedef typename Parent::UEdge UEdge; + typedef typename Parent::Edge Edge; + + typedef typename Parent::EdgeNotifier UEdgeNotifier; + + using Parent::getNotifier; + + typedef AlterationNotifier EdgeNotifier; + EdgeNotifier& getNotifier(Edge) const { return edge_notifier; } + + protected: + + class NotifierProxy : public UEdgeNotifier::ObserverBase { + public: + + typedef typename UEdgeNotifier::ObserverBase Parent; + typedef UndirGraphAdaptorBase AdaptorBase; - void set(UEdge e, T a) { - map.set(e, a); + NotifierProxy(EdgeNotifier& _edge_notifier) + : Parent(), edge_notifier(_edge_notifier) { } - T operator[](UEdge e) const { - return map[e]; + virtual ~NotifierProxy() { + if (Parent::attached()) { + Parent::detach(); + } } + + void setUEdgeNotifier(UEdgeNotifier& _uedge_notifier) { + Parent::attach(_uedge_notifier); + } + + + protected: + + virtual void add(const UEdge& uedge) { + std::vector edges; + edges.push_back(AdaptorBase::Parent::direct(uedge, true)); + edges.push_back(AdaptorBase::Parent::direct(uedge, false)); + edge_notifier.add(edges); + } + virtual void add(const std::vector& uedges) { + std::vector edges; + for (int i = 0; i < (int)uedges.size(); ++i) { + edges.push_back(AdaptorBase::Parent::direct(uedges[i], true)); + edges.push_back(AdaptorBase::Parent::direct(uedges[i], false)); + } + edge_notifier.add(edges); + } + virtual void erase(const UEdge& uedge) { + std::vector edges; + edges.push_back(AdaptorBase::Parent::direct(uedge, true)); + edges.push_back(AdaptorBase::Parent::direct(uedge, false)); + edge_notifier.erase(edges); + } + virtual void erase(const std::vector& uedges) { + std::vector edges; + for (int i = 0; i < (int)uedges.size(); ++i) { + edges.push_back(AdaptorBase::Parent::direct(uedges[i], true)); + edges.push_back(AdaptorBase::Parent::direct(uedges[i], false)); + } + edge_notifier.erase(edges); + } + virtual void build() { + edge_notifier.build(); + } + virtual void clear() { + edge_notifier.clear(); + } + + EdgeNotifier& edge_notifier; + }; + + + mutable EdgeNotifier edge_notifier; + NotifierProxy edge_notifier_proxy; + + public: + + + template + class EdgeMap { + private: + + typedef typename _Graph::template EdgeMap<_Value> MapImpl; + + public: + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + + typedef _Value Value; + typedef Edge Key; + + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : + forward_map(*(_g.graph)), backward_map(*(_g.graph)) {} + + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, const Value& a) + : forward_map(*(_g.graph), a), backward_map(*(_g.graph), a) {} + + void set(const Edge& e, const Value& a) { + if (Parent::direction(e)) { + forward_map.set(e, a); + } else { + backward_map.set(e, a); + } + } + + typename MapTraits::ConstReturnValue + operator[](const Edge& e) const { + if (Parent::direction(e)) { + return forward_map[e]; + } else { + return backward_map[e]; + } + } + + typename MapTraits::ReturnValue + operator[](const Edge& e) { + if (Parent::direction(e)) { + return forward_map[e]; + } else { + return backward_map[e]; + } + } + + protected: + + MapImpl forward_map, backward_map; + + }; + + template + class UEdgeMap : public _Graph::template EdgeMap<_Value> { + public: + + typedef typename _Graph::template EdgeMap<_Value> Parent; + + UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) + : Parent(*(g.graph)) {} + + UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, const _Value& a) + : Parent(*(g.graph), a) {} + }; }; @@ -786,373 +1119,90 @@ UndirGraphAdaptor(_Graph& _graph) { setGraph(_graph); } - }; - - template - class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> { - public: - typedef _Graph Graph; - typedef GraphAdaptorBase<_Graph> Parent; - protected: - ForwardFilterMap* forward_filter; - BackwardFilterMap* backward_filter; - SubBidirGraphAdaptorBase() : Parent(), - forward_filter(0), backward_filter(0) { } + template + class CombinedEdgeMap { + public: + + typedef _ForwardMap ForwardMap; + typedef _BackwardMap BackwardMap; - void setForwardFilterMap(ForwardFilterMap& _forward_filter) { - forward_filter=&_forward_filter; - } - void setBackwardFilterMap(BackwardFilterMap& _backward_filter) { - backward_filter=&_backward_filter; - } + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; - public: -// SubGraphAdaptorBase(Graph& _graph, -// NodeFilterMap& _node_filter_map, -// EdgeFilterMap& _edge_filter_map) : -// Parent(&_graph), -// node_filter_map(&node_filter_map), -// edge_filter_map(&edge_filter_map) { } + typedef typename ForwardMap::Value Value; + typedef typename Parent::Edge Key; + + CombinedEdgeMap() : forward_map(0), backward_map(0) {} - typedef typename Parent::Node Node; - typedef typename _Graph::Edge GraphEdge; - template class EdgeMap; - // SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from - // _Graph::Edge. It contains an extra bool flag which is true - // if and only if the - // edge is the backward version of the original edge. - class Edge : public _Graph::Edge { - friend class SubBidirGraphAdaptorBase< - Graph, ForwardFilterMap, BackwardFilterMap>; - template friend class EdgeMap; - protected: - bool backward; //true, iff backward - public: - Edge() { } - // \todo =false is needed, or causes problems? - // If \c _backward is false, then we get an edge corresponding to the - // original one, otherwise its oppositely directed pair is obtained. - Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : - _Graph::Edge(e), backward(_backward) { } - Edge(Invalid i) : _Graph::Edge(i), backward(true) { } - bool operator==(const Edge& v) const { - return (this->backward==v.backward && - static_cast(*this)== - static_cast(v)); - } - bool operator!=(const Edge& v) const { - return (this->backward!=v.backward || - static_cast(*this)!= - static_cast(v)); - } - }; - - void first(Node& i) const { - Parent::first(i); - } - - void first(Edge& i) const { - Parent::first(i); - i.backward=false; - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::next(i); - if (*static_cast(&i)==INVALID) { - Parent::first(i); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::next(i); - } - } - - void firstIn(Edge& i, const Node& n) const { - Parent::firstIn(i, n); - i.backward=false; - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::nextIn(i); - if (*static_cast(&i)==INVALID) { - Parent::firstOut(i, n); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextOut(i); - } - } - - void firstOut(Edge& i, const Node& n) const { - Parent::firstOut(i, n); - i.backward=false; - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::nextOut(i); - if (*static_cast(&i)==INVALID) { - Parent::firstIn(i, n); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextIn(i); - } - } - - void next(Node& i) const { - Parent::next(i); - } - - void next(Edge& i) const { - if (!(i.backward)) { - Parent::next(i); - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::next(i); - if (*static_cast(&i)==INVALID) { - Parent::first(i); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::next(i); - } - } else { - Parent::next(i); - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::next(i); - } - } - - void nextIn(Edge& i) const { - if (!(i.backward)) { - Node n=Parent::target(i); - Parent::nextIn(i); - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::nextIn(i); - if (*static_cast(&i)==INVALID) { - Parent::firstOut(i, n); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextOut(i); - } - } else { - Parent::nextOut(i); - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextOut(i); - } - } - - void nextOut(Edge& i) const { - if (!(i.backward)) { - Node n=Parent::source(i); - Parent::nextOut(i); - while (*static_cast(&i)!=INVALID && - !(*forward_filter)[i]) Parent::nextOut(i); - if (*static_cast(&i)==INVALID) { - Parent::firstIn(i, n); - i.backward=true; - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextIn(i); - } - } else { - Parent::nextIn(i); - while (*static_cast(&i)!=INVALID && - !(*backward_filter)[i]) Parent::nextIn(i); - } - } - - Node source(Edge e) const { - return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); } - Node target(Edge e) const { - return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); } - - /// Gives back the opposite edge. - - ///\e - /// - Edge opposite(const Edge& e) const { - Edge f=e; - f.backward=!f.backward; - return f; - } - - ///\e - - /// \warning This is a linear time operation and works only if - /// \c Graph::EdgeIt is defined. - /// \todo hmm - int edgeNum() const { - int i=0; - Edge e; - for (first(e); e!=INVALID; next(e)) ++i; - return i; - } - - bool forward(const Edge& e) const { return !e.backward; } - bool backward(const Edge& e) const { return e.backward; } - - ///\e - - /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two - /// _Graph::EdgeMap one for the forward edges and - /// one for the backward edges. - template - class EdgeMap { - template friend class EdgeMap; - typename _Graph::template EdgeMap forward_map, backward_map; - public: - typedef T Value; - typedef Edge Key; - - EdgeMap(const SubBidirGraphAdaptorBase<_Graph, - ForwardFilterMap, BackwardFilterMap>& g) : - forward_map(*(g.graph)), backward_map(*(g.graph)) { } - - EdgeMap(const SubBidirGraphAdaptorBase<_Graph, - ForwardFilterMap, BackwardFilterMap>& g, T a) : - forward_map(*(g.graph), a), backward_map(*(g.graph), a) { } + CombinedEdgeMap(ForwardMap& _forward_map, BackwardMap& _backward_map) + : forward_map(&_forward_map), backward_map(&_backward_map) {} - void set(Edge e, T a) { - if (!e.backward) - forward_map.set(e, a); - else - backward_map.set(e, a); + void set(const Key& e, const Value& a) { + if (Parent::direction(e)) { + forward_map->set(e, a); + } else { + backward_map->set(e, a); + } } -// typename _Graph::template EdgeMap::ConstReference -// operator[](Edge e) const { -// if (!e.backward) -// return forward_map[e]; -// else -// return backward_map[e]; -// } - -// typename _Graph::template EdgeMap::Reference - T operator[](Edge e) const { - if (!e.backward) - return forward_map[e]; - else - return backward_map[e]; + typename MapTraits::ConstReturnValue + operator[](const Key& e) const { + if (Parent::direction(e)) { + return (*forward_map)[e]; + } else { + return (*backward_map)[e]; + } } - void update() { - forward_map.update(); - backward_map.update(); + typename MapTraits::ReturnValue + operator[](const Key& e) { + if (Parent::direction(e)) { + return (*forward_map)[e]; + } else { + return (*backward_map)[e]; + } } + + void setForwardMap(ForwardMap& _forward_map) { + forward_map = &_forward_map; + } + + void setBackwardMap(BackwardMap& _backward_map) { + backward_map = &_backward_map; + } + + protected: + + ForwardMap* forward_map; + BackwardMap* backward_map; + }; }; - - ///\brief An adaptor for composing a subgraph of a - /// bidirected graph made from a directed one. - ///\ingroup graph_adaptors + /// \brief Just gives back an undir graph adaptor /// - /// An adaptor for composing a subgraph of a - /// bidirected graph made from a directed one. - /// - ///\warning Graph adaptors are in even more experimental state - ///than the other - ///parts of the lib. Use them at you own risk. - /// - /// Let \f$ G=(V, A) \f$ be a directed graph and for each directed edge - ///\f$ e\in A \f$, let \f$ \bar e \f$ denote the edge obtained by - /// reversing its orientation. We are given moreover two bool valued - /// maps on the edge-set, - ///\f$ forward\_filter \f$, and \f$ backward\_filter \f$. - /// SubBidirGraphAdaptor implements the graph structure with node-set - ///\f$ V \f$ and edge-set - ///\f$ \{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\} \f$. - /// The purpose of writing + instead of union is because parallel - /// edges can arise. (Similarly, antiparallel edges also can arise). - /// In other words, a subgraph of the bidirected graph obtained, which - /// is given by orienting the edges of the original graph in both directions. - /// As the oppositely directed edges are logically different, - /// the maps are able to attach different values for them. - /// - /// An example for such a construction is \c RevGraphAdaptor where the - /// forward_filter is everywhere false and the backward_filter is - /// everywhere true. We note that for sake of efficiency, - /// \c RevGraphAdaptor is implemented in a different way. - /// But BidirGraphAdaptor is obtained from - /// SubBidirGraphAdaptor by considering everywhere true - /// valued maps both for forward_filter and backward_filter. - /// - /// The most important application of SubBidirGraphAdaptor - /// is ResGraphAdaptor, which stands for the residual graph in directed - /// flow and circulation problems. - /// As adaptors usually, the SubBidirGraphAdaptor implements the - /// above mentioned graph structure without its physical storage, - /// that is the whole stuff is stored in constant memory. - template - class SubBidirGraphAdaptor : - public GraphAdaptorExtender< - SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > { - public: - typedef _Graph Graph; - typedef GraphAdaptorExtender< - SubBidirGraphAdaptorBase< - _Graph, ForwardFilterMap, BackwardFilterMap> > Parent; - protected: - SubBidirGraphAdaptor() { } - public: - SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter, - BackwardFilterMap& _backward_filter) { - setGraph(_graph); - setForwardFilterMap(_forward_filter); - setBackwardFilterMap(_backward_filter); - } - }; - - - - ///\brief An adaptor for composing bidirected graph from a directed one. - ///\ingroup graph_adaptors - /// - ///\warning Graph adaptors are in even more experimental state - ///than the other - ///parts of the lib. Use them at you own risk. - /// - /// An adaptor for composing bidirected graph from a directed one. - /// A bidirected graph is composed over the directed one without physical - /// storage. As the oppositely directed edges are logically different ones - /// the maps are able to attach different values for them. + /// Just gives back an undir graph adaptor template - class BidirGraphAdaptor : - public SubBidirGraphAdaptor< - Graph, - ConstMap, - ConstMap > { - public: - typedef SubBidirGraphAdaptor< - Graph, - ConstMap, - ConstMap > Parent; - protected: - ConstMap cm; - - BidirGraphAdaptor() : Parent(), cm(true) { - Parent::setForwardFilterMap(cm); - Parent::setBackwardFilterMap(cm); - } - public: - BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) { - Parent::setGraph(_graph); - Parent::setForwardFilterMap(cm); - Parent::setBackwardFilterMap(cm); - } - - int edgeNum() const { - return 2*this->graph->edgeNum(); - } - }; - + UndirGraphAdaptor + undirGraphAdaptor(const Graph& graph) { + return UndirGraphAdaptor(graph); + } template class ResForwardFilter { - // const Graph* graph; const CapacityMap* capacity; const FlowMap* flow; public: - ResForwardFilter(/*const Graph& _graph, */ - const CapacityMap& _capacity, const FlowMap& _flow) : - /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { } - ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { } - void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; } - void setFlow(const FlowMap& _flow) { flow=&_flow; } + typedef typename Graph::Edge Key; + typedef bool Value; + + ResForwardFilter(const CapacityMap& _capacity, const FlowMap& _flow) + : capacity(&_capacity), flow(&_flow) { } + ResForwardFilter() : capacity(0), flow(0) { } + void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; } + void setFlow(const FlowMap& _flow) { flow = &_flow; } bool operator[](const typename Graph::Edge& e) const { return (Number((*flow)[e]) < Number((*capacity)[e])); } @@ -1164,12 +1214,14 @@ const CapacityMap* capacity; const FlowMap* flow; public: - ResBackwardFilter(/*const Graph& _graph,*/ - const CapacityMap& _capacity, const FlowMap& _flow) : - /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { } - ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { } - void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; } - void setFlow(const FlowMap& _flow) { flow=&_flow; } + typedef typename Graph::Edge Key; + typedef bool Value; + + ResBackwardFilter(const CapacityMap& _capacity, const FlowMap& _flow) + : capacity(&_capacity), flow(&_flow) { } + ResBackwardFilter() : capacity(0), flow(0) { } + void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; } + void setFlow(const FlowMap& _flow) { flow = &_flow; } bool operator[](const typename Graph::Edge& e) const { return (Number(0) < Number((*flow)[e])); } @@ -1207,80 +1259,118 @@ ///typedef ListGraph Graph; ///Graph::EdgeMap f(g); ///Graph::EdgeMap c(g); - ///ResGraphAdaptor, Graph::EdgeMap > gw(g); + ///ResGraphAdaptor, Graph::EdgeMap > ga(g); ///\endcode ///\author Marton Makai /// template class ResGraphAdaptor : - public SubBidirGraphAdaptor< - Graph, + public EdgeSubGraphAdaptor< + UndirGraphAdaptor, + typename UndirGraphAdaptor::template CombinedEdgeMap< ResForwardFilter, - ResBackwardFilter > { + ResBackwardFilter > > { public: - typedef SubBidirGraphAdaptor< - Graph, - ResForwardFilter, - ResBackwardFilter > Parent; + + typedef UndirGraphAdaptor UGraph; + + typedef ResForwardFilter + ForwardFilter; + + typedef ResBackwardFilter + BackwardFilter; + + typedef typename UGraph:: + template CombinedEdgeMap + EdgeFilter; + + typedef EdgeSubGraphAdaptor Parent; + protected: + const CapacityMap* capacity; FlowMap* flow; - ResForwardFilter forward_filter; - ResBackwardFilter backward_filter; - ResGraphAdaptor() : Parent(), - capacity(0), flow(0) { } + + UGraph ugraph; + ForwardFilter forward_filter; + BackwardFilter backward_filter; + EdgeFilter edge_filter; + void setCapacityMap(const CapacityMap& _capacity) { capacity=&_capacity; forward_filter.setCapacity(_capacity); backward_filter.setCapacity(_capacity); } + void setFlowMap(FlowMap& _flow) { flow=&_flow; forward_filter.setFlow(_flow); backward_filter.setFlow(_flow); } + public: + ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity, - FlowMap& _flow) : - Parent(), capacity(&_capacity), flow(&_flow), - forward_filter(/*_graph,*/ _capacity, _flow), - backward_filter(/*_graph,*/ _capacity, _flow) { - Parent::setGraph(_graph); - Parent::setForwardFilterMap(forward_filter); - Parent::setBackwardFilterMap(backward_filter); + FlowMap& _flow) + : Parent(), capacity(&_capacity), flow(&_flow), + ugraph(_graph), + forward_filter(_capacity, _flow), + backward_filter(_capacity, _flow), + edge_filter(forward_filter, backward_filter) { + Parent::setGraph(ugraph); + Parent::setEdgeFilterMap(edge_filter); } typedef typename Parent::Edge Edge; void augment(const Edge& e, Number a) const { - if (Parent::forward(e)) + if (UGraph::direction(e)) { flow->set(e, (*flow)[e]+a); - else + } else { flow->set(e, (*flow)[e]-a); + } } + static bool forward(const Edge& e) { + return UGraph::direction(e); + } + + static bool backward(const Edge& e) { + return !UGraph::direction(e); + } + + static Edge forward(const typename Graph::Edge& e) { + return UGraph::direct(e, true); + } + + static Edge backward(const typename Graph::Edge& e) { + return UGraph::direct(e, false); + } + + /// \brief Residual capacity map. /// /// In generic residual graphs the residual capacity can be obtained /// as a map. class ResCap { protected: - const ResGraphAdaptor* res_graph; + const ResGraphAdaptor* res_graph; public: typedef Number Value; typedef Edge Key; - ResCap(const ResGraphAdaptor& - _res_graph) : res_graph(&_res_graph) { } + ResCap(const ResGraphAdaptor& _res_graph) + : res_graph(&_res_graph) {} + Number operator[](const Edge& e) const { - if (res_graph->forward(e)) + if (ResGraphAdaptor::direction(e)) return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; else return (*(res_graph->flow))[e]; } + }; - // KEEP_MAPS(Parent, ResGraphAdaptor); }; diff -r 15fb7a4ea6be -r d7442141d9ef lemon/list_graph.h --- a/lemon/list_graph.h Wed Mar 01 10:17:25 2006 +0000 +++ b/lemon/list_graph.h Wed Mar 01 10:25:30 2006 +0000 @@ -962,8 +962,8 @@ /// \brief A smart bipartite undirected graph class. /// /// This is a bipartite undirected graph implementation. - /// Except from this it conforms to - /// the \ref concept::BpUGraph "BpUGraph" concept. + /// It is conforms to the \ref concept::ErasableBpUGraph "ErasableBpUGraph" + /// concept. /// \sa concept::BpUGraph. /// class ListBpUGraph : public ExtendedListBpUGraphBase {}; diff -r 15fb7a4ea6be -r d7442141d9ef lemon/ugraph_adaptor.h --- a/lemon/ugraph_adaptor.h Wed Mar 01 10:17:25 2006 +0000 +++ b/lemon/ugraph_adaptor.h Wed Mar 01 10:25:30 2006 +0000 @@ -42,9 +42,6 @@ /// /// \brief Base type for the Graph Adaptors /// - /// \warning Graph adaptors are in even more experimental state than the - /// other parts of the lib. Use them at you own risk. - /// /// This is the base type for most of LEMON graph adaptors. /// This class implements a trivial graph adaptor i.e. it only wraps the /// functions and types of the graph. The purpose of this class is to @@ -93,7 +90,6 @@ void nextOut(Edge& i) const { graph->nextOut(i); } void nextInc(UEdge &i, bool &d) const { graph->nextInc(i, d); } - Node source(const UEdge& e) const { return graph->source(e); } Node target(const UEdge& e) const { return graph->target(e); } @@ -111,7 +107,6 @@ const Edge& prev = INVALID) { return graph->findEdge(source, target, prev); } - UEdge findUEdge(const Node& source, const Node& target, const UEdge& prev = INVALID) { return graph->findUEdge(source, target, prev); @@ -132,18 +127,36 @@ bool direction(const Edge& e) const { return graph->direction(e); } Edge direct(const UEdge& e, bool d) const { return graph->direct(e, d); } - Edge direct(const UEdge& e, const Node& n) const { - return graph->direct(e, n); + + int maxNodeId() const { + return graph->maxNodeId(); } - Node oppositeNode(const Node& n, const Edge& e) const { - return graph->oppositeNode(n, e); + int maxEdgeId() const { + return graph->maxEdgeId(); } - Edge oppositeEdge(const Edge& e) const { - return graph->oppositeEdge(e); + int maxUEdgeId() const { + return graph->maxEdgeId(); } + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& getNotifier(Node) const { + return graph->getNotifier(Node()); + } + + typedef typename ItemSetTraits::ItemNotifier EdgeNotifier; + + EdgeNotifier& getNotifier(Edge) const { + return graph->getNotifier(Edge()); + } + + typedef typename ItemSetTraits::ItemNotifier UEdgeNotifier; + + UEdgeNotifier& getNotifier(UEdge) const { + return graph->getNotifier(UEdge()); + } template class NodeMap : public Graph::template NodeMap<_Value> { @@ -379,6 +392,30 @@ typedef False NodeNumTag; typedef False EdgeNumTag; + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& source, const Node& target, + const Edge& prev = INVALID) { + if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) { + return INVALID; + } + Edge edge = Parent::findEdge(source, target, prev); + while (edge != INVALID && !(*uedge_filter_map)[edge]) { + edge = Parent::findEdge(source, target, edge); + } + return edge; + } + UEdge findUEdge(const Node& source, const Node& target, + const UEdge& prev = INVALID) { + if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) { + return INVALID; + } + UEdge uedge = Parent::findUEdge(source, target, prev); + while (uedge != INVALID && !(*uedge_filter_map)[uedge]) { + uedge = Parent::findUEdge(source, target, uedge); + } + return uedge; + } }; template @@ -504,6 +541,24 @@ typedef False NodeNumTag; typedef False EdgeNumTag; + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& source, const Node& target, + const Edge& prev = INVALID) { + Edge edge = Parent::findEdge(source, target, prev); + while (edge != INVALID && !(*uedge_filter_map)[edge]) { + edge = Parent::findEdge(source, target, edge); + } + return edge; + } + UEdge findUEdge(const Node& source, const Node& target, + const UEdge& prev = INVALID) { + UEdge uedge = Parent::findUEdge(source, target, prev); + while (uedge != INVALID && !(*uedge_filter_map)[uedge]) { + uedge = Parent::findUEdge(source, target, uedge); + } + return uedge; + } }; /// \ingroup graph_adaptors @@ -581,7 +636,6 @@ /// /// \brief An adaptor for hiding nodes from an undirected graph. /// - /// /// An adaptor for hiding nodes from an undirected graph. /// This adaptor specializes SubUGraphAdaptor in the way that only /// the node-set @@ -598,6 +652,11 @@ typedef _UGraph Graph; protected: ConstMap const_true_map; + + NodeSubUGraphAdaptor() : const_true_map(true) { + Parent::setUEdgeFilterMap(const_true_map); + } + public: NodeSubUGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) : Parent(), const_true_map(true) { @@ -639,6 +698,11 @@ typedef _UGraph Graph; protected: ConstMap const_true_map; + + EdgeSubUGraphAdaptor() : const_true_map(true) { + Parent::setNodeFilterMap(const_true_map); + } + public: EdgeSubUGraphAdaptor(Graph& _graph, UEdgeFilterMap& _uedge_filter_map) : Parent(), const_true_map(true) { @@ -670,6 +734,10 @@ typedef typename _UGraph::Node Node; typedef typename _UGraph::UEdge Edge; + void reverseEdge(const Edge& edge) { + direction->set(edge, !(*direction)[edge]); + } + void first(Node& i) const { graph->first(i); } void first(Edge& i) const { graph->first(i); } void firstIn(Edge& i, const Node& n) const { @@ -746,10 +814,26 @@ int id(const Node& v) const { return graph->id(v); } int id(const Edge& e) const { return graph->id(e); } - void reverseEdge(const Edge& edge) { - direction->set(edge, !(*direction)[edge]); + int maxNodeId() const { + return graph->maxNodeId(); } + int maxEdgeId() const { + return graph->maxEdgeId(); + } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& getNotifier(Node) const { + return graph->getNotifier(Node()); + } + + typedef typename ItemSetTraits::ItemNotifier EdgeNotifier; + + EdgeNotifier& getNotifier(Edge) const { + return graph->getNotifier(Edge()); + } + template class NodeMap : public _UGraph::template NodeMap<_Value> { public: @@ -788,7 +872,8 @@ /// \ingroup graph_adaptors - /// \brief A directed graph is made from a undirected graph by an adaptor + /// + /// \brief A directed graph is made from an undirected graph by an adaptor /// /// This adaptor gives a direction for each uedge in the undirected graph. /// The direction of the edges stored in the DirectionMap. This map is diff -r 15fb7a4ea6be -r d7442141d9ef test/graph_adaptor_test.cc --- a/test/graph_adaptor_test.cc Wed Mar 01 10:17:25 2006 +0000 +++ b/test/graph_adaptor_test.cc Wed Mar 01 10:25:30 2006 +0000 @@ -58,9 +58,6 @@ checkConcept > >(); - checkConcept, Graph::EdgeMap > >(); - // checkConcept >(); checkConcept, Graph::EdgeMap > >();