[Lemon-commits] [lemon_svn] deba: r2742 - in hugo/trunk: doc/images lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:54:53 CET 2006
Author: deba
Date: Fri May 12 11:56:14 2006
New Revision: 2742
Added:
hugo/trunk/doc/images/edge_disjoint.eps
hugo/trunk/doc/images/edge_disjoint.png (contents, props changed)
hugo/trunk/doc/images/node_disjoint.eps
hugo/trunk/doc/images/node_disjoint.png (contents, props changed)
Modified:
hugo/trunk/lemon/graph_adaptor.h
Log:
Remade SplitGraphAdaptor
Added: hugo/trunk/doc/images/edge_disjoint.eps
==============================================================================
--- (empty file)
+++ hugo/trunk/doc/images/edge_disjoint.eps Fri May 12 11:56:14 2006
@@ -0,0 +1,116 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: edge disjoint path
+%%Copyright: (C) 2006 LEMON Project
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri May 12 01:53:21 2006
+%%BoundingBox: -290 -170 470 230
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+ 4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+ 2 index 1 index sub 2 index 2 index add lineto
+ 2 index 1 index sub 2 index 2 index sub lineto
+ 2 index 1 index add 2 index 2 index sub lineto
+ closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+ 2 index 2 index 2 index add lineto
+ 2 index 1 index sub 2 index lineto
+ 2 index 2 index 2 index sub lineto
+ closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+ setrgbcolor 1.1 div sq fill
+ } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+ setrgbcolor 1.1 div di fill
+ } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+ newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+ lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+ 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+ 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/nmale {
+ 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+ newpath 5 index 5 index moveto
+ 5 index 4 index 1 mul 1.5 mul add
+ 5 index 5 index 3 sqrt 1.5 mul mul add
+ 1 index 1 index lineto
+ 1 index 1 index 7 index sub moveto
+ 1 index 1 index lineto
+ exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+ stroke
+ 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+ /w exch def /len exch def
+ newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+ len w sub arrl sub dx dy lrl
+ arrw dy dx neg lrl
+ dx arrl w add mul dy w 2 div arrw add mul sub
+ dy arrl w add mul dx w 2 div arrw add mul add rlineto
+ dx arrl w add mul neg dy w 2 div arrw add mul sub
+ dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+ arrw dy dx neg lrl
+ len w sub arrl sub neg dx dy lrl
+ closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+ neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+10 dup scale
+%Edges:
+gsave
+15.6433 0.3 0.841178 -0.540758 -27 5 1 0 0 arr
+19.5913 0.3 0.874157 0.485643 -27 5 1 0 0 arr
+10.1803 0.3 0.98387 -0.178885 -20 17 1 0 0 arr
+20.587 0.3 0.972806 0.231621 -18 -14 1 0 0 arr
+15.7631 0.3 0.95448 -0.298275 -13 -4 0 0 0 arr
+15.9706 0.3 0.707107 -0.707107 -9 15 1 0 0 arr
+16.4642 0.3 0.916157 0.400819 -13 -4 1 0 0 arr
+14.5242 0.3 0.966235 -0.257663 -12 7 0 0 0 arr
+10.6619 0.3 0.857493 0.514496 -9 15 1 0 0 arr
+22.4094 0.3 0.939793 -0.341743 3 3 1 0 0 arr
+27.1602 0.3 0.958798 -0.284088 1 21 1 0 0 arr
+25.9258 0.3 0.928477 0.371391 3 3 1 0 0 arr
+25.9072 0.3 0.743294 0.668965 25 -15 1 0 0 arr
+20.5407 0.3 0.928477 0.371391 25 -5 1 0 0 arr
+18.7231 0.3 0.861934 -0.50702 28 13 1 0 0 arr
+14.2315 0.3 0.393919 0.919145 39 -11 0 0 0 arr
+10.6619 0.3 0.514496 -0.857493 39 13 1 0 0 arr
+20.0238 0.3 0.428086 -0.903738 -27 5 1 0 0 arr
+21.8035 0.3 0.964764 -0.263117 3 -9 1 0 0 arr
+14.1328 0.3 0.991228 0.132164 -27 5 0 0 0 arr
+13.5602 0.3 0.961524 0.274721 25 -15 0 0 0 arr
+10 0.3 1 0 28 13 1 0 0 arr
+12.8924 0.3 0.503871 0.863779 -27 5 1 0 0 arr
+grestore
+%Nodes:
+gsave
+-27 5 1 1 1 1 nc
+-13 -4 1 1 1 1 nc
+-9 15 1 1 1 1 nc
+3 -9 1 1 1 1 nc
+3 3 1 1 1 1 nc
+1 21 1 1 1 1 nc
+25 -5 1 1 1 1 nc
+28 13 1 1 1 1 nc
+45 3 1 1 1 1 nc
+-18 -14 1 1 1 1 nc
+25 -15 1 1 1 1 nc
+-12 7 1 1 1 1 nc
+39 -11 1 1 1 1 nc
+39 13 1 1 1 1 nc
+-20 17 1 1 1 1 nc
+grestore
+grestore
+showpage
Added: hugo/trunk/doc/images/edge_disjoint.png
==============================================================================
Binary file. No diff available.
Added: hugo/trunk/doc/images/node_disjoint.eps
==============================================================================
--- (empty file)
+++ hugo/trunk/doc/images/node_disjoint.eps Fri May 12 11:56:14 2006
@@ -0,0 +1,146 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: node disjoint path
+%%Copyright: (C) 2006 LEMON Project
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri May 12 01:53:21 2006
+%%BoundingBox: -290 -170 520 230
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+ 4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+ 2 index 1 index sub 2 index 2 index add lineto
+ 2 index 1 index sub 2 index 2 index sub lineto
+ 2 index 1 index add 2 index 2 index sub lineto
+ closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+ 2 index 2 index 2 index add lineto
+ 2 index 1 index sub 2 index lineto
+ 2 index 2 index 2 index sub lineto
+ closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+ setrgbcolor 1.1 div sq fill
+ } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+ setrgbcolor 1.1 div di fill
+ } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+ newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+ lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+ 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+ 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/nmale {
+ 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+ newpath 5 index 5 index moveto
+ 5 index 4 index 1 mul 1.5 mul add
+ 5 index 5 index 3 sqrt 1.5 mul mul add
+ 1 index 1 index lineto
+ 1 index 1 index 7 index sub moveto
+ 1 index 1 index lineto
+ exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+ stroke
+ 5 index 5 index 5 index c fill
+ setrgbcolor 1.1 div c fill
+ } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+ /w exch def /len exch def
+ newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+ len w sub arrl sub dx dy lrl
+ arrw dy dx neg lrl
+ dx arrl w add mul dy w 2 div arrw add mul sub
+ dy arrl w add mul dx w 2 div arrw add mul add rlineto
+ dx arrl w add mul neg dy w 2 div arrw add mul sub
+ dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+ arrw dy dx neg lrl
+ len w sub arrl sub neg dx dy lrl
+ closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+ neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+10 dup scale
+%Edges:
+gsave
+4 0.3 1 0 -27 5 0 0 0 arr
+4 0.3 1 0 -13 -4 1 0 0 arr
+4 0.3 1 0 -9 15 1 0 0 arr
+4 0.3 1 0 3 -9 1 0 0 arr
+4 0.3 1 0 3 3 1 0 0 arr
+4 0.3 1 0 1 21 1 0 0 arr
+4 0.3 1 0 25 -5 1 0 0 arr
+4 0.3 1 0 28 13 1 0 0 arr
+4 0.3 1 0 45 3 0 0 0 arr
+4 0.3 1 0 -18 -14 1 0 0 arr
+4 0.3 1 0 25 -15 1 0 0 arr
+4 0.3 1 0 -12 7 0 0 0 arr
+4 0.3 1 0 39 -11 0 0 0 arr
+4 0.3 1 0 39 13 0 0 0 arr
+4 0.3 1 0 -20 17 1 0 0 arr
+11.7279 0.3 0.707107 -0.707107 -22 5 1 0 0 arr
+15.4012 0.3 0.792624 0.609711 -22 5 0 0 0 arr
+5.32455 0.3 0.948683 -0.316228 -15 17 1 0 0 arr
+15.7631 0.3 0.95448 0.298275 -13 -14 1 0 0 arr
+11.083 0.3 0.910366 -0.413803 -8 -4 0 0 0 arr
+12.8924 0.3 0.503871 -0.863779 -4 15 0 0 0 arr
+12.0384 0.3 0.843661 0.536875 -8 -4 1 0 0 arr
+9.77033 0.3 0.928477 -0.371391 -7 7 0 0 0 arr
+6.81025 0.3 0.640184 0.768221 -4 15 1 0 0 arr
+17.7883 0.3 0.904819 -0.425797 8 3 1 0 0 arr
+22.4094 0.3 0.939793 -0.341743 6 21 1 0 0 arr
+21.3607 0.3 0.894427 0.447214 8 3 0 0 0 arr
+22.4307 0.3 0.640184 0.768221 30 -15 1 0 0 arr
+16 0.3 0.882353 0.470588 30 -5 1 0 0 arr
+14.6205 0.3 0.768221 -0.640184 33 13 1 0 0 arr
+13.0357 0.3 0.071247 0.997459 44 -11 0 0 0 arr
+9.04987 0.3 0.0995037 -0.995037 44 13 0 0 0 arr
+18.4165 0.3 0.20601 -0.97855 -22 5 1 0 0 arr
+17.0278 0.3 0.94299 -0.33282 8 -9 1 0 0 arr
+9.19804 0.3 0.980581 0.196116 -22 5 0 0 0 arr
+8.84886 0.3 0.913812 0.406138 30 -15 0 0 0 arr
+5 0.3 1 0 33 13 0 0 0 arr
+11.1655 0.3 0.164399 0.986394 -22 5 1 0 0 arr
+grestore
+%Nodes:
+gsave
+-27 5 1 1 1 1 nc
+-22 5 1 1 1 1 nc
+-13 -4 1 1 1 1 nc
+-8 -4 1 1 1 1 nc
+-9 15 1 1 1 1 nc
+-4 15 1 1 1 1 nc
+3 -9 1 1 1 1 nc
+8 -9 1 1 1 1 nc
+3 3 1 1 1 1 nc
+8 3 1 1 1 1 nc
+1 21 1 1 1 1 nc
+6 21 1 1 1 1 nc
+25 -5 1 1 1 1 nc
+30 -5 1 1 1 1 nc
+28 13 1 1 1 1 nc
+33 13 1 1 1 1 nc
+45 3 1 1 1 1 nc
+50 3 1 1 1 1 nc
+-18 -14 1 1 1 1 nc
+-13 -14 1 1 1 1 nc
+25 -15 1 1 1 1 nc
+30 -15 1 1 1 1 nc
+-12 7 1 1 1 1 nc
+-7 7 1 1 1 1 nc
+39 -11 1 1 1 1 nc
+44 -11 1 1 1 1 nc
+39 13 1 1 1 1 nc
+44 13 1 1 1 1 nc
+-20 17 1 1 1 1 nc
+-15 17 1 1 1 1 nc
+grestore
+grestore
+showpage
Added: hugo/trunk/doc/images/node_disjoint.png
==============================================================================
Binary file. No diff available.
Modified: hugo/trunk/lemon/graph_adaptor.h
==============================================================================
--- hugo/trunk/lemon/graph_adaptor.h (original)
+++ hugo/trunk/lemon/graph_adaptor.h Fri May 12 11:56:14 2006
@@ -36,7 +36,7 @@
#include <lemon/tolerance.h>
-#include <iostream>
+#include <algorithm>
namespace lemon {
@@ -256,9 +256,8 @@
///\code
/// RevGraphAdaptor<ListGraph> ga(g);
///\endcode
- ///implements the graph obtained from \c g by
+ /// implements the graph obtained from \c g by
/// reversing the orientation of its edges.
-
template<typename _Graph>
class RevGraphAdaptor :
public GraphAdaptorExtender<RevGraphAdaptorBase<_Graph> > {
@@ -983,13 +982,13 @@
return EdgeSubGraphAdaptor<const Graph, const EdgeFilterMap>(graph, efm);
}
- template <typename _Graph, typename Enable = void>
+ template <typename _Graph>
class UndirGraphAdaptorBase :
- public UGraphBaseExtender<GraphAdaptorBase<_Graph> > {
+ public UndirGraphExtender<GraphAdaptorBase<_Graph> > {
public:
typedef _Graph Graph;
typedef UndirGraphAdaptorBase Adaptor;
- typedef UGraphBaseExtender<GraphAdaptorBase<_Graph> > Parent;
+ typedef UndirGraphExtender<GraphAdaptorBase<_Graph> > Parent;
protected:
@@ -1103,38 +1102,50 @@
};
+ template <typename _Graph, typename Enable = void>
+ class AlterableUndirGraphAdaptor
+ : public UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > {
+ public:
+ typedef UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > Parent;
+
+ protected:
+
+ AlterableUndirGraphAdaptor() : Parent() {}
+
+ public:
+
+ typedef typename Parent::EdgeNotifier UEdgeNotifier;
+ typedef InvalidType EdgeNotifier;
+
+ };
+
template <typename _Graph>
- class UndirGraphAdaptorBase<
- _Graph, typename enable_if<
- typename _Graph::EdgeNotifier::Notifier>::type >
- : public UGraphBaseExtender<GraphAdaptorBase<_Graph> > {
+ class AlterableUndirGraphAdaptor<
+ _Graph,
+ typename enable_if<typename _Graph::EdgeNotifier::Notifier>::type >
+ : public UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > {
public:
+ typedef UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > Parent;
typedef _Graph Graph;
- typedef UndirGraphAdaptorBase Adaptor;
- typedef UGraphBaseExtender<GraphAdaptorBase<_Graph> > Parent;
-
+ typedef typename _Graph::Edge GraphEdge;
+
protected:
- UndirGraphAdaptorBase()
- : edge_notifier(*this), edge_notifier_proxy(edge_notifier) {}
+ AlterableUndirGraphAdaptor()
+ : Parent(), edge_notifier(*this), edge_notifier_proxy(*this) {}
void setGraph(_Graph& graph) {
Parent::setGraph(graph);
- edge_notifier_proxy.setUEdgeNotifier(graph.getNotifier(UEdge()));
+ edge_notifier_proxy.setNotifier(graph.getNotifier(GraphEdge()));
}
public:
- ~UndirGraphAdaptorBase() {
+ ~AlterableUndirGraphAdaptor() {
edge_notifier.clear();
}
- int maxId(typename Parent::Edge) const {
- return Parent::maxEdgeId();
- }
-
-
typedef typename Parent::UEdge UEdge;
typedef typename Parent::Edge Edge;
@@ -1142,19 +1153,20 @@
using Parent::getNotifier;
- typedef AlterationNotifier<UndirGraphAdaptorBase, Edge> EdgeNotifier;
+ typedef AlterationNotifier<AlterableUndirGraphAdaptor,
+ Edge> EdgeNotifier;
EdgeNotifier& getNotifier(Edge) const { return edge_notifier; }
protected:
- class NotifierProxy : public UEdgeNotifier::ObserverBase {
+ class NotifierProxy : public Graph::EdgeNotifier::ObserverBase {
public:
- typedef typename UEdgeNotifier::ObserverBase Parent;
- typedef UndirGraphAdaptorBase AdaptorBase;
+ typedef typename Graph::EdgeNotifier::ObserverBase Parent;
+ typedef AlterableUndirGraphAdaptor AdaptorBase;
- NotifierProxy(EdgeNotifier& _edge_notifier)
- : Parent(), edge_notifier(_edge_notifier) {
+ NotifierProxy(const AdaptorBase& _adaptor)
+ : Parent(), adaptor(&_adaptor) {
}
virtual ~NotifierProxy() {
@@ -1163,173 +1175,70 @@
}
}
- void setUEdgeNotifier(UEdgeNotifier& _uedge_notifier) {
- Parent::attach(_uedge_notifier);
+ void setNotifier(typename Graph::EdgeNotifier& notifier) {
+ Parent::attach(notifier);
}
protected:
- virtual void add(const UEdge& uedge) {
+ virtual void add(const GraphEdge& ge) {
std::vector<Edge> edges;
- edges.push_back(AdaptorBase::Parent::direct(uedge, true));
- edges.push_back(AdaptorBase::Parent::direct(uedge, false));
- edge_notifier.add(edges);
+ edges.push_back(AdaptorBase::Parent::direct(ge, true));
+ edges.push_back(AdaptorBase::Parent::direct(ge, false));
+ adaptor->getNotifier(Edge()).add(edges);
}
- virtual void add(const std::vector<UEdge>& uedges) {
+ virtual void add(const std::vector<GraphEdge>& ge) {
std::vector<Edge> 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));
+ for (int i = 0; i < (int)ge.size(); ++i) {
+ edges.push_back(AdaptorBase::Parent::direct(ge[i], true));
+ edges.push_back(AdaptorBase::Parent::direct(ge[i], false));
}
- edge_notifier.add(edges);
+ adaptor->getNotifier(Edge()).add(edges);
}
- virtual void erase(const UEdge& uedge) {
+ virtual void erase(const GraphEdge& ge) {
std::vector<Edge> edges;
- edges.push_back(AdaptorBase::Parent::direct(uedge, true));
- edges.push_back(AdaptorBase::Parent::direct(uedge, false));
- edge_notifier.erase(edges);
+ edges.push_back(AdaptorBase::Parent::direct(ge, true));
+ edges.push_back(AdaptorBase::Parent::direct(ge, false));
+ adaptor->getNotifier(Edge()).erase(edges);
}
- virtual void erase(const std::vector<UEdge>& uedges) {
+ virtual void erase(const std::vector<GraphEdge>& ge) {
std::vector<Edge> 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));
+ for (int i = 0; i < (int)ge.size(); ++i) {
+ edges.push_back(AdaptorBase::Parent::direct(ge[i], true));
+ edges.push_back(AdaptorBase::Parent::direct(ge[i], false));
}
- edge_notifier.erase(edges);
+ adaptor->getNotifier(Edge()).erase(edges);
}
virtual void build() {
- edge_notifier.build();
+ adaptor->getNotifier(Edge()).build();
}
virtual void clear() {
- edge_notifier.clear();
+ adaptor->getNotifier(Edge()).clear();
}
- EdgeNotifier& edge_notifier;
+ const AdaptorBase* adaptor;
};
mutable EdgeNotifier edge_notifier;
NotifierProxy edge_notifier_proxy;
- private:
-
- template <typename _Value>
- class EdgeMapBase {
- private:
-
- typedef typename _Graph::template EdgeMap<_Value> MapImpl;
-
- public:
-
- typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
-
- typedef _Value Value;
- typedef Edge Key;
-
- EdgeMapBase(const Adaptor& adaptor) :
- forward_map(*adaptor.graph), backward_map(*adaptor.graph) {}
-
- EdgeMapBase(const Adaptor& adaptor, const Value& v)
- : forward_map(*adaptor.graph, v), backward_map(*adaptor.graph, v) {}
-
- 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<MapImpl>::ConstReturnValue operator[](Edge e) const {
- if (Parent::direction(e)) {
- return forward_map[e];
- } else {
- return backward_map[e];
- }
- }
-
- typename MapTraits<MapImpl>::ReturnValue operator[](Edge e) {
- if (Parent::direction(e)) {
- return forward_map[e];
- } else {
- return backward_map[e];
- }
- }
-
- protected:
-
- MapImpl forward_map, backward_map;
-
- };
-
- public:
-
- template <typename _Value>
- class EdgeMap
- : public SubMapExtender<Adaptor, EdgeMapBase<_Value> >
- {
- public:
- typedef Adaptor Graph;
- typedef SubMapExtender<Adaptor, EdgeMapBase<_Value> > Parent;
-
- EdgeMap(const Graph& graph)
- : Parent(graph) {}
- EdgeMap(const Graph& graph, const _Value& value)
- : Parent(graph, value) {}
-
- EdgeMap& operator=(const EdgeMap& cmap) {
- return operator=<EdgeMap>(cmap);
- }
-
- template <typename CMap>
- EdgeMap& operator=(const CMap& cmap) {
- Parent::operator=(cmap);
- return *this;
- }
- };
-
- template <typename _Value>
- class UEdgeMap : public Graph::template EdgeMap<_Value> {
- public:
-
- typedef typename Graph::template EdgeMap<_Value> Parent;
-
- explicit UEdgeMap(const Adaptor& ga)
- : Parent(*ga.graph) {}
-
- UEdgeMap(const Adaptor& ga, const _Value& value)
- : Parent(*ga.graph, value) {}
-
- UEdgeMap& operator=(const UEdgeMap& cmap) {
- return operator=<UEdgeMap>(cmap);
- }
-
- template <typename CMap>
- UEdgeMap& operator=(const CMap& cmap) {
- Parent::operator=(cmap);
- return *this;
- }
-
- };
-
};
- ///\brief An undirected graph is made from a directed graph by an adaptor
- ///\ingroup graph_adaptors
+
+ /// \brief An undirected graph is made from a directed graph by an adaptor
+ /// \ingroup graph_adaptors
///
/// Undocumented, untested!!!
/// If somebody knows nice demo application, let's polulate it.
///
/// \author Marton Makai
template<typename _Graph>
- class UndirGraphAdaptor :
- public UGraphAdaptorExtender<
- UndirGraphAdaptorBase<_Graph> > {
+ class UndirGraphAdaptor : public AlterableUndirGraphAdaptor<_Graph> {
public:
typedef _Graph Graph;
- typedef UGraphAdaptorExtender<
- UndirGraphAdaptorBase<_Graph> > Parent;
+ typedef AlterableUndirGraphAdaptor<_Graph> Parent;
protected:
UndirGraphAdaptor() { }
public:
@@ -1694,371 +1603,977 @@
};
-// template <typename _Graph>
-// class SplitGraphAdaptorBase
-// : public GraphAdaptorBase<_Graph> {
-// public:
-// typedef GraphAdaptorBase<_Graph> Parent;
-
-// class Node;
-// class Edge;
-// template <typename T> class NodeMap;
-// template <typename T> class EdgeMap;
-
-
-// class Node : public Parent::Node {
-// friend class SplitGraphAdaptorBase;
-// template <typename T> friend class NodeMap;
-// typedef typename Parent::Node NodeParent;
-// private:
-
-// bool entry;
-// Node(typename Parent::Node _node, bool _entry)
-// : Parent::Node(_node), entry(_entry) {}
-
-// public:
-// Node() {}
-// Node(Invalid) : NodeParent(INVALID), entry(true) {}
-
-// bool operator==(const Node& node) const {
-// return NodeParent::operator==(node) && entry == node.entry;
-// }
-
-// bool operator!=(const Node& node) const {
-// return !(*this == node);
-// }
-
-// bool operator<(const Node& node) const {
-// return NodeParent::operator<(node) ||
-// (NodeParent::operator==(node) && entry < node.entry);
-// }
-// };
-
-// /// \todo May we want VARIANT/union type
-// class Edge : public Parent::Edge {
-// friend class SplitGraphAdaptorBase;
-// template <typename T> friend class EdgeMap;
-// private:
-// typedef typename Parent::Edge EdgeParent;
-// typedef typename Parent::Node NodeParent;
-// NodeParent bind;
-
-// Edge(const EdgeParent& edge, const NodeParent& node)
-// : EdgeParent(edge), bind(node) {}
-// public:
-// Edge() {}
-// Edge(Invalid) : EdgeParent(INVALID), bind(INVALID) {}
-
-// bool operator==(const Edge& edge) const {
-// return EdgeParent::operator==(edge) && bind == edge.bind;
-// }
-
-// bool operator!=(const Edge& edge) const {
-// return !(*this == edge);
-// }
-
-// bool operator<(const Edge& edge) const {
-// return EdgeParent::operator<(edge) ||
-// (EdgeParent::operator==(edge) && bind < edge.bind);
-// }
-// };
-
-// void first(Node& node) const {
-// Parent::first(node);
-// node.entry = true;
-// }
-
-// void next(Node& node) const {
-// if (node.entry) {
-// node.entry = false;
-// } else {
-// node.entry = true;
-// Parent::next(node);
-// }
-// }
-
-// void first(Edge& edge) const {
-// Parent::first(edge);
-// if ((typename Parent::Edge&)edge == INVALID) {
-// Parent::first(edge.bind);
-// } else {
-// edge.bind = INVALID;
-// }
-// }
-
-// void next(Edge& edge) const {
-// if ((typename Parent::Edge&)edge != INVALID) {
-// Parent::next(edge);
-// if ((typename Parent::Edge&)edge == INVALID) {
-// Parent::first(edge.bind);
-// }
-// } else {
-// Parent::next(edge.bind);
-// }
-// }
-
-// void firstIn(Edge& edge, const Node& node) const {
-// if (node.entry) {
-// Parent::firstIn(edge, node);
-// edge.bind = INVALID;
-// } else {
-// (typename Parent::Edge&)edge = INVALID;
-// edge.bind = node;
-// }
-// }
-
-// void nextIn(Edge& edge) const {
-// if ((typename Parent::Edge&)edge != INVALID) {
-// Parent::nextIn(edge);
-// } else {
-// edge.bind = INVALID;
-// }
-// }
-
-// void firstOut(Edge& edge, const Node& node) const {
-// if (!node.entry) {
-// Parent::firstOut(edge, node);
-// edge.bind = INVALID;
-// } else {
-// (typename Parent::Edge&)edge = INVALID;
-// edge.bind = node;
-// }
-// }
-
-// void nextOut(Edge& edge) const {
-// if ((typename Parent::Edge&)edge != INVALID) {
-// Parent::nextOut(edge);
-// } else {
-// edge.bind = INVALID;
-// }
-// }
-
-// Node source(const Edge& edge) const {
-// if ((typename Parent::Edge&)edge != INVALID) {
-// return Node(Parent::source(edge), false);
-// } else {
-// return Node(edge.bind, true);
-// }
-// }
-
-// Node target(const Edge& edge) const {
-// if ((typename Parent::Edge&)edge != INVALID) {
-// return Node(Parent::target(edge), true);
-// } else {
-// return Node(edge.bind, false);
-// }
-// }
-
-// static bool entryNode(const Node& node) {
-// return node.entry;
-// }
-
-// static bool exitNode(const Node& node) {
-// return !node.entry;
-// }
-
-// static Node getEntry(const typename Parent::Node& node) {
-// return Node(node, true);
-// }
-
-// static Node getExit(const typename Parent::Node& node) {
-// return Node(node, false);
-// }
-
-// static bool originalEdge(const Edge& edge) {
-// return (typename Parent::Edge&)edge != INVALID;
-// }
-
-// static bool bindingEdge(const Edge& edge) {
-// return edge.bind != INVALID;
-// }
-
-// static Node getBindedNode(const Edge& edge) {
-// return edge.bind;
-// }
-
-// int nodeNum() const {
-// return Parent::nodeNum() * 2;
-// }
-
-// typedef True EdgeNumTag;
-
-// int edgeNum() const {
-// return countEdges() + Parent::nodeNum();
-// }
-
-// Edge findEdge(const Node& source, const Node& target,
-// const Edge& prev = INVALID) const {
-// if (exitNode(source) && entryNode(target)) {
-// return Parent::findEdge(source, target, prev);
-// } else {
-// if (prev == INVALID && entryNode(source) && exitNode(target) &&
-// (typename Parent::Node&)source == (typename Parent::Node&)target) {
-// return Edge(INVALID, source);
-// } else {
-// return INVALID;
-// }
-// }
-// }
-
-// template <typename T>
-// class NodeMap : public MapBase<Node, T> {
-// typedef typename Parent::template NodeMap<T> NodeImpl;
-// public:
-// NodeMap(const SplitGraphAdaptorBase& _graph)
-// : entry(_graph), exit(_graph) {}
-// NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
-// : entry(_graph, t), exit(_graph, t) {}
-
-// void set(const Node& key, const T& val) {
-// if (key.entry) { entry.set(key, val); }
-// else {exit.set(key, val); }
-// }
-
-// typename MapTraits<NodeImpl>::ReturnValue
-// operator[](const Node& key) {
-// if (key.entry) { return entry[key]; }
-// else { return exit[key]; }
-// }
-
-// typename MapTraits<NodeImpl>::ConstReturnValue
-// operator[](const Node& key) const {
-// if (key.entry) { return entry[key]; }
-// else { return exit[key]; }
-// }
-
-// private:
-// NodeImpl entry, exit;
-// };
-
-// template <typename T>
-// class EdgeMap : public MapBase<Edge, T> {
-// typedef typename Parent::template NodeMap<T> NodeImpl;
-// typedef typename Parent::template EdgeMap<T> EdgeImpl;
-// public:
-// EdgeMap(const SplitGraphAdaptorBase& _graph)
-// : bind(_graph), orig(_graph) {}
-// EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
-// : bind(_graph, t), orig(_graph, t) {}
-
-// void set(const Edge& key, const T& val) {
-// if ((typename Parent::Edge&)key != INVALID) { orig.set(key, val); }
-// else {bind.set(key.bind, val); }
-// }
-
-// typename MapTraits<EdgeImpl>::ReturnValue
-// operator[](const Edge& key) {
-// if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
-// else {return bind[key.bind]; }
-// }
-
-// typename MapTraits<EdgeImpl>::ConstReturnValue
-// operator[](const Edge& key) const {
-// if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
-// else {return bind[key.bind]; }
-// }
-
-// private:
-// typename Parent::template NodeMap<T> bind;
-// typename Parent::template EdgeMap<T> orig;
-// };
-
-// template <typename EntryMap, typename ExitMap>
-// class CombinedNodeMap : public MapBase<Node, typename EntryMap::Value> {
-// public:
-// typedef MapBase<Node, typename EntryMap::Value> Parent;
-
-// typedef typename Parent::Key Key;
-// typedef typename Parent::Value Value;
-
-// CombinedNodeMap(EntryMap& _entryMap, ExitMap& _exitMap)
-// : entryMap(_entryMap), exitMap(_exitMap) {}
-
-// Value& operator[](const Key& key) {
-// if (key.entry) {
-// return entryMap[key];
-// } else {
-// return exitMap[key];
-// }
-// }
-
-// Value operator[](const Key& key) const {
-// if (key.entry) {
-// return entryMap[key];
-// } else {
-// return exitMap[key];
-// }
-// }
-
-// void set(const Key& key, const Value& value) {
-// if (key.entry) {
-// entryMap.set(key, value);
-// } else {
-// exitMap.set(key, value);
-// }
-// }
-
-// private:
-
-// EntryMap& entryMap;
-// ExitMap& exitMap;
-
-// };
-
-// template <typename EdgeMap, typename NodeMap>
-// class CombinedEdgeMap : public MapBase<Edge, typename EdgeMap::Value> {
-// public:
-// typedef MapBase<Edge, typename EdgeMap::Value> Parent;
-
-// typedef typename Parent::Key Key;
-// typedef typename Parent::Value Value;
-
-// CombinedEdgeMap(EdgeMap& _edgeMap, NodeMap& _nodeMap)
-// : edgeMap(_edgeMap), nodeMap(_nodeMap) {}
-
-// void set(const Edge& edge, const Value& val) {
-// if (SplitGraphAdaptorBase::originalEdge(edge)) {
-// edgeMap.set(edge, val);
-// } else {
-// nodeMap.set(SplitGraphAdaptorBase::bindedNode(edge), val);
-// }
-// }
-
-// Value operator[](const Key& edge) const {
-// if (SplitGraphAdaptorBase::originalEdge(edge)) {
-// return edgeMap[edge];
-// } else {
-// return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
-// }
-// }
-
-// Value& operator[](const Key& edge) {
-// if (SplitGraphAdaptorBase::originalEdge(edge)) {
-// return edgeMap[edge];
-// } else {
-// return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
-// }
-// }
-
-// private:
-// EdgeMap& edgeMap;
-// NodeMap& nodeMap;
-// };
-
-// };
-
-// template <typename _Graph>
-// class SplitGraphAdaptor
-// : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
-// public:
-// typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
-
-// SplitGraphAdaptor(_Graph& graph) {
-// Parent::setGraph(graph);
-// }
+ /// \brief Base class for split graph adaptor
+ ///
+ /// Base class of split graph adaptor. In most case you do not need to
+ /// use it directly but the documented member functions of this class can
+ /// be used with the SplitGraphAdaptor class.
+ /// \sa SplitGraphAdaptor
+ template <typename _Graph>
+ class SplitGraphAdaptorBase
+ : public GraphAdaptorBase<const _Graph> {
+ public:
+
+ typedef _Graph Graph;
+
+ typedef GraphAdaptorBase<const _Graph> Parent;
+
+ typedef typename Graph::Node GraphNode;
+ typedef typename Graph::Edge GraphEdge;
+
+ class Node;
+ class Edge;
+
+ template <typename T> class NodeMap;
+ template <typename T> class EdgeMap;
+
+
+ class Node : public GraphNode {
+ friend class SplitGraphAdaptorBase;
+ template <typename T> friend class NodeMap;
+ private:
+
+ bool in_node;
+ Node(GraphNode _node, bool _in_node)
+ : GraphNode(_node), in_node(_in_node) {}
+
+ public:
+
+ Node() {}
+ Node(Invalid) : GraphNode(INVALID), in_node(true) {}
+
+ bool operator==(const Node& node) const {
+ return GraphNode::operator==(node) && in_node == node.in_node;
+ }
+
+ bool operator!=(const Node& node) const {
+ return !(*this == node);
+ }
+
+ bool operator<(const Node& node) const {
+ return GraphNode::operator<(node) ||
+ (GraphNode::operator==(node) && in_node < node.in_node);
+ }
+ };
+
+ class Edge {
+ friend class SplitGraphAdaptorBase;
+ template <typename T> friend class EdgeMap;
+ private:
+ typedef BiVariant<GraphEdge, GraphNode> EdgeImpl;
+
+ explicit Edge(const GraphEdge& edge) : item(edge) {}
+ explicit Edge(const GraphNode& node) : item(node) {}
+
+ EdgeImpl item;
+
+ public:
+ Edge() {}
+ Edge(Invalid) : item(GraphEdge(INVALID)) {}
+
+ bool operator==(const Edge& edge) const {
+ if (item.firstState()) {
+ if (edge.item.firstState()) {
+ return item.first() == edge.item.first();
+ }
+ } else {
+ if (edge.item.secondState()) {
+ return item.second() == edge.item.second();
+ }
+ }
+ return false;
+ }
+
+ bool operator!=(const Edge& edge) const {
+ return !(*this == edge);
+ }
+
+ bool operator<(const Edge& edge) const {
+ if (item.firstState()) {
+ if (edge.item.firstState()) {
+ return item.first() < edge.item.first();
+ }
+ return false;
+ } else {
+ if (edge.item.secondState()) {
+ return item.second() < edge.item.second();
+ }
+ return true;
+ }
+ }
+
+ operator GraphEdge() const { return item.first(); }
+ operator GraphNode() const { return item.second(); }
+
+ };
+
+ void first(Node& node) const {
+ Parent::first(node);
+ node.in_node = true;
+ }
+
+ void next(Node& node) const {
+ if (node.in_node) {
+ node.in_node = false;
+ } else {
+ node.in_node = true;
+ Parent::next(node);
+ }
+ }
+
+ void first(Edge& edge) const {
+ edge.item.setSecond();
+ Parent::first(edge.item.second());
+ if (edge.item.second() == INVALID) {
+ edge.item.setFirst();
+ Parent::first(edge.item.first());
+ }
+ }
+
+ void next(Edge& edge) const {
+ if (edge.item.secondState()) {
+ Parent::next(edge.item.second());
+ if (edge.item.second() == INVALID) {
+ edge.item.setFirst();
+ Parent::first(edge.item.first());
+ }
+ } else {
+ Parent::next(edge.item.first());
+ }
+ }
+
+ void firstOut(Edge& edge, const Node& node) const {
+ if (node.in_node) {
+ edge.item.setSecond(node);
+ } else {
+ edge.item.setFirst();
+ Parent::firstOut(edge.item.first(), node);
+ }
+ }
+
+ void nextOut(Edge& edge) const {
+ if (!edge.item.firstState()) {
+ edge.item.setFirst(INVALID);
+ } else {
+ Parent::nextOut(edge.item.first());
+ }
+ }
+
+ void firstIn(Edge& edge, const Node& node) const {
+ if (!node.in_node) {
+ edge.item.setSecond(node);
+ } else {
+ edge.item.setFirst();
+ Parent::firstIn(edge.item.first(), node);
+ }
+ }
+
+ void nextIn(Edge& edge) const {
+ if (!edge.item.firstState()) {
+ edge.item.setFirst(INVALID);
+ } else {
+ Parent::nextIn(edge.item.first());
+ }
+ }
+
+ Node source(const Edge& edge) const {
+ if (edge.item.firstState()) {
+ return Node(Parent::source(edge.item.first()), false);
+ } else {
+ return Node(edge.item.second(), true);
+ }
+ }
+
+ Node target(const Edge& edge) const {
+ if (edge.item.firstState()) {
+ return Node(Parent::target(edge.item.first()), true);
+ } else {
+ return Node(edge.item.second(), false);
+ }
+ }
+
+ int id(const Node& node) const {
+ return (Parent::id(node) << 1) | (node.in_node ? 0 : 1);
+ }
+ Node nodeFromId(int id) const {
+ return Node(Parent::nodeFromId(id >> 1), (id & 1) == 0);
+ }
+ int maxNodeId() const {
+ return 2 * Parent::maxNodeId() + 1;
+ }
+
+ int id(const Edge& edge) const {
+ if (edge.item.firstState()) {
+ return Parent::id(edge.item.first()) << 1;
+ } else {
+ return (Parent::id(edge.item.second()) << 1) | 1;
+ }
+ }
+ Edge edgeFromId(int id) const {
+ if ((id & 1) == 0) {
+ return Edge(Parent::edgeFromId(id >> 1));
+ } else {
+ return Edge(Parent::nodeFromId(id >> 1));
+ }
+ }
+ int maxEdgeId() const {
+ return std::max(Parent::maxNodeId() << 1,
+ (Parent::maxEdgeId() << 1) | 1);
+ }
+
+ /// \brief Returns true when the node is in-node.
+ ///
+ /// Returns true when the node is in-node.
+ static bool inNode(const Node& node) {
+ return node.in_node;
+ }
+
+ /// \brief Returns true when the node is out-node.
+ ///
+ /// Returns true when the node is out-node.
+ static bool outNode(const Node& node) {
+ return !node.in_node;
+ }
+
+ /// \brief Returns true when the edge is edge in the original graph.
+ ///
+ /// Returns true when the edge is edge in the original graph.
+ static bool origEdge(const Edge& edge) {
+ return edge.item.firstState();
+ }
+
+ /// \brief Returns true when the edge binds an in-node and an out-node.
+ ///
+ /// Returns true when the edge binds an in-node and an out-node.
+ static bool bindEdge(const Edge& edge) {
+ return edge.item.secondState();
+ }
+
+ /// \brief Gives back the in-node created from the \c node.
+ ///
+ /// Gives back the in-node created from the \c node.
+ static Node inNode(const GraphNode& node) {
+ return Node(node, true);
+ }
+
+ /// \brief Gives back the out-node created from the \c node.
+ ///
+ /// Gives back the out-node created from the \c node.
+ static Node outNode(const GraphNode& node) {
+ return Node(node, false);
+ }
+
+ /// \brief Gives back the edge binds the two part of the node.
+ ///
+ /// Gives back the edge binds the two part of the node.
+ static Edge edge(const GraphNode& node) {
+ return Edge(node);
+ }
+
+ /// \brief Gives back the edge of the original edge.
+ ///
+ /// Gives back the edge of the original edge.
+ static Edge edge(const GraphEdge& edge) {
+ return Edge(edge);
+ }
+
+ typedef True NodeNumTag;
+
+ int nodeNum() const {
+ return 2 * countNodes(*Parent::graph);
+ }
+
+ typedef True EdgeNumTag;
+
+ int edgeNum() const {
+ return countEdges(*Parent::graph) + countNodes(*Parent::graph);
+ }
+
+ typedef True FindEdgeTag;
+
+ Edge findEdge(const Node& source, const Node& target,
+ const Edge& prev = INVALID) const {
+ if (inNode(source)) {
+ if (outNode(target)) {
+ if ((GraphNode&)source == (GraphNode&)target && prev == INVALID) {
+ return Edge(source);
+ }
+ }
+ } else {
+ if (inNode(target)) {
+ return Edge(findEdge(*Parent::graph, source, target, prev));
+ }
+ }
+ return INVALID;
+ }
+
+ template <typename T>
+ class NodeMap : public MapBase<Node, T> {
+ typedef typename Parent::template NodeMap<T> NodeImpl;
+ public:
+ NodeMap(const SplitGraphAdaptorBase& _graph)
+ : inNodeMap(_graph), outNodeMap(_graph) {}
+ NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
+ : inNodeMap(_graph, t), outNodeMap(_graph, t) {}
+
+ void set(const Node& key, const T& val) {
+ if (SplitGraphAdaptorBase::inNode(key)) { inNodeMap.set(key, val); }
+ else {outNodeMap.set(key, val); }
+ }
+
+ typename MapTraits<NodeImpl>::ReturnValue
+ operator[](const Node& key) {
+ if (SplitGraphAdaptorBase::inNode(key)) { return inNodeMap[key]; }
+ else { return outNodeMap[key]; }
+ }
+
+ typename MapTraits<NodeImpl>::ConstReturnValue
+ operator[](const Node& key) const {
+ if (SplitGraphAdaptorBase::inNode(key)) { return inNodeMap[key]; }
+ else { return outNodeMap[key]; }
+ }
+
+ private:
+ NodeImpl inNodeMap, outNodeMap;
+ };
+
+ template <typename T>
+ class EdgeMap : public MapBase<Edge, T> {
+ typedef typename Parent::template EdgeMap<T> EdgeMapImpl;
+ typedef typename Parent::template NodeMap<T> NodeMapImpl;
+ public:
+
+ EdgeMap(const SplitGraphAdaptorBase& _graph)
+ : edge_map(_graph), node_map(_graph) {}
+ EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
+ : edge_map(_graph, t), node_map(_graph, t) {}
+
+ void set(const Edge& key, const T& val) {
+ if (SplitGraphAdaptorBase::origEdge(key)) {
+ edge_map.set(key.item.first(), val);
+ } else {
+ node_map.set(key.item.second(), val);
+ }
+ }
+
+ typename MapTraits<EdgeMapImpl>::ReturnValue
+ operator[](const Edge& key) {
+ if (SplitGraphAdaptorBase::origEdge(key)) {
+ return edge_map[key.item.first()];
+ } else {
+ return node_map[key.item.second()];
+ }
+ }
+
+ typename MapTraits<EdgeMapImpl>::ConstReturnValue
+ operator[](const Edge& key) const {
+ if (SplitGraphAdaptorBase::origEdge(key)) {
+ return edge_map[key.item.first()];
+ } else {
+ return node_map[key.item.second()];
+ }
+ }
+
+ private:
+ typename Parent::template EdgeMap<T> edge_map;
+ typename Parent::template NodeMap<T> node_map;
+ };
+
+
+ };
+
+ template <typename _Graph, typename NodeEnable = void,
+ typename EdgeEnable = void>
+ class AlterableSplitGraphAdaptor
+ : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
+ public:
+
+ typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
+ typedef _Graph Graph;
+
+ typedef typename Graph::Node GraphNode;
+ typedef typename Graph::Node GraphEdge;
+
+ protected:
+
+ AlterableSplitGraphAdaptor() : Parent() {}
+
+ public:
+
+ typedef InvalidType NodeNotifier;
+ typedef InvalidType EdgeNotifier;
+
+ };
+
+ template <typename _Graph, typename EdgeEnable>
+ class AlterableSplitGraphAdaptor<
+ _Graph,
+ typename enable_if<typename _Graph::NodeNotifier::Notifier>::type,
+ EdgeEnable>
+ : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
+ public:
+
+ typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
+ typedef _Graph Graph;
+
+ typedef typename Graph::Node GraphNode;
+ typedef typename Graph::Edge GraphEdge;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::Edge Edge;
+
+ protected:
+
+ AlterableSplitGraphAdaptor()
+ : Parent(), node_notifier(*this), node_notifier_proxy(*this) {}
+
+ void setGraph(_Graph& graph) {
+ Parent::setGraph(graph);
+ node_notifier_proxy.setNotifier(graph.getNotifier(GraphNode()));
+ }
+
+ public:
+
+ ~AlterableSplitGraphAdaptor() {
+ node_notifier.clear();
+ }
+
+ typedef AlterationNotifier<AlterableSplitGraphAdaptor, Node> NodeNotifier;
+ typedef InvalidType EdgeNotifier;
+
+ NodeNotifier& getNotifier(Node) const { return node_notifier; }
+
+ protected:
+
+ class NodeNotifierProxy : public Graph::NodeNotifier::ObserverBase {
+ public:
+
+ typedef typename Graph::NodeNotifier::ObserverBase Parent;
+ typedef AlterableSplitGraphAdaptor AdaptorBase;
+
+ NodeNotifierProxy(const AdaptorBase& _adaptor)
+ : Parent(), adaptor(&_adaptor) {
+ }
+
+ virtual ~NodeNotifierProxy() {
+ if (Parent::attached()) {
+ Parent::detach();
+ }
+ }
+
+ void setNotifier(typename Graph::NodeNotifier& graph_notifier) {
+ Parent::attach(graph_notifier);
+ }
+
+
+ protected:
+
+ virtual void add(const GraphNode& gn) {
+ std::vector<Node> nodes;
+ nodes.push_back(AdaptorBase::Parent::inNode(gn));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn));
+ adaptor->getNotifier(Node()).add(nodes);
+ }
+
+ virtual void add(const std::vector<GraphNode>& gn) {
+ std::vector<Node> nodes;
+ for (int i = 0; i < (int)gn.size(); ++i) {
+ nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
+ }
+ adaptor->getNotifier(Node()).add(nodes);
+ }
+
+ virtual void erase(const GraphNode& gn) {
+ std::vector<Node> nodes;
+ nodes.push_back(AdaptorBase::Parent::inNode(gn));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn));
+ adaptor->getNotifier(Node()).erase(nodes);
+ }
+
+ virtual void erase(const std::vector<GraphNode>& gn) {
+ std::vector<Node> nodes;
+ for (int i = 0; i < (int)gn.size(); ++i) {
+ nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
+ }
+ adaptor->getNotifier(Node()).erase(nodes);
+ }
+ virtual void build() {
+ adaptor->getNotifier(Node()).build();
+ }
+ virtual void clear() {
+ adaptor->getNotifier(Node()).clear();
+ }
+
+ const AdaptorBase* adaptor;
+ };
+
+
+ mutable NodeNotifier node_notifier;
+
+ NodeNotifierProxy node_notifier_proxy;
+
+ };
+
+ template <typename _Graph>
+ class AlterableSplitGraphAdaptor<
+ _Graph,
+ typename enable_if<typename _Graph::NodeNotifier::Notifier>::type,
+ typename enable_if<typename _Graph::EdgeNotifier::Notifier>::type>
+ : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
+ public:
+
+ typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
+ typedef _Graph Graph;
+
+ typedef typename Graph::Node GraphNode;
+ typedef typename Graph::Edge GraphEdge;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::Edge Edge;
+
+ protected:
+
+ AlterableSplitGraphAdaptor()
+ : Parent(), node_notifier(*this), edge_notifier(*this),
+ node_notifier_proxy(*this), edge_notifier_proxy(*this) {}
+
+ void setGraph(_Graph& graph) {
+ Parent::setGraph(graph);
+ node_notifier_proxy.setNotifier(graph.getNotifier(GraphNode()));
+ edge_notifier_proxy.setNotifier(graph.getNotifier(GraphEdge()));
+ }
+
+ public:
+
+ ~AlterableSplitGraphAdaptor() {
+ node_notifier.clear();
+ edge_notifier.clear();
+ }
+
+ typedef AlterationNotifier<AlterableSplitGraphAdaptor, Node> NodeNotifier;
+ typedef AlterationNotifier<AlterableSplitGraphAdaptor, Edge> EdgeNotifier;
+
+ NodeNotifier& getNotifier(Node) const { return node_notifier; }
+ EdgeNotifier& getNotifier(Edge) const { return edge_notifier; }
+
+ protected:
+
+ class NodeNotifierProxy : public Graph::NodeNotifier::ObserverBase {
+ public:
+
+ typedef typename Graph::NodeNotifier::ObserverBase Parent;
+ typedef AlterableSplitGraphAdaptor AdaptorBase;
+
+ NodeNotifierProxy(const AdaptorBase& _adaptor)
+ : Parent(), adaptor(&_adaptor) {
+ }
+
+ virtual ~NodeNotifierProxy() {
+ if (Parent::attached()) {
+ Parent::detach();
+ }
+ }
+
+ void setNotifier(typename Graph::NodeNotifier& graph_notifier) {
+ Parent::attach(graph_notifier);
+ }
+
+
+ protected:
+
+ virtual void add(const GraphNode& gn) {
+ std::vector<Node> nodes;
+ nodes.push_back(AdaptorBase::Parent::inNode(gn));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn));
+ adaptor->getNotifier(Node()).add(nodes);
+ adaptor->getNotifier(Edge()).add(AdaptorBase::Parent::edge(gn));
+ }
+ virtual void add(const std::vector<GraphNode>& gn) {
+ std::vector<Node> nodes;
+ std::vector<Edge> edges;
+ for (int i = 0; i < (int)gn.size(); ++i) {
+ edges.push_back(AdaptorBase::Parent::edge(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
+ }
+ adaptor->getNotifier(Node()).add(nodes);
+ adaptor->getNotifier(Edge()).add(edges);
+ }
+ virtual void erase(const GraphNode& gn) {
+ adaptor->getNotifier(Edge()).erase(AdaptorBase::Parent::edge(gn));
+ std::vector<Node> nodes;
+ nodes.push_back(AdaptorBase::Parent::inNode(gn));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn));
+ adaptor->getNotifier(Node()).erase(nodes);
+ }
+ virtual void erase(const std::vector<GraphNode>& gn) {
+ std::vector<Node> nodes;
+ std::vector<Edge> edges;
+ for (int i = 0; i < (int)gn.size(); ++i) {
+ edges.push_back(AdaptorBase::Parent::edge(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
+ nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
+ }
+ adaptor->getNotifier(Edge()).erase(edges);
+ adaptor->getNotifier(Node()).erase(nodes);
+ }
+ virtual void build() {
+ std::vector<Edge> edges;
+ const typename Parent::Notifier* notifier = Parent::getNotifier();
+ GraphNode it;
+ for (notifier->first(it); it != INVALID; notifier->next(it)) {
+ edges.push_back(AdaptorBase::Parent::edge(it));
+ }
+ adaptor->getNotifier(Node()).build();
+ adaptor->getNotifier(Edge()).add(edges);
+ }
+ virtual void clear() {
+ std::vector<Edge> edges;
+ const typename Parent::Notifier* notifier = Parent::getNotifier();
+ GraphNode it;
+ for (notifier->first(it); it != INVALID; notifier->next(it)) {
+ edges.push_back(AdaptorBase::Parent::edge(it));
+ }
+ adaptor->getNotifier(Edge()).erase(edges);
+ adaptor->getNotifier(Node()).clear();
+ }
+
+ const AdaptorBase* adaptor;
+ };
+
+ class EdgeNotifierProxy : public Graph::EdgeNotifier::ObserverBase {
+ public:
+
+ typedef typename Graph::EdgeNotifier::ObserverBase Parent;
+ typedef AlterableSplitGraphAdaptor AdaptorBase;
+
+ EdgeNotifierProxy(const AdaptorBase& _adaptor)
+ : Parent(), adaptor(&_adaptor) {
+ }
+
+ virtual ~EdgeNotifierProxy() {
+ if (Parent::attached()) {
+ Parent::detach();
+ }
+ }
+
+ void setNotifier(typename Graph::EdgeNotifier& graph_notifier) {
+ Parent::attach(graph_notifier);
+ }
+
+
+ protected:
+
+ virtual void add(const GraphEdge& ge) {
+ adaptor->getNotifier(Edge()).add(AdaptorBase::edge(ge));
+ }
+ virtual void add(const std::vector<GraphEdge>& ge) {
+ std::vector<Edge> edges;
+ for (int i = 0; i < (int)ge.size(); ++i) {
+ edges.push_back(AdaptorBase::edge(ge[i]));
+ }
+ adaptor->getNotifier(Edge()).add(edges);
+ }
+ virtual void erase(const GraphEdge& ge) {
+ adaptor->getNotifier(Edge()).erase(AdaptorBase::edge(ge));
+ }
+ virtual void erase(const std::vector<GraphEdge>& ge) {
+ std::vector<Edge> edges;
+ for (int i = 0; i < (int)ge.size(); ++i) {
+ edges.push_back(AdaptorBase::edge(ge[i]));
+ }
+ adaptor->getNotifier(Edge()).erase(edges);
+ }
+ virtual void build() {
+ std::vector<Edge> edges;
+ const typename Parent::Notifier* notifier = Parent::getNotifier();
+ GraphEdge it;
+ for (notifier->first(it); it != INVALID; notifier->next(it)) {
+ edges.push_back(AdaptorBase::Parent::edge(it));
+ }
+ adaptor->getNotifier(Edge()).add(edges);
+ }
+ virtual void clear() {
+ std::vector<Edge> edges;
+ const typename Parent::Notifier* notifier = Parent::getNotifier();
+ GraphEdge it;
+ for (notifier->first(it); it != INVALID; notifier->next(it)) {
+ edges.push_back(AdaptorBase::Parent::edge(it));
+ }
+ adaptor->getNotifier(Edge()).erase(edges);
+ }
+
+ const AdaptorBase* adaptor;
+ };
+
+
+ mutable NodeNotifier node_notifier;
+ mutable EdgeNotifier edge_notifier;
+
+ NodeNotifierProxy node_notifier_proxy;
+ EdgeNotifierProxy edge_notifier_proxy;
+
+ };
+
+ /// \ingroup graph_adaptors
+ ///
+ /// \brief SplitGraphAdaptor class
+ ///
+ /// This is an graph adaptor which splits all node into an in-node
+ /// and an out-node. Formaly, the adaptor replaces each \f$ u \f$
+ /// node in the graph with two node, \f$ u_{in} \f$ node and
+ /// \f$ u_{out} \f$ node. If there is an \f$ (v, u) \f$ edge in the
+ /// original graph the new target of the edge will be \f$ u_{in} \f$ and
+ /// similarly the source of the original \f$ (u, v) \f$ edge will be
+ /// \f$ u_{out} \f$. The adaptor will add for each node in the
+ /// original graph an additional edge which will connect
+ /// \f$ (u_{in}, u_{out}) \f$.
+ ///
+ /// The aim of this class is to run algorithm with node costs if the
+ /// algorithm can use directly just edge costs. In this case we should use
+ /// a \c SplitGraphAdaptor and set the node cost of the graph to the
+ /// bind edge in the adapted graph.
+ ///
+ /// By example a maximum flow algoritm can compute how many edge
+ /// disjoint paths are in the graph. But we would like to know how
+ /// many node disjoint paths are in the graph. First we have to
+ /// adapt the graph with the \c SplitGraphAdaptor. Then run the flow
+ /// algorithm on the adapted graph. The bottleneck of the flow will
+ /// be the bind edges which bounds the flow with the count of the
+ /// node disjoint paths.
+ ///
+ ///\code
+ ///
+ /// typedef SplitGraphAdaptor<SmartGraph> SGraph;
+ ///
+ /// SGraph sgraph(graph);
+ ///
+ /// typedef ConstMap<SGraph::Edge, int> SCapacity;
+ /// SCapacity scapacity(1);
+ ///
+ /// SGraph::EdgeMap<int> sflow(sgraph);
+ ///
+ /// Preflow<SGraph, int, SCapacity>
+ /// spreflow(sgraph, SGraph::outNode(source),SGraph::inNode(target),
+ /// scapacity, sflow);
+ ///
+ /// spreflow.run();
+ ///
+ ///\endcode
+ ///
+ /// The result of the mamixum flow on the original graph
+ /// shows the next figure:
+ ///
+ /// \image html edge_disjoint.png
+ /// \image latex edge_disjoint.eps "Edge disjoint paths" width=\textwidth
+ ///
+ /// And the maximum flow on the adapted graph:
+ ///
+ /// \image html node_disjoint.png
+ /// \image latex node_disjoint.eps "Node disjoint paths" width=\textwidth
+ ///
+ /// The second solution contains just 3 disjoint paths while the first 4.
+ ///
+ /// This graph adaptor is fully conform to the
+ /// \ref concept::StaticGraph "StaticGraph" concept and
+ /// contains some additional member functions and types. The
+ /// documentation of some member functions may be found just in the
+ /// SplitGraphAdaptorBase class.
+ ///
+ /// \sa SplitGraphAdaptorBase
+ template <typename _Graph>
+ class SplitGraphAdaptor : public AlterableSplitGraphAdaptor<_Graph> {
+ public:
+ typedef AlterableSplitGraphAdaptor<_Graph> Parent;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::Edge Edge;
+ /// \brief Constructor of the adaptor.
+ ///
+ /// Constructor of the adaptor.
+ SplitGraphAdaptor(_Graph& graph) {
+ Parent::setGraph(graph);
+ }
+
+ /// \brief NodeMap combined from two original NodeMap
+ ///
+ /// This class adapt two of the original graph NodeMap to
+ /// get a node map on the adapted graph.
+ template <typename InNodeMap, typename OutNodeMap>
+ class CombinedNodeMap {
+ public:
+
+ typedef Node Key;
+ typedef typename InNodeMap::Value Value;
+
+ /// \brief Constructor
+ ///
+ /// Constructor.
+ CombinedNodeMap(InNodeMap& _inNodeMap, OutNodeMap& _outNodeMap)
+ : inNodeMap(_inNodeMap), outNodeMap(_outNodeMap) {}
+
+ /// \brief The subscript operator.
+ ///
+ /// The subscript operator.
+ Value& operator[](const Key& key) {
+ if (Parent::inNode(key)) {
+ return inNodeMap[key];
+ } else {
+ return outNodeMap[key];
+ }
+ }
+
+ /// \brief The const subscript operator.
+ ///
+ /// The const subscript operator.
+ Value operator[](const Key& key) const {
+ if (Parent::inNode(key)) {
+ return inNodeMap[key];
+ } else {
+ return outNodeMap[key];
+ }
+ }
+
+ /// \brief The setter function of the map.
+ ///
+ /// The setter function of the map.
+ void set(const Key& key, const Value& value) {
+ if (Parent::inNode(key)) {
+ inNodeMap.set(key, value);
+ } else {
+ outNodeMap.set(key, value);
+ }
+ }
+
+ private:
+
+ InNodeMap& inNodeMap;
+ OutNodeMap& outNodeMap;
+
+ };
+
+
+ /// \brief Just gives back a combined node map.
+ ///
+ /// Just gives back a combined node map.
+ template <typename InNodeMap, typename OutNodeMap>
+ static CombinedNodeMap<InNodeMap, OutNodeMap>
+ combinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map) {
+ return CombinedNodeMap<InNodeMap, OutNodeMap>(in_map, out_map);
+ }
+
+ template <typename InNodeMap, typename OutNodeMap>
+ static CombinedNodeMap<const InNodeMap, OutNodeMap>
+ combinedNodeMap(const InNodeMap& in_map, OutNodeMap& out_map) {
+ return CombinedNodeMap<const InNodeMap, OutNodeMap>(in_map, out_map);
+ }
+
+ template <typename InNodeMap, typename OutNodeMap>
+ static CombinedNodeMap<InNodeMap, const OutNodeMap>
+ combinedNodeMap(InNodeMap& in_map, const OutNodeMap& out_map) {
+ return CombinedNodeMap<InNodeMap, const OutNodeMap>(in_map, out_map);
+ }
+
+ template <typename InNodeMap, typename OutNodeMap>
+ static CombinedNodeMap<const InNodeMap, const OutNodeMap>
+ combinedNodeMap(const InNodeMap& in_map, const OutNodeMap& out_map) {
+ return CombinedNodeMap<const InNodeMap,
+ const OutNodeMap>(in_map, out_map);
+ }
+
+ /// \brief EdgeMap combined from an original EdgeMap and NodeMap
+ ///
+ /// This class adapt an original graph EdgeMap and NodeMap to
+ /// get an edge map on the adapted graph.
+ template <typename GraphEdgeMap, typename GraphNodeMap>
+ class CombinedEdgeMap
+ : public MapBase<Edge, typename GraphEdgeMap::Value> {
+ public:
+ typedef MapBase<Edge, typename GraphEdgeMap::Value> Parent;
+
+ typedef typename Parent::Key Key;
+ typedef typename Parent::Value Value;
+
+ /// \brief Constructor
+ ///
+ /// Constructor.
+ CombinedEdgeMap(GraphEdgeMap& _edge_map, GraphNodeMap& _node_map)
+ : edge_map(_edge_map), node_map(_node_map) {}
+
+ /// \brief The subscript operator.
+ ///
+ /// The subscript operator.
+ void set(const Edge& edge, const Value& val) {
+ if (Parent::origEdge(edge)) {
+ edge_map.set(edge, val);
+ } else {
+ node_map.set(edge, val);
+ }
+ }
+
+ /// \brief The const subscript operator.
+ ///
+ /// The const subscript operator.
+ Value operator[](const Key& edge) const {
+ if (Parent::origEdge(edge)) {
+ return edge_map[edge];
+ } else {
+ return node_map[edge];
+ }
+ }
+
+ /// \brief The const subscript operator.
+ ///
+ /// The const subscript operator.
+ Value& operator[](const Key& edge) {
+ if (Parent::origEdge(edge)) {
+ return edge_map[edge];
+ } else {
+ return node_map[edge];
+ }
+ }
+
+ private:
+ GraphEdgeMap& edge_map;
+ GraphNodeMap& node_map;
+ };
+
+ /// \brief Just gives back a combined edge map.
+ ///
+ /// Just gives back a combined edge map.
+ template <typename GraphEdgeMap, typename GraphNodeMap>
+ static CombinedEdgeMap<GraphEdgeMap, GraphNodeMap>
+ combinedEdgeMap(GraphEdgeMap& edge_map, GraphNodeMap& node_map) {
+ return CombinedEdgeMap<GraphEdgeMap, GraphNodeMap>(edge_map, node_map);
+ }
+
+ template <typename GraphEdgeMap, typename GraphNodeMap>
+ static CombinedEdgeMap<const GraphEdgeMap, GraphNodeMap>
+ combinedEdgeMap(const GraphEdgeMap& edge_map, GraphNodeMap& node_map) {
+ return CombinedEdgeMap<const GraphEdgeMap,
+ GraphNodeMap>(edge_map, node_map);
+ }
+
+ template <typename GraphEdgeMap, typename GraphNodeMap>
+ static CombinedEdgeMap<GraphEdgeMap, const GraphNodeMap>
+ combinedEdgeMap(GraphEdgeMap& edge_map, const GraphNodeMap& node_map) {
+ return CombinedEdgeMap<GraphEdgeMap,
+ const GraphNodeMap>(edge_map, node_map);
+ }
+
+ template <typename GraphEdgeMap, typename GraphNodeMap>
+ static CombinedEdgeMap<const GraphEdgeMap, const GraphNodeMap>
+ combinedEdgeMap(const GraphEdgeMap& edge_map,
+ const GraphNodeMap& node_map) {
+ return CombinedEdgeMap<const GraphEdgeMap,
+ const GraphNodeMap>(edge_map, node_map);
+ }
+
+ };
-// };
} //namespace lemon
More information about the Lemon-commits
mailing list