1.1 --- a/Makefile.am Sat May 21 21:04:57 2005 +0000
1.2 +++ b/Makefile.am Mon May 23 04:48:14 2005 +0000
1.3 @@ -9,7 +9,10 @@
1.4 if WANT_DOCS
1.5 MAYBE_DOC = doc
1.6 endif
1.7 -SUBDIRS = src $(MAYBE_DOC)
1.8 +if WANT_GUI
1.9 + MAYBE_GUI = gui
1.10 +endif
1.11 +SUBDIRS = lemon benchmark demo test $(MAYBE_GUI) $(MAYBE_DOC)
1.12
1.13 MRPROPERFILES = \
1.14 aclocal.m4 \
1.15 @@ -26,19 +29,18 @@
1.16 config/mkinstalldirs \
1.17 doc/Makefile.in \
1.18 doc/doxygen.log \
1.19 - src/Makefile.in \
1.20 - src/lemon/Makefile.in \
1.21 - src/test/Makefile.in \
1.22 - src/benchmark/Makefile.in \
1.23 - src/demo/Makefile.in \
1.24 - src/gui/Makefile.in \
1.25 - src/gui/src/Makefile.in
1.26 + Makefile.in \
1.27 + lemon/Makefile.in \
1.28 + test/Makefile.in \
1.29 + benchmark/Makefile.in \
1.30 + demo/Makefile.in \
1.31 + gui/Makefile.in
1.32
1.33 docs:
1.34 $(MAKE) -C doc $(AM_MAKEFLAGS) clean html
1.35
1.36 benchmark:
1.37 - $(MAKE) -C src/benchmark $(AM_MAKEFLAGS)
1.38 + $(MAKE) -C benchmark $(AM_MAKEFLAGS)
1.39
1.40 mrproper:
1.41 $(MAKE) $(AM_MAKEFLAGS) maintainer-clean
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/benchmark/Makefile.am Mon May 23 04:48:14 2005 +0000
2.3 @@ -0,0 +1,11 @@
2.4 +AM_CPPFLAGS = -I$(top_srcdir)
2.5 +
2.6 +noinst_HEADERS = bench_tools.h
2.7 +
2.8 +noinst_PROGRAMS = graph-bench hcube bfs-bench
2.9 +
2.10 +graph_bench_SOURCES = graph-bench.cc
2.11 +
2.12 +hcube_SOURCES = hcube.cc
2.13 +
2.14 +bfs_bench_SOURCES = bfs-bench.cc
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/benchmark/bench_tools.h Mon May 23 04:48:14 2005 +0000
3.3 @@ -0,0 +1,128 @@
3.4 +// -*- mode:C++ -*-
3.5 +#ifndef LEMON_BENCH_TEST_H
3.6 +#define LEMON_BENCH_TEST_H
3.7 +
3.8 +#include<vector>
3.9 +#include<iostream>
3.10 +
3.11 +#include<lemon/time_measure.h>
3.12 +
3.13 +///An experimental typedef factory
3.14 +#define GRAPH_TYPEDEF_FACTORY(Graph) \
3.15 + typedef typename Graph:: Node Node;\
3.16 + typedef typename Graph:: NodeIt NodeIt;\
3.17 + typedef typename Graph:: Edge Edge;\
3.18 + typedef typename Graph:: EdgeIt EdgeIt;\
3.19 + typedef typename Graph:: InEdgeIt InEdgeIt;\
3.20 + typedef typename Graph::OutEdgeIt OutEdgeIt;
3.21 +
3.22 +#define GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph) \
3.23 + typedef Graph:: Node Node;\
3.24 + typedef Graph:: NodeIt NodeIt;\
3.25 + typedef Graph:: Edge Edge;\
3.26 + typedef Graph:: EdgeIt EdgeIt;\
3.27 + typedef Graph:: InEdgeIt InEdgeIt;\
3.28 + typedef Graph::OutEdgeIt OutEdgeIt;
3.29 +
3.30 +
3.31 +///A primitive primtest
3.32 +
3.33 +///\bug 2 is not a prime according to this function!
3.34 +///
3.35 +///\bug This function should go out of header file. I'm making it
3.36 +/// inline for now.
3.37 +inline bool isPrim(int n)
3.38 +{
3.39 + if(n%2) {
3.40 + for(int k=3;n/k>=k;k+=2)
3.41 + if(!(n%k)) return false;
3.42 + return true;
3.43 + }
3.44 + return false;
3.45 +}
3.46 +
3.47 +///Finds the smallest prime not less then \c n.
3.48 +
3.49 +///\bug This function should go out of header file. I'm making it
3.50 +/// inline for now.
3.51 +inline int nextPrim(int n)
3.52 +{
3.53 + for(n+=!(n%2);!isPrim(n);n+=2) ;
3.54 + return n;
3.55 +}
3.56 +
3.57 +
3.58 +/// Class to generate consecutive primes
3.59 +class Primes
3.60 +{
3.61 + std::vector<int> primes;
3.62 + int n;
3.63 +
3.64 + bool isPrime(int m)
3.65 + {
3.66 + for(int i=0;m<primes[i]*primes[i];i++) if(!(m%primes[i])) return false;
3.67 + return true;
3.68 + }
3.69 +public:
3.70 + Primes() : n(1) {}
3.71 +
3.72 + int operator() ()
3.73 + {
3.74 + if(primes.size()==0) {
3.75 + primes.push_back(2);
3.76 + return 2;
3.77 + }
3.78 + else {
3.79 + do n+=2; while(!isPrime(n));
3.80 + primes.push_back(n);
3.81 + return n;
3.82 + }
3.83 + }
3.84 +};
3.85 +
3.86 +inline void PrintTime(char *ID,lemon::Timer &T)
3.87 +{
3.88 + lemon::TimeStamp S(T);
3.89 + std::cout << ID << ' ' << S.getUserTime() << ' '
3.90 + << S.getSystemTime() << ' ' << S.getRealTime() << std::endl;
3.91 +}
3.92 +
3.93 +
3.94 +
3.95 +///
3.96 +template<class Graph>
3.97 +void addHiperCube(Graph &G,int dim,std::vector<typename Graph::Node> &nodes)
3.98 +{
3.99 + GRAPH_TYPEDEF_FACTORY(Graph);
3.100 +
3.101 + std::vector<int> bits(dim+1);
3.102 + bits[0]=1;
3.103 + for(int i=1;i<=dim;i++) bits[i]=2*bits[i-1];
3.104 +
3.105 + for(int i=0;i<bits[dim];i++) {
3.106 + nodes.push_back(G.addNode());
3.107 + for(int j=0;j<dim;j++) if(i&bits[j]) G.addEdge(nodes[i-bits[j]],nodes[i]);
3.108 + }
3.109 +}
3.110 +
3.111 +///
3.112 +template<class Graph>
3.113 +void addBiDirHiperCube(Graph &G,int dim,std::vector<typename Graph::Node>&nodes)
3.114 +{
3.115 + GRAPH_TYPEDEF_FACTORY(Graph);
3.116 +
3.117 + std::vector<int> bits(dim+1);
3.118 + bits[0]=1;
3.119 + for(int i=1;i<=dim;i++) bits[i]=2*bits[i-1];
3.120 +
3.121 + for(int i=0;i<bits[dim];i++) {
3.122 + nodes.push_back(G.addNode());
3.123 + for(int j=0;j<dim;j++) if(i&bits[j]) {
3.124 + G.addEdge(nodes[i-bits[j]],nodes[i]);
3.125 + G.addEdge(nodes[i],nodes[i-bits[j]]);
3.126 + }
3.127 +
3.128 + }
3.129 +}
3.130 +
3.131 +#endif
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/benchmark/benchmark Mon May 23 04:48:14 2005 +0000
4.3 @@ -0,0 +1,41 @@
4.4 +#!/bin/bash
4.5 +
4.6 +function runtest () # prefix, prog, args
4.7 +{
4.8 + echo $1 1>&2
4.9 + $2 $3 $4 $5 $6 $7 $8 $9 >/dev/null;
4.10 + for ((i=1;i<=3;i++))
4.11 + do
4.12 + $2 $3 $4 $5 $6 $7 $8 $9;
4.13 + done |
4.14 + awk '{print "'$1'",$0}'
4.15 +}
4.16 +
4.17 +function runalltest() #postfix, CXX, CXXFLAGS
4.18 +{
4.19 + echo $1 1>&2
4.20 + make clean >/dev/null
4.21 + make CXX="$2" CXXFLAGS="$3" >/dev/null
4.22 + {
4.23 + runtest HCUBE19 hcube 19
4.24 + runtest BFS13-5000 hcube 13 5000
4.25 + runtest BFS10-50000 hcube 10 50000
4.26 + runtest GRBENCH graph-bench
4.27 + } | awk "{print \$0, \"$1\"}"
4.28 +}
4.29 +
4.30 +runalltest "gcc-3.3 -O2" g++ "-O2"
4.31 +runalltest "gcc-3.3 -O2-march=pentium-m" g++ "-O2 -march=pentium-m"
4.32 +runalltest "gcc-3.3 -O3" g++ "-O3"
4.33 +runalltest "gcc-3.3 -O3-march=pentium-m" g++ "-O3 -march=pentium-m"
4.34 +
4.35 +runalltest "gcc-3.4 -O2" g++-3.4 "-O2"
4.36 +runalltest "gcc-3.4 -O2-march=pentium-m" g++-3.4 "-O2 -march=pentium-m"
4.37 +runalltest "gcc-3.4 -O3" g++-3.4 "-O3"
4.38 +runalltest "gcc-3.4 -O3-march=pentium-m" g++-3.4 "-O3 -march=pentium-m"
4.39 +
4.40 +runalltest "icc -O2" icc "-O2"
4.41 +runalltest "icc -O2-march=pentium-m" icc "-O2 -march=pentium-m"
4.42 +runalltest "icc -O3" icc "-O3"
4.43 +runalltest "icc -O3-march=pentium-m" icc "-O3 -march=pentium-m"
4.44 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/benchmark/bfs-bench.cc Mon May 23 04:48:14 2005 +0000
5.3 @@ -0,0 +1,144 @@
5.4 +// -*- mode:C++ -*-
5.5 +
5.6 +#include <queue>
5.7 +#include<math.h>
5.8 +#include<lemon/smart_graph.h>
5.9 +#include"bench_tools.h"
5.10 +
5.11 +using namespace std;
5.12 +using namespace lemon;
5.13 +
5.14 +inline int numOfOnes(int n,int dim)
5.15 +{
5.16 + int s=0;
5.17 + for(int i=0;i<dim;i++) {
5.18 + s+=n%2;
5.19 + n>>=1;
5.20 + }
5.21 + return s;
5.22 +}
5.23 +
5.24 +inline int numOfZeros(int n,int dim)
5.25 +{
5.26 + int s=dim;
5.27 + for(int i=0;i<dim;i++) {
5.28 + s-=n&1;
5.29 + n>>=1;
5.30 + }
5.31 + return s;
5.32 +}
5.33 +
5.34 +template<class Graph>
5.35 +void bfsStlQueue(Graph &G,typename Graph::Node source)
5.36 +{
5.37 + GRAPH_TYPEDEF_FACTORY(Graph);
5.38 +
5.39 + using namespace std;
5.40 +
5.41 + typename Graph::template NodeMap<bool> visited(G,false);
5.42 +
5.43 + queue<typename Graph::Node> Q;
5.44 +
5.45 + Q.push(source);
5.46 + visited[source]=true;
5.47 + do {
5.48 + Node n(Q.front());
5.49 + Node m;
5.50 + Q.pop();
5.51 + for(OutEdgeIt e(G,n);e!=INVALID;++e)
5.52 + if(!visited[m=G.target(e)]) {
5.53 + Q.push(m);
5.54 + visited.set(m,true);
5.55 + }
5.56 + } while(!Q.empty());
5.57 +}
5.58 +
5.59 +template<class Graph>
5.60 +void bfsOwnQueue(Graph &G,typename Graph::Node source)
5.61 +{
5.62 + GRAPH_TYPEDEF_FACTORY(Graph);
5.63 +
5.64 + using namespace std;
5.65 +
5.66 + typename Graph::template NodeMap<bool> visited(G,false);
5.67 +
5.68 + int N=G.nodeNum();
5.69 + vector<typename Graph::Node> Q(N);
5.70 + int Qh=0;
5.71 + int Qt=0;
5.72 +
5.73 +
5.74 + Q[Qh++]=source;
5.75 + visited.set(source,true);
5.76 + do {
5.77 + Node m;
5.78 + Node n=Q[Qt++];
5.79 + for(OutEdgeIt e(G,n);e!=INVALID;++e)
5.80 + if(!visited[m=G.target(e)]) {
5.81 + Q[Qh++]=m;
5.82 + visited.set(m,true);
5.83 + }
5.84 + } while(Qt!=Qh);
5.85 +}
5.86 +
5.87 +template<class Graph>
5.88 +void iteratorBench(Graph &G)
5.89 +{
5.90 + GRAPH_TYPEDEF_FACTORY(Graph);
5.91 +
5.92 + int i=0;
5.93 +
5.94 + for(NodeIt n(G);n!=INVALID;++n)
5.95 + for(OutEdgeIt e(G,n);e!=INVALID;++e)
5.96 + i++;
5.97 +}
5.98 +
5.99 +int main(int argc, char *argv[])
5.100 +{
5.101 + typedef SmartGraph Graph;
5.102 +
5.103 + ///\bug GRAPH_TYPEDEF_FACTORY(Graph);
5.104 + GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph);
5.105 +
5.106 + Graph G;
5.107 +
5.108 + Timer T;
5.109 +
5.110 + if(argc!=3) {
5.111 + cout << "Usage: " << argv[0] << " dim mul\n";
5.112 + return 1;
5.113 + }
5.114 +
5.115 + int dim=atoi(argv[1]);
5.116 + int mul=atoi(argv[2]);
5.117 +
5.118 +// cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
5.119 +// << dim*(1<<dim) << " edges):";
5.120 +
5.121 + T.reset();
5.122 + vector<Node> nodes;
5.123 + addBiDirHiperCube(G,dim,nodes);
5.124 +
5.125 + PrintTime("GENGRAPH",T);
5.126 +
5.127 + T.reset();
5.128 + {
5.129 + for(int i=0;i<mul;i++)
5.130 + bfsStlQueue(G,nodes[0]);
5.131 + }
5.132 + PrintTime("BFS-STL",T);
5.133 + T.reset();
5.134 + {
5.135 + for(int i=0;i<mul;i++)
5.136 + bfsOwnQueue(G,nodes[0]);
5.137 + }
5.138 + PrintTime("BFS-OWN",T);
5.139 + T.reset();
5.140 + {
5.141 + for(int i=0;i<mul;i++)
5.142 + iteratorBench(G);
5.143 + }
5.144 + PrintTime("ITERATE",T);
5.145 +
5.146 +
5.147 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/benchmark/graph-bench.cc Mon May 23 04:48:14 2005 +0000
6.3 @@ -0,0 +1,55 @@
6.4 +#include<lemon/list_graph.h>
6.5 +
6.6 +#include"bench_tools.h"
6.7 +
6.8 +using namespace lemon;
6.9 +
6.10 +///Makes a full graph by adding and deleting a lot of edges;
6.11 +
6.12 +///\param n Number of nodes.
6.13 +///\param rat The funcion will make \f$rat\timesn^2\f$ edge addition and
6.14 +///\f$(rat-1)\timesn^2\f$ deletion.
6.15 +///\param p Tuning parameters.
6.16 +///\warning \c rat, \c p, and \c n must be pairwise relative primes.
6.17 +template <class Graph>
6.18 +void makeFullGraph(int n, int rat, int p)
6.19 +{
6.20 + GRAPH_TYPEDEF_FACTORY(Graph);
6.21 +
6.22 + Graph G;
6.23 +
6.24 + // Node nodes[n];
6.25 + std::vector<Node> nodes(n);
6.26 + for(int i=0;i<n;i++) nodes[i]=G.addNode();
6.27 +
6.28 + //Edge equ[rat];
6.29 + std::vector<Edge> equ(rat);
6.30 +
6.31 + long long int count;
6.32 +
6.33 + for(count=0;count<rat;count++) {
6.34 + equ[count%rat]=G.addEdge(nodes[(count*p)%n],nodes[(count*p/n)%n]);
6.35 + }
6.36 + for(;(count%rat)||((count*p)%n)||((count*p/n)%n);count++) {
6.37 + // if(!(count%1000000)) fprintf(stderr,"%d\r",count);
6.38 + if(count%rat) G.erase(equ[count%rat]);
6.39 + equ[count%rat]=G.addEdge(nodes[(count*p)%n],nodes[(count*p/n)%n]);
6.40 + }
6.41 +// std::cout << "Added " << count
6.42 +// << " ( " << n << "^2 * " << rat << " ) edges\n";
6.43 +
6.44 +
6.45 + // for(int i=0;1;i++) ;
6.46 +}
6.47 +
6.48 +int main()
6.49 +{
6.50 + lemon::Timer T;
6.51 + makeFullGraph<ListGraph>(nextPrim(1000),nextPrim(300),nextPrim(100));
6.52 +
6.53 + PrintTime("BIG",T);
6.54 + T.reset();
6.55 + makeFullGraph<ListGraph>(nextPrim(100),nextPrim(30000),nextPrim(150));
6.56 +
6.57 + PrintTime("SMALL",T);
6.58 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/benchmark/hcube.cc Mon May 23 04:48:14 2005 +0000
7.3 @@ -0,0 +1,106 @@
7.4 +// -*- mode:C++ -*-
7.5 +
7.6 +#include<math.h>
7.7 +#include<lemon/list_graph.h>
7.8 +#include<lemon/smart_graph.h>
7.9 +#include<lemon/dijkstra.h>
7.10 +#include<lemon/preflow.h>
7.11 +
7.12 +#include"bench_tools.h"
7.13 +
7.14 +using namespace std;
7.15 +using namespace lemon;
7.16 +
7.17 +inline int numOfOnes(int n,int dim)
7.18 +{
7.19 + int s=0;
7.20 + for(int i=0;i<dim;i++) {
7.21 + s+=n%2;
7.22 + n>>=1;
7.23 + }
7.24 + return s;
7.25 +}
7.26 +
7.27 +inline int numOfZeros(int n,int dim)
7.28 +{
7.29 + int s=dim;
7.30 + for(int i=0;i<dim;i++) {
7.31 + s-=n&1;
7.32 + n>>=1;
7.33 + }
7.34 + return s;
7.35 +}
7.36 +
7.37 +int main(int argc, char *argv[])
7.38 +{
7.39 + // typedef ListGraph Graph;
7.40 + typedef SmartGraph Graph;
7.41 +
7.42 + ///\bug GRAPH_TYPEDEF_FACTORY(Graph);
7.43 + GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph);
7.44 +
7.45 + Graph G;
7.46 +
7.47 + Timer T;
7.48 +
7.49 + if(argc!=2) {
7.50 + cout << "Usage: " << argv[0] << " dim\n";
7.51 + return 1;
7.52 + }
7.53 +
7.54 + int dim=atoi(argv[1]);
7.55 +
7.56 +// cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
7.57 +// << dim*(1<<dim) << " edges):";
7.58 +
7.59 + T.reset();
7.60 + vector<Node> nodes;
7.61 + addBiDirHiperCube(G,dim,nodes);
7.62 +
7.63 + PrintTime("GENGRAPH",T);
7.64 +
7.65 + T.reset();
7.66 + Graph::EdgeMap<int> map(G);
7.67 + for(int i=0;i<5;i++) {
7.68 + Primes P;
7.69 + for(int i=0;i<dim*(1<<dim);i++) P();
7.70 +
7.71 + // for(EdgeIt e(G);G.valid(e);G.next(e)) map[e]=P();
7.72 +
7.73 + ///\todo It must have been commented out because of
7.74 + ///setToId
7.75 +// Edge te;
7.76 +// for(int i=0;i<dim*(1<<dim);i++) {
7.77 +// te.setToId(((long long int)(i)*93505)%(dim*(1<<dim)));
7.78 +// // map[Edge(((long long int)(i)*2987)%(dim*(1<<dim)))]=P();
7.79 +// map[te]=P();
7.80 +// }
7.81 +
7.82 +// for(int i=0;i<(1<<dim);i++) {
7.83 +// int mul= (1<<(numOfZeros(i,dim)/4));
7.84 +// for(OutEdgeIt e(G,nodes[i]);G.valid(e);G.next(e))
7.85 +// map[e]*=mul;
7.86 +// }
7.87 + }
7.88 +
7.89 + PrintTime("GENLENGTHS",T);
7.90 +
7.91 + T.reset();
7.92 + {
7.93 + Dijkstra<Graph> Dij(G,map);
7.94 + for(int i=0;i<10;i++)
7.95 + Dij.run(nodes[0]);
7.96 + }
7.97 + PrintTime("DIJKSTRA",T);
7.98 +
7.99 + T.reset();
7.100 + {
7.101 + Graph::EdgeMap<int> flow(G);
7.102 +
7.103 + Preflow<Graph,int> MF(G,nodes[0],nodes[1<<dim-1],map,flow);
7.104 + for(int i=0;i<10;i++)
7.105 + MF.run(MF.NO_FLOW);
7.106 + }
7.107 + PrintTime("PREFLOW",T);
7.108 +
7.109 +}
8.1 --- a/configure.ac Sat May 21 21:04:57 2005 +0000
8.2 +++ b/configure.ac Mon May 23 04:48:14 2005 +0000
8.3 @@ -2,8 +2,8 @@
8.4 AC_INIT([LEMON], [0.4], [etik-ol@cs.elte.hu], [lemon])
8.5 AC_CONFIG_AUX_DIR([config])
8.6 AM_INIT_AUTOMAKE
8.7 -AC_CONFIG_SRCDIR([src/lemon/invalid.h])
8.8 -AC_CONFIG_HEADERS([config.h src/lemon/config.h])
8.9 +AC_CONFIG_SRCDIR([lemon/invalid.h])
8.10 +AC_CONFIG_HEADERS([config.h lemon/config.h])
8.11 AC_PREREQ([2.53])
8.12
8.13 dnl Save user defined CXXFLAGS
8.14 @@ -51,13 +51,12 @@
8.15 autopackage/default.apspec
8.16 doc/Makefile
8.17 doc/Doxyfile
8.18 -src/Makefile
8.19 -src/lemon/Makefile
8.20 -src/lemon/lemon.pc
8.21 -src/benchmark/Makefile
8.22 -src/demo/Makefile
8.23 -src/test/Makefile
8.24 -src/gui/Makefile
8.25 +lemon/Makefile
8.26 +lemon/lemon.pc
8.27 +benchmark/Makefile
8.28 +demo/Makefile
8.29 +test/Makefile
8.30 +gui/Makefile
8.31 ])
8.32
8.33 AC_OUTPUT
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/demo/Makefile.am Mon May 23 04:48:14 2005 +0000
9.3 @@ -0,0 +1,41 @@
9.4 +AM_CPPFLAGS = -I$(top_srcdir)
9.5 +LDADD = $(top_builddir)/lemon/libemon.la
9.6 +
9.7 +EXTRA_DIST = sub_graph_adaptor_demo.dim
9.8 +
9.9 +noinst_PROGRAMS = \
9.10 + dim_to_dot \
9.11 + dim_to_lgf \
9.12 + graph_to_eps_demo \
9.13 + min_route \
9.14 + sub_graph_adaptor_demo \
9.15 + coloring
9.16 +
9.17 +if HAVE_GLPK
9.18 +noinst_PROGRAMS += lp_demo lp_maxflow_demo
9.19 +else !HAVE_GLPK
9.20 +if HAVE_CPLEX
9.21 +noinst_PROGRAMS += lp_demo lp_maxflow_demo
9.22 +endif HAVE_CPLEX
9.23 +endif !HAVE_GLPK
9.24 +
9.25 +
9.26 +dim_to_dot_SOURCES = dim_to_dot.cc
9.27 +
9.28 +dim_to_lgf_SOURCES = dim_to_lgf.cc
9.29 +
9.30 +coloring_SOURCES = coloring.cc
9.31 +
9.32 +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
9.33 +
9.34 +min_route_SOURCES = min_route.cc
9.35 +
9.36 +sub_graph_adaptor_demo_SOURCES = \
9.37 + sub_graph_adaptor_demo.cc \
9.38 + tight_edge_filter_map.h
9.39 +
9.40 +lp_demo_SOURCES = lp_demo.cc
9.41 +lp_demo_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
9.42 +
9.43 +lp_maxflow_demo_SOURCES = lp_maxflow_demo.cc
9.44 +lp_maxflow_demo_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/demo/coloring.cc Mon May 23 04:48:14 2005 +0000
10.3 @@ -0,0 +1,71 @@
10.4 +#include <vector>
10.5 +
10.6 +#include <lemon/smart_graph.h>
10.7 +#include <lemon/bin_heap.h>
10.8 +#include <lemon/graph_reader.h>
10.9 +#include <lemon/graph_to_eps.h>
10.10 +
10.11 +using namespace std;
10.12 +using namespace lemon;
10.13 +
10.14 +int main() {
10.15 + typedef UndirSmartGraph Graph;
10.16 + typedef Graph::Node Node;
10.17 + typedef Graph::NodeIt NodeIt;
10.18 + typedef Graph::UndirEdge UndirEdge;
10.19 + typedef Graph::IncEdgeIt IncEdgeIt;
10.20 +
10.21 + Graph graph;
10.22 +
10.23 + UndirGraphReader<Graph> reader(std::cin, graph);
10.24 + Graph::NodeMap<xy<double> > coords(graph);
10.25 + reader.readNodeMap("coords", coords);
10.26 +
10.27 + reader.run();
10.28 +
10.29 + Graph::NodeMap<int> color(graph, -2);
10.30 +
10.31 + Graph::NodeMap<int> heapMap(graph, -1);
10.32 + BinHeap<Node, int, Graph::NodeMap<int> > heap(heapMap);
10.33 +
10.34 + for (NodeIt it(graph); it != INVALID; ++it) {
10.35 + heap.push(it, countOutEdges(graph, it));
10.36 + }
10.37 +
10.38 + vector<Node> order;
10.39 +
10.40 + while (!heap.empty()) {
10.41 + Node node = heap.top();
10.42 + heap.pop();
10.43 + color[node] = -1;
10.44 + order.push_back(node);
10.45 + for (IncEdgeIt it(graph, node); it != INVALID; ++it) {
10.46 + Node target = graph.runningNode(it);
10.47 + if (color[target] == -2) {
10.48 + heap.decrease(target, heap[target] - 1);
10.49 + }
10.50 + }
10.51 + }
10.52 +
10.53 + for (int i = order.size() - 1; i >= 0; --i) {
10.54 + set<int> forbidden;
10.55 + for (IncEdgeIt it(graph, order[i]); it != INVALID; ++it) {
10.56 + Node target = graph.runningNode(it);
10.57 + if (color[target] != -1) {
10.58 + forbidden.insert(color[target]);
10.59 + }
10.60 + }
10.61 + int current = 0;
10.62 + while (forbidden.find(current) != forbidden.end()) ++current;
10.63 + color[order[i]] = current;
10.64 + }
10.65 +
10.66 + ColorSet colorSet;
10.67 +
10.68 + graphToEps(graph, "six_coloring.eps").
10.69 + title("Six Colored Graph").copyright("(C) 2005 LEMON Project").
10.70 + coords(coords).nodeColors(composeMap(colorSet, color)).
10.71 + scaleToA4().run();
10.72 +
10.73 + return 0;
10.74 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/demo/dijkstra_demo.cc Mon May 23 04:48:14 2005 +0000
11.3 @@ -0,0 +1,75 @@
11.4 +#include <iostream>
11.5 +
11.6 +#include <lemon/list_graph.h>
11.7 +#include <lemon/dijkstra.h>
11.8 +
11.9 +using namespace lemon;
11.10 +
11.11 +
11.12 +int main (int, char*[])
11.13 +{
11.14 +
11.15 + typedef ListGraph Graph;
11.16 + typedef Graph::Node Node;
11.17 + typedef Graph::Edge Edge;
11.18 + typedef Graph::EdgeMap<int> LengthMap;
11.19 +
11.20 + Graph g;
11.21 +
11.22 + //An example from Ahuja's book
11.23 +
11.24 + Node s=g.addNode();
11.25 + Node v2=g.addNode();
11.26 + Node v3=g.addNode();
11.27 + Node v4=g.addNode();
11.28 + Node v5=g.addNode();
11.29 + Node t=g.addNode();
11.30 +
11.31 + Edge s_v2=g.addEdge(s, v2);
11.32 + Edge s_v3=g.addEdge(s, v3);
11.33 + Edge v2_v4=g.addEdge(v2, v4);
11.34 + Edge v2_v5=g.addEdge(v2, v5);
11.35 + Edge v3_v5=g.addEdge(v3, v5);
11.36 + Edge v4_t=g.addEdge(v4, t);
11.37 + Edge v5_t=g.addEdge(v5, t);
11.38 +
11.39 + LengthMap len(g);
11.40 +
11.41 + len.set(s_v2, 10);
11.42 + len.set(s_v3, 10);
11.43 + len.set(v2_v4, 5);
11.44 + len.set(v2_v5, 8);
11.45 + len.set(v3_v5, 5);
11.46 + len.set(v4_t, 8);
11.47 + len.set(v5_t, 8);
11.48 +
11.49 + std::cout << "The id of s is " << g.id(s)<< ", the id of t is " << g.id(t)<<"."<<std::endl;
11.50 +
11.51 + std::cout << "Dijkstra algorithm test..." << std::endl;
11.52 +
11.53 + Dijkstra<Graph, LengthMap> dijkstra_test(g,len);
11.54 +
11.55 + dijkstra_test.run(s);
11.56 +
11.57 +
11.58 + std::cout << "The distance of node t from node s: " << dijkstra_test.dist(t)<<std::endl;
11.59 +
11.60 + std::cout << "The shortest path from s to t goes through the following nodes (the first one is t, the last one is s): "<<std::endl;
11.61 +
11.62 + for (Node v=t;v != s; v=dijkstra_test.predNode(v)){
11.63 + std::cout << g.id(v) << "<-";
11.64 + }
11.65 + std::cout << g.id(s) << std::endl;
11.66 +
11.67 +
11.68 + return 0;
11.69 +}
11.70 +
11.71 +
11.72 +
11.73 +
11.74 +
11.75 +
11.76 +
11.77 +
11.78 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/demo/dim_to_dot.cc Mon May 23 04:48:14 2005 +0000
12.3 @@ -0,0 +1,59 @@
12.4 +// -*- c++ -*-
12.5 +
12.6 +// Use a DIMACS max flow file as stdin.
12.7 +// dim_to_dot < dimacs_max_flow_file > dot_output_file
12.8 +// This program makes a dot file from a dimacs max flow file.
12.9 +// This program can be an aid in making up to date visualized documantation
12.10 +// of demo programs.
12.11 +
12.12 +#include <iostream>
12.13 +#include <fstream>
12.14 +
12.15 +#include <lemon/smart_graph.h>
12.16 +#include <lemon/dimacs.h>
12.17 +
12.18 +using namespace lemon;
12.19 +
12.20 +using std::cout;
12.21 +using std::endl;
12.22 +
12.23 +int main()
12.24 +{
12.25 + typedef SmartGraph Graph;
12.26 +
12.27 + typedef Graph::Edge Edge;
12.28 + typedef Graph::Node Node;
12.29 + typedef Graph::EdgeIt EdgeIt;
12.30 + typedef Graph::NodeIt NodeIt;
12.31 + typedef Graph::EdgeMap<int> LengthMap;
12.32 +
12.33 + Graph g;
12.34 + Node s, t;
12.35 + LengthMap length(g);
12.36 +
12.37 + readDimacs(std::cin, g, length, s, t);
12.38 +
12.39 + cout << "digraph lemon_dot_example {" << endl;
12.40 + cout << " node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
12.41 + for(NodeIt n(g); n!=INVALID; ++n) {
12.42 + if (n==s) {
12.43 + cout << " n" << g.id(n)
12.44 + << " [ label=\"" << g.id(n) << " (s)\" ]; " << endl;
12.45 + } else {
12.46 + if (n==t) {
12.47 + cout << " n" << g.id(n)
12.48 + << " [ label=\"" << g.id(n) << " (t)\" ]; " << endl;
12.49 + } else {
12.50 + cout << " n" << g.id(n)
12.51 + << " [ label=\"" << g.id(n) << "\" ]; " << endl;
12.52 + }
12.53 + }
12.54 + }
12.55 + cout << " edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
12.56 + for(EdgeIt e(g); e!=INVALID; ++e) {
12.57 + cout << " n" << g.id(g.source(e)) << " -> " << " n" << g.id(g.target(e))
12.58 + << " [ label=\"" << g.id(e)
12.59 + << ", length:" << length[e] << "\" ]; " << endl;
12.60 + }
12.61 + cout << "}" << endl;
12.62 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/demo/dim_to_lgf.cc Mon May 23 04:48:14 2005 +0000
13.3 @@ -0,0 +1,166 @@
13.4 +#include <iostream>
13.5 +#include <fstream>
13.6 +#include <cstring>
13.7 +
13.8 +#include <lemon/smart_graph.h>
13.9 +#include <lemon/dimacs.h>
13.10 +#include <lemon/graph_writer.h>
13.11 +
13.12 +using namespace std;
13.13 +using namespace lemon;
13.14 +
13.15 +const char* versionString =
13.16 +"dim_to_lgf - part of lemon library\n";
13.17 +
13.18 +const char* helpString =
13.19 +"Dimacs to LGF converter\n"
13.20 +"Usage: dim_to_lgf [OPTIONS]\n"
13.21 +"\n"
13.22 +"Examples:\n"
13.23 +" dim_to_lgf --type shortestpath --input graph.dim --output graph.lgf\n"
13.24 +"\n"
13.25 +"Options:\n"
13.26 +" -i FILE, --input FILE use FILE as input instead of standard input\n"
13.27 +" -o FILE, --output FILE use FILE as output instead of standard output\n"
13.28 +" -t TYPE, --type TYPE set up the type of the graph\n"
13.29 +" Possible types:\n"
13.30 +" mincostflow\n"
13.31 +" maxflow (default)\n"
13.32 +" shortestpath\n"
13.33 +" capacitated\n"
13.34 +" plain\n"
13.35 +" -v, --version shows the version of the converter\n"
13.36 +" -h, --help shows the help of the converter\n";
13.37 +
13.38 +
13.39 +int main(int argc, const char *argv[]) {
13.40 + typedef SmartGraph Graph;
13.41 +
13.42 + typedef Graph::Edge Edge;
13.43 + typedef Graph::Node Node;
13.44 + typedef Graph::EdgeIt EdgeIt;
13.45 + typedef Graph::NodeIt NodeIt;
13.46 + typedef Graph::EdgeMap<string> StringMap;
13.47 +
13.48 + std::string inputName;
13.49 + std::string outputName;
13.50 + std::string typeName;
13.51 +
13.52 + bool help = false;
13.53 + bool version = false;
13.54 +
13.55 + for (int arg = 1; arg < argc; ++arg) {
13.56 + if (strcmp(argv[arg], "--type") == 0 ||
13.57 + strcmp(argv[arg], "-t") == 0) {
13.58 + if (!typeName.empty()) {
13.59 + cerr << "Multiple type description" << endl;
13.60 + return -1;
13.61 + }
13.62 + if (arg + 1 == argc) {
13.63 + cerr << "Parameter without value" << endl;
13.64 + return -1;
13.65 + }
13.66 + typeName = argv[++arg];
13.67 + }
13.68 + else if (strcmp(argv[arg], "--input") == 0 ||
13.69 + strcmp(argv[arg], "-i") == 0) {
13.70 + if (!inputName.empty()) {
13.71 + cerr << "Multiple input description" << endl;
13.72 + return -1;
13.73 + }
13.74 + if (arg + 1 == argc) {
13.75 + cerr << "Parameter without value" << endl;
13.76 + return -1;
13.77 + }
13.78 + inputName = argv[++arg];
13.79 + }
13.80 + else if (strcmp(argv[arg], "--output") == 0 ||
13.81 + strcmp(argv[arg], "-o") == 0) {
13.82 + if (!outputName.empty()) {
13.83 + cerr << "Multiple input description" << endl;
13.84 + return -1;
13.85 + }
13.86 + if (arg + 1 == argc) {
13.87 + cerr << "Parameter without value" << endl;
13.88 + return -1;
13.89 + }
13.90 + outputName = argv[++arg];
13.91 + } else if (strcmp(argv[arg], "--help") == 0 ||
13.92 + strcmp(argv[arg], "-h") == 0) {
13.93 + help = true;
13.94 + } else if (strcmp(argv[arg], "--version") == 0 ||
13.95 + strcmp(argv[arg], "-v") == 0) {
13.96 + version = true;
13.97 + } else {
13.98 + cerr << "Invalid option: " << argv[arg] << endl;
13.99 + return -1;
13.100 + }
13.101 + }
13.102 +
13.103 + if (version) {
13.104 + cout << versionString;
13.105 + }
13.106 + if (help) {
13.107 + cout << helpString;
13.108 + }
13.109 + if (help || version) {
13.110 + return 0;
13.111 + }
13.112 +
13.113 + ifstream input;
13.114 + if (!inputName.empty()) {
13.115 + input.open(inputName.c_str());
13.116 + if (!input) {
13.117 + cerr << "File open error" << endl;
13.118 + return -1;
13.119 + }
13.120 + }
13.121 + istream& is = (inputName.empty() ? cin : input);
13.122 +
13.123 + ofstream output;
13.124 + if (!outputName.empty()) {
13.125 + output.open(outputName.c_str());
13.126 + if (!output) {
13.127 + cerr << "File open error" << endl;
13.128 + return -1;
13.129 + }
13.130 + }
13.131 + ostream& os = (outputName.empty() ? cout : output);
13.132 +
13.133 + if (typeName.empty()) {
13.134 + typeName = "maxflow";
13.135 + }
13.136 +
13.137 + if (typeName == "mincostflow") {
13.138 + Graph graph;
13.139 + Node s, t;
13.140 + StringMap cost(graph), capacity(graph);
13.141 + readDimacs(is, graph, capacity, s, t, cost);
13.142 + writeGraph(os, graph, capacity, s, t, cost);
13.143 + } else if (typeName == "maxflow") {
13.144 + Graph graph;
13.145 + Node s, t;
13.146 + StringMap capacity(graph);
13.147 + readDimacs(is, graph, capacity, s, t);
13.148 + writeGraph(os, graph, capacity, s, t);
13.149 + } else if (typeName == "shortestpath") {
13.150 + Graph graph;
13.151 + Node s;
13.152 + StringMap capacity(graph);
13.153 + readDimacs(is, graph, capacity, s);
13.154 + writeGraph(os, graph, capacity, s);
13.155 + } else if (typeName == "capacitated") {
13.156 + Graph graph;
13.157 + StringMap capacity(graph);
13.158 + readDimacs(is, graph, capacity);
13.159 + writeGraph(os, graph, capacity);
13.160 + } else if (typeName == "plain") {
13.161 + Graph graph;
13.162 + readDimacs(is, graph);
13.163 + writeGraph(os, graph);
13.164 + } else {
13.165 + cerr << "Invalid type error" << endl;
13.166 + return -1;
13.167 + }
13.168 + return 0;
13.169 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/demo/graph_to_eps_demo.cc Mon May 23 04:48:14 2005 +0000
14.3 @@ -0,0 +1,168 @@
14.4 +/* -*- C++ -*-
14.5 + * demo/graph_to_eps.cc - Part of LEMON, a generic C++ optimization library
14.6 + *
14.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
14.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
14.9 + *
14.10 + * Permission to use, modify and distribute this software is granted
14.11 + * provided that this copyright notice appears in all copies. For
14.12 + * precise terms see the accompanying LICENSE file.
14.13 + *
14.14 + * This software is provided "AS IS" with no warranty of any kind,
14.15 + * express or implied, and with no claim as to its suitability for any
14.16 + * purpose.
14.17 + *
14.18 + */
14.19 +
14.20 +#include<lemon/graph_to_eps.h>
14.21 +#include<lemon/maps.h>
14.22 +#include<lemon/list_graph.h>
14.23 +#include<lemon/graph_utils.h>
14.24 +
14.25 +#include <cmath>
14.26 +
14.27 +
14.28 +using namespace std;
14.29 +using namespace lemon;
14.30 +
14.31 +int main()
14.32 +{
14.33 + ColorSet colorSet;
14.34 +
14.35 + ListGraph g;
14.36 + typedef ListGraph::Node Node;
14.37 + typedef ListGraph::NodeIt NodeIt;
14.38 + typedef ListGraph::Edge Edge;
14.39 + typedef xy<int> Xy;
14.40 +
14.41 + Node n1=g.addNode();
14.42 + Node n2=g.addNode();
14.43 + Node n3=g.addNode();
14.44 + Node n4=g.addNode();
14.45 + Node n5=g.addNode();
14.46 +
14.47 + ListGraph::NodeMap<Xy> coords(g);
14.48 + ListGraph::NodeMap<double> sizes(g);
14.49 + ListGraph::NodeMap<int> colors(g);
14.50 + ListGraph::NodeMap<int> shapes(g);
14.51 + ListGraph::EdgeMap<int> ecolors(g);
14.52 + ListGraph::EdgeMap<int> widths(g);
14.53 +
14.54 + coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
14.55 + coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
14.56 + coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
14.57 + coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
14.58 + coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
14.59 +
14.60 + Edge e;
14.61 +
14.62 + e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
14.63 + e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
14.64 + e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
14.65 + e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
14.66 + e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
14.67 + e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
14.68 + e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
14.69 +
14.70 + IdMap<ListGraph,Node> id(g);
14.71 +
14.72 + graphToEps(g,"graph_to_eps_demo_out.eps").scale(10).coords(coords).
14.73 + title("Sample .eps figure").
14.74 + copyright("(C) 2005 LEMON Project").
14.75 + nodeScale(2).nodeSizes(sizes).
14.76 + nodeShapes(shapes).
14.77 + nodeColors(composeMap(colorSet,colors)).
14.78 + edgeColors(composeMap(colorSet,ecolors)).
14.79 + edgeWidthScale(.4).edgeWidths(widths).
14.80 + nodeTexts(id).nodeTextSize(3).
14.81 + run();
14.82 +
14.83 + graphToEps(g,"graph_to_eps_demo_out_arr.eps").scale(10).
14.84 + title("Sample .eps figure (with arrowheads)").
14.85 + copyright("(C) 2005 LEMON Project").
14.86 + nodeColors(composeMap(colorSet,colors)).
14.87 + coords(coords).
14.88 + nodeScale(2).nodeSizes(sizes).
14.89 + nodeShapes(shapes).
14.90 + edgeColors(composeMap(colorSet,ecolors)).
14.91 + edgeWidthScale(.4).edgeWidths(widths).
14.92 + nodeTexts(id).nodeTextSize(3).
14.93 + drawArrows().arrowWidth(1).arrowLength(1).
14.94 + run();
14.95 +
14.96 + e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
14.97 + e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
14.98 +
14.99 + e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
14.100 + e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
14.101 + e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
14.102 + e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
14.103 + e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
14.104 + e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
14.105 + e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
14.106 +
14.107 + graphToEps(g,"graph_to_eps_demo_out_par.eps").scale(10).
14.108 + title("Sample .eps figure (parallel edges)").
14.109 + copyright("(C) 2005 LEMON Project").
14.110 + nodeShapes(shapes).
14.111 + coords(coords).
14.112 + nodeScale(2).nodeSizes(sizes).
14.113 + nodeColors(composeMap(colorSet,colors)).
14.114 + edgeColors(composeMap(colorSet,ecolors)).
14.115 + edgeWidthScale(.4).edgeWidths(widths).
14.116 + nodeTexts(id).nodeTextSize(3).
14.117 + enableParallel().parEdgeDist(1.5).
14.118 + run();
14.119 +
14.120 + graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").scale(10).
14.121 + title("Sample .eps figure (parallel edges and arrowheads)").
14.122 + copyright("(C) 2005 LEMON Project").
14.123 + nodeScale(2).nodeSizes(sizes).
14.124 + coords(coords).
14.125 + nodeShapes(shapes).
14.126 + nodeColors(composeMap(colorSet,colors)).
14.127 + edgeColors(composeMap(colorSet,ecolors)).
14.128 + edgeWidthScale(.3).edgeWidths(widths).
14.129 + nodeTexts(id).nodeTextSize(3).
14.130 + enableParallel().parEdgeDist(1).
14.131 + drawArrows().arrowWidth(1).arrowLength(1).
14.132 + run();
14.133 +
14.134 + graphToEps(g,"graph_to_eps_demo_out_a4.eps").scaleToA4().
14.135 + title("Sample .eps figure (fits to A4)").
14.136 + copyright("(C) 2005 LEMON Project").
14.137 + nodeScale(2).nodeSizes(sizes).
14.138 + coords(coords).
14.139 + nodeShapes(shapes).
14.140 + nodeColors(composeMap(colorSet,colors)).
14.141 + edgeColors(composeMap(colorSet,ecolors)).
14.142 + edgeWidthScale(.3).edgeWidths(widths).
14.143 + nodeTexts(id).nodeTextSize(3).
14.144 + enableParallel().parEdgeDist(1).
14.145 + drawArrows().arrowWidth(1).arrowLength(1).
14.146 + run();
14.147 +
14.148 + ListGraph h;
14.149 + ListGraph::NodeMap<int> hcolors(h);
14.150 + ListGraph::NodeMap<Xy> hcoords(h);
14.151 +
14.152 + int cols=int(sqrt(double(colorSet.size())));
14.153 + for(int i=0;i<int(colorSet.size());i++) {
14.154 + Node n=h.addNode();
14.155 + hcoords[n]=Xy(i%cols,i/cols);
14.156 + hcolors[n]=i;
14.157 + }
14.158 +
14.159 + graphToEps(h,"graph_to_eps_demo_out_colors.eps").scale(60).
14.160 + title("Sample .eps figure (parallel edges and arrowheads)").
14.161 + copyright("(C) 2005 LEMON Project").
14.162 + coords(hcoords).
14.163 + nodeScale(.45).
14.164 + distantColorNodeTexts().
14.165 + // distantBWNodeTexts().
14.166 + nodeTexts(hcolors).nodeTextSize(.6).
14.167 + nodeColors(composeMap(colorSet,hcolors)).
14.168 + run();
14.169 +
14.170 +
14.171 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/demo/helloworld.cc Mon May 23 04:48:14 2005 +0000
15.3 @@ -0,0 +1,34 @@
15.4 +#include <iostream>
15.5 +#include <lemon/list_graph.h>
15.6 +
15.7 +using namespace lemon;
15.8 +
15.9 +int main()
15.10 +{
15.11 + typedef ListGraph Graph;
15.12 + typedef Graph::Edge Edge;
15.13 + typedef Graph::InEdgeIt InEdgeIt;
15.14 + typedef Graph::OutEdgeIt OutEdgeIt;
15.15 + typedef Graph::EdgeIt EdgeIt;
15.16 + typedef Graph::Node Node;
15.17 + typedef Graph::NodeIt NodeIt;
15.18 +
15.19 + Graph g;
15.20 +
15.21 + for (int i = 0; i < 3; i++)
15.22 + g.addNode();
15.23 +
15.24 + for (NodeIt i(g); i!=INVALID; ++i)
15.25 + for (NodeIt j(g); j!=INVALID; ++j)
15.26 + if (i != j) g.addEdge(i, j);
15.27 +
15.28 + std::cout << "Nodes:";
15.29 + for (NodeIt i(g); i!=INVALID; ++i)
15.30 + std::cout << " " << g.id(i);
15.31 + std::cout << std::endl;
15.32 +
15.33 + std::cout << "Edges:";
15.34 + for (EdgeIt i(g); i!=INVALID; ++i)
15.35 + std::cout << " (" << g.id(g.source(i)) << "," << g.id(g.target(i)) << ")";
15.36 + std::cout << std::endl;
15.37 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/demo/kruskal_demo.cc Mon May 23 04:48:14 2005 +0000
16.3 @@ -0,0 +1,95 @@
16.4 +#include <iostream>
16.5 +#include <vector>
16.6 +
16.7 +#include <lemon/maps.h>
16.8 +#include <lemon/kruskal.h>
16.9 +#include <lemon/list_graph.h>
16.10 +
16.11 +
16.12 +using namespace std;
16.13 +using namespace lemon;
16.14 +
16.15 +
16.16 +int main() {
16.17 +
16.18 + typedef ListGraph::Node Node;
16.19 + typedef ListGraph::Edge Edge;
16.20 + typedef ListGraph::NodeIt NodeIt;
16.21 + typedef ListGraph::EdgeIt EdgeIt;
16.22 +
16.23 + ListGraph G;
16.24 +
16.25 + Node s=G.addNode();
16.26 + Node v1=G.addNode();
16.27 + Node v2=G.addNode();
16.28 + Node v3=G.addNode();
16.29 + Node v4=G.addNode();
16.30 + Node t=G.addNode();
16.31 +
16.32 + Edge e1 = G.addEdge(s, v1);
16.33 + Edge e2 = G.addEdge(s, v2);
16.34 + Edge e3 = G.addEdge(v1, v2);
16.35 + Edge e4 = G.addEdge(v2, v1);
16.36 + Edge e5 = G.addEdge(v1, v3);
16.37 + Edge e6 = G.addEdge(v3, v2);
16.38 + Edge e7 = G.addEdge(v2, v4);
16.39 + Edge e8 = G.addEdge(v4, v3);
16.40 + Edge e9 = G.addEdge(v3, t);
16.41 + Edge e10 = G.addEdge(v4, t);
16.42 +
16.43 + typedef ListGraph::EdgeMap<int> ECostMap;
16.44 + typedef ListGraph::EdgeMap<bool> EBoolMap;
16.45 +
16.46 + ECostMap edge_cost_map(G, 2);
16.47 + EBoolMap tree_map(G);
16.48 +
16.49 +
16.50 + //Test with const map.
16.51 + std::cout << "The weight of the minimum spanning tree is " << kruskalEdgeMap(G, ConstMap<ListGraph::Edge,int>(2), tree_map)<<std::endl;
16.52 +
16.53 +/*
16.54 + ==10,
16.55 + "Total cost should be 10");
16.56 + //Test with a edge map (filled with uniform costs).
16.57 + check(kruskalEdgeMap(G, edge_cost_map, tree_map)==10,
16.58 + "Total cost should be 10");
16.59 +
16.60 + edge_cost_map.set(e1, -10);
16.61 + edge_cost_map.set(e2, -9);
16.62 + edge_cost_map.set(e3, -8);
16.63 + edge_cost_map.set(e4, -7);
16.64 + edge_cost_map.set(e5, -6);
16.65 + edge_cost_map.set(e6, -5);
16.66 + edge_cost_map.set(e7, -4);
16.67 + edge_cost_map.set(e8, -3);
16.68 + edge_cost_map.set(e9, -2);
16.69 + edge_cost_map.set(e10, -1);
16.70 +
16.71 + vector<Edge> tree_edge_vec;
16.72 +
16.73 + //Test with a edge map and inserter.
16.74 + check(kruskalEdgeMap_IteratorOut(G, edge_cost_map,
16.75 + back_inserter(tree_edge_vec))
16.76 + ==-31,
16.77 + "Total cost should be -31.");
16.78 +
16.79 + tree_edge_vec.clear();
16.80 +
16.81 + //The above test could also be coded like this:
16.82 + check(kruskal(G,
16.83 + makeKruskalMapInput(G, edge_cost_map),
16.84 + makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
16.85 + ==-31,
16.86 + "Total cost should be -31.");
16.87 +
16.88 + check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
16.89 +
16.90 + check(tree_edge_vec[0]==e1 &&
16.91 + tree_edge_vec[1]==e2 &&
16.92 + tree_edge_vec[2]==e5 &&
16.93 + tree_edge_vec[3]==e7 &&
16.94 + tree_edge_vec[4]==e9,
16.95 + "Wrong tree.");
16.96 +*/
16.97 + return 0;
16.98 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/demo/lp_demo.cc Mon May 23 04:48:14 2005 +0000
17.3 @@ -0,0 +1,113 @@
17.4 +#ifdef HAVE_CONFIG_H
17.5 +#include <config.h>
17.6 +#endif
17.7 +
17.8 +#include <iostream>
17.9 +
17.10 +
17.11 +#ifdef HAVE_GLPK
17.12 +#include <lemon/lp_glpk.h>
17.13 +#elif HAVE_CPLEX
17.14 +#include <lemon/lp_cplex.h>
17.15 +#endif
17.16 +
17.17 +using namespace lemon;
17.18 +
17.19 +#ifdef HAVE_GLPK
17.20 +typedef LpGlpk LpDefault;
17.21 +#elif HAVE_CPLEX
17.22 +typedef LpCplex LpDefault;
17.23 +#endif
17.24 +
17.25 +int main()
17.26 +{
17.27 + //The following example is taken from the documentation of the GLPK library.
17.28 + //See it in the GLPK reference manual and among the GLPK sample files (sample.c)
17.29 + LpDefault lp;
17.30 + typedef LpDefault::Row Row;
17.31 + typedef LpDefault::Col Col;
17.32 +
17.33 + lp.max();
17.34 +
17.35 + Col x1 = lp.addCol();
17.36 + Col x2 = lp.addCol();
17.37 + Col x3 = lp.addCol();
17.38 +
17.39 + //One solution
17.40 + // Row p = lp.addRow();
17.41 + // Row q = lp.addRow();
17.42 + // Row r = lp.addRow();
17.43 + // lp.setRow(p,x1+x2+x3 <=100);
17.44 + // lp.setRow(q,10*x1+4*x2+5*x3<=600);
17.45 + // lp.setRow(r,2*x1+2*x2+6*x3<=300);
17.46 +
17.47 + //A more elegant one
17.48 + //Constraints
17.49 + lp.addRow(x1+x2+x3 <=100);
17.50 + lp.addRow(10*x1+4*x2+5*x3<=600);
17.51 + lp.addRow(2*x1+2*x2+6*x3<=300);
17.52 + //Nonnegativity of the variables
17.53 + lp.colLowerBound(x1, 0);
17.54 + lp.colLowerBound(x2, 0);
17.55 + lp.colLowerBound(x3, 0);
17.56 + //Objective function
17.57 + lp.setObj(10*x1+6*x2+4*x3);
17.58 +
17.59 + lp.solve();
17.60 +
17.61 + if (lp.primalStatus()==LpSolverBase::OPTIMAL){
17.62 + printf("Z = %g; x1 = %g; x2 = %g; x3 = %g\n",
17.63 + lp.primalValue(),
17.64 + lp.primal(x1), lp.primal(x2), lp.primal(x3));
17.65 + }
17.66 + else{
17.67 + std::cout<<"Optimal solution not found!"<<std::endl;
17.68 + }
17.69 +
17.70 +
17.71 + //Here comes the same problem written in C using GLPK API routines
17.72 +
17.73 +// LPX *lp;
17.74 +// int ia[1+1000], ja[1+1000];
17.75 +// double ar[1+1000], Z, x1, x2, x3;
17.76 +// s1: lp = lpx_create_prob();
17.77 +// s2: lpx_set_prob_name(lp, "sample");
17.78 +// s3: lpx_set_obj_dir(lp, LPX_MAX);
17.79 +// s4: lpx_add_rows(lp, 3);
17.80 +// s5: lpx_set_row_name(lp, 1, "p");
17.81 +// s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0);
17.82 +// s7: lpx_set_row_name(lp, 2, "q");
17.83 +// s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0);
17.84 +// s9: lpx_set_row_name(lp, 3, "r");
17.85 +// s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0);
17.86 +// s11: lpx_add_cols(lp, 3);
17.87 +// s12: lpx_set_col_name(lp, 1, "x1");
17.88 +// s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0);
17.89 +// s14: lpx_set_obj_coef(lp, 1, 10.0);
17.90 +// s15: lpx_set_col_name(lp, 2, "x2");
17.91 +// s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0);
17.92 +// s17: lpx_set_obj_coef(lp, 2, 6.0);
17.93 +// s18: lpx_set_col_name(lp, 3, "x3");
17.94 +// s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0);
17.95 +// s20: lpx_set_obj_coef(lp, 3, 4.0);
17.96 +// s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
17.97 +// s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */
17.98 +// s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */
17.99 +// s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */
17.100 +// s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */
17.101 +// s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */
17.102 +// s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */
17.103 +// s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */
17.104 +// s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */
17.105 +// s30: lpx_load_matrix(lp, 9, ia, ja, ar);
17.106 +// s31: lpx_simplex(lp);
17.107 +// s32: Z = lpx_get_obj_val(lp);
17.108 +// s33: x1 = lpx_get_col_prim(lp, 1);
17.109 +// s34: x2 = lpx_get_col_prim(lp, 2);
17.110 +// s35: x3 = lpx_get_col_prim(lp, 3);
17.111 +// s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3);
17.112 +// s37: lpx_delete_prob(lp);
17.113 +// return 0;
17.114 +
17.115 + return 0;
17.116 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/demo/lp_maxflow_demo.cc Mon May 23 04:48:14 2005 +0000
18.3 @@ -0,0 +1,86 @@
18.4 +#ifdef HAVE_CONFIG_H
18.5 +#include <config.h>
18.6 +#endif
18.7 +
18.8 +#include<lemon/graph_reader.h>
18.9 +#include<lemon/list_graph.h>
18.10 +
18.11 +
18.12 +#ifdef HAVE_GLPK
18.13 +#include <lemon/lp_glpk.h>
18.14 +#elif HAVE_CPLEX
18.15 +#include <lemon/lp_cplex.h>
18.16 +#endif
18.17 +
18.18 +using namespace lemon;
18.19 +
18.20 +#ifdef HAVE_GLPK
18.21 +typedef LpGlpk LpDefault;
18.22 +#elif HAVE_CPLEX
18.23 +typedef LpCplex LpDefault;
18.24 +#endif
18.25 +
18.26 +
18.27 +template<class G,class C>
18.28 +double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
18.29 +{
18.30 + LpDefault lp;
18.31 +
18.32 + typedef G Graph;
18.33 + typedef typename G::Node Node;
18.34 + typedef typename G::NodeIt NodeIt;
18.35 + typedef typename G::Edge Edge;
18.36 + typedef typename G::EdgeIt EdgeIt;
18.37 + typedef typename G::OutEdgeIt OutEdgeIt;
18.38 + typedef typename G::InEdgeIt InEdgeIt;
18.39 +
18.40 + typename G::template EdgeMap<LpDefault::Col> x(g);
18.41 + lp.addColSet(x);
18.42 +
18.43 + for(EdgeIt e(g);e!=INVALID;++e) {
18.44 + lp.colUpperBound(x[e],cap[e]);
18.45 + lp.colLowerBound(x[e],0);
18.46 + }
18.47 +
18.48 + for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
18.49 + LpDefault::Expr ex;
18.50 + for(InEdgeIt e(g,n);e!=INVALID;++e) ex+=x[e];
18.51 + for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
18.52 + lp.addRow(ex==0);
18.53 + }
18.54 + {
18.55 + LpDefault::Expr ex;
18.56 + for(InEdgeIt e(g,t);e!=INVALID;++e) ex+=x[e];
18.57 + for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
18.58 + lp.setObj(ex);
18.59 + }
18.60 + lp.max();
18.61 +
18.62 +#ifdef HAVE_GLPK
18.63 + lp.presolver(true);
18.64 + lp.messageLevel(3);
18.65 +#endif
18.66 +
18.67 + lp.solve();
18.68 +
18.69 + return lp.primalValue();
18.70 +}
18.71 +
18.72 +int main()
18.73 +{
18.74 + ListGraph g;
18.75 + ListGraph::Node s;
18.76 + ListGraph::Node t;
18.77 +
18.78 + ListGraph::EdgeMap<double> cap(g);
18.79 +
18.80 + GraphReader<ListGraph> reader(std::cin,g);
18.81 + reader.readNode("source",s).readNode("target",t)
18.82 + .readEdgeMap("capacity",cap).run();
18.83 +
18.84 + // std::ifstream file("../test/preflow_");
18.85 +// readDimacs(file, g, cap, s, t);
18.86 +
18.87 + std::cout << "Max flow value = " << maxFlow(g,cap,s,t) << std::endl;
18.88 +
18.89 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/demo/min_route.cc Mon May 23 04:48:14 2005 +0000
19.3 @@ -0,0 +1,114 @@
19.4 +#include <iostream>
19.5 +#include <fstream>
19.6 +
19.7 +#include <lemon/smart_graph.h>
19.8 +#include <lemon/dijkstra.h>
19.9 +#include <lemon/maps.h>
19.10 +#include <lemon/xy.h>
19.11 +#include <lemon/graph_reader.h>
19.12 +
19.13 +#include <lemon/time_measure.h>
19.14 +
19.15 +#include <cmath>
19.16 +
19.17 +
19.18 +using namespace lemon;
19.19 +
19.20 +template <typename CoordMap>
19.21 +class PotentialMap {
19.22 +public:
19.23 + typedef double Value;
19.24 + typedef typename CoordMap::Key Key;
19.25 +
19.26 + PotentialMap(const CoordMap& _coord, const xy<double>& _target)
19.27 + : coord(_coord), target(_target) {}
19.28 +
19.29 + double operator[](const Key& node) const {
19.30 + return std::sqrt((coord[node].x - target.x) * (coord[node].x - target.x) +
19.31 + (coord[node].y - target.y) * (coord[node].y - target.y));
19.32 + }
19.33 +private:
19.34 + const CoordMap& coord;
19.35 + xy<double> target;
19.36 +};
19.37 +
19.38 +template <typename Graph, typename LengthMap, typename PotentialMap>
19.39 +class ReducedLengthMap {
19.40 +public:
19.41 + typedef double Value;
19.42 + typedef typename LengthMap::Key Key;
19.43 +
19.44 + ReducedLengthMap(const Graph& _graph, const LengthMap& _length,
19.45 + const PotentialMap& _pot)
19.46 + : graph(_graph), length(_length), pot(_pot) {}
19.47 +
19.48 + Value operator[](const Key& edge) const {
19.49 + return length[edge] - (pot[graph.source(edge)] - pot[graph.target(edge)]);
19.50 + }
19.51 +
19.52 +private:
19.53 + const Graph& graph;
19.54 + const LengthMap& length;
19.55 + const PotentialMap& pot;
19.56 +};
19.57 +
19.58 +int main() {
19.59 + typedef SmartGraph Graph;
19.60 +
19.61 + typedef Graph::Edge Edge;
19.62 + typedef Graph::Node Node;
19.63 + typedef Graph::EdgeIt EdgeIt;
19.64 + typedef Graph::NodeIt NodeIt;
19.65 + typedef Graph::EdgeMap<double> LengthMap;
19.66 + typedef Graph::NodeMap<xy<double> > CoordMap;
19.67 +
19.68 + SmartGraph graph;
19.69 +
19.70 + std::ifstream is("route.lgf");
19.71 + GraphReader<Graph> reader(is, graph);
19.72 +
19.73 + CoordMap coord(graph);
19.74 + XMap<CoordMap> xcoord = xMap(coord);
19.75 + reader.readNodeMap("coordinates_x", xcoord);
19.76 + YMap<CoordMap> ycoord = yMap(coord);
19.77 + reader.readNodeMap("coordinates_y", ycoord);
19.78 +
19.79 + LengthMap length(graph);
19.80 + reader.readEdgeMap("length", length);
19.81 +
19.82 + Node source, target;
19.83 + reader.readNode("source", source);
19.84 + reader.readNode("target", target);
19.85 +
19.86 + reader.run();
19.87 +
19.88 + {
19.89 + Timer timer;
19.90 + Dijkstra<Graph, LengthMap> dijkstra(graph, length);
19.91 + dijkstra.init();
19.92 + dijkstra.addSource(source);
19.93 + dijkstra.start(target);
19.94 +
19.95 + std::cout << dijkstra.dist(target) << std::endl;
19.96 + std::cout << timer << std::endl;
19.97 + }
19.98 + {
19.99 + Timer timer;
19.100 + typedef PotentialMap<CoordMap> Potential;
19.101 + Potential potential(coord, coord[target]);
19.102 +
19.103 + typedef ReducedLengthMap<Graph, LengthMap, Potential> ReducedLength;
19.104 + ReducedLength reduced(graph, length, potential);
19.105 +
19.106 + Dijkstra<Graph, ReducedLength> dijkstra(graph, reduced);
19.107 +
19.108 + dijkstra.init();
19.109 + dijkstra.addSource(source);
19.110 + dijkstra.start(target);
19.111 +
19.112 + std::cout << dijkstra.dist(target) + potential[source] << std::endl;
19.113 + std::cout << timer << std::endl;
19.114 + }
19.115 +
19.116 + return 0;
19.117 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/demo/route.lgf Mon May 23 04:48:14 2005 +0000
20.3 @@ -0,0 +1,41 @@
20.4 +@nodeset
20.5 +id coordinates_x coordinates_y
20.6 +9 447.907 578.328
20.7 +8 79.2573 909.464
20.8 +7 878.677 960.04
20.9 +6 11.5504 938.413
20.10 +5 327.398 815.035
20.11 +4 427.002 954.002
20.12 +3 148.549 753.748
20.13 +2 903.889 326.476
20.14 +1 408.248 577.327
20.15 +0 189.239 92.5316
20.16 +@edgeset
20.17 + length
20.18 +2 3 901.074
20.19 +8 5 270.85
20.20 +6 9 601.553
20.21 +5 9 285.022
20.22 +9 4 408.091
20.23 +3 0 719.712
20.24 +7 5 612.836
20.25 +0 4 933.353
20.26 +5 0 778.871
20.27 +5 5 0
20.28 +7 1 664.049
20.29 +5 5 0
20.30 +0 9 560.464
20.31 +4 8 352.36
20.32 +4 9 399.625
20.33 +4 1 402.171
20.34 +1 2 591.688
20.35 +3 8 182.376
20.36 +4 5 180.254
20.37 +3 1 345.283
20.38 +5 4 184.511
20.39 +6 2 1112.45
20.40 +0 1 556.624
20.41 +@nodes
20.42 +source 1
20.43 +target 8
20.44 +@end
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/demo/sub_graph_adaptor_demo.cc Mon May 23 04:48:14 2005 +0000
21.3 @@ -0,0 +1,80 @@
21.4 +// -*- c++ -*-
21.5 +
21.6 +// Use a DIMACS max flow file as stdin.
21.7 +// sub_graph_adaptor_demo < dimacs_max_flow_file
21.8 +// This program computes a maximum number of edge-disjoint shortest paths
21.9 +// between s and t.
21.10 +
21.11 +#include <iostream>
21.12 +#include <fstream>
21.13 +
21.14 +#include <lemon/smart_graph.h>
21.15 +#include <lemon/dijkstra.h>
21.16 +#include <lemon/maps.h>
21.17 +#include <lemon/graph_adaptor.h>
21.18 +#include <lemon/dimacs.h>
21.19 +#include <lemon/preflow.h>
21.20 +#include <tight_edge_filter_map.h>
21.21 +
21.22 +using namespace lemon;
21.23 +
21.24 +using std::cout;
21.25 +using std::endl;
21.26 +
21.27 +int main()
21.28 +{
21.29 + typedef SmartGraph Graph;
21.30 +
21.31 + typedef Graph::Edge Edge;
21.32 + typedef Graph::Node Node;
21.33 + typedef Graph::EdgeIt EdgeIt;
21.34 + typedef Graph::NodeIt NodeIt;
21.35 + typedef Graph::EdgeMap<int> LengthMap;
21.36 +
21.37 + Graph g;
21.38 + Node s, t;
21.39 + LengthMap length(g);
21.40 +
21.41 + readDimacs(std::cin, g, length, s, t);
21.42 +
21.43 + cout << "edges with lengths (of form id, source--length->target): " << endl;
21.44 + for(EdgeIt e(g); e!=INVALID; ++e)
21.45 + cout << " " << g.id(e) << ", " << g.id(g.source(e)) << "--"
21.46 + << length[e] << "->" << g.id(g.target(e)) << endl;
21.47 +
21.48 + cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
21.49 +
21.50 + typedef Dijkstra<Graph, LengthMap> Dijkstra;
21.51 + Dijkstra dijkstra(g, length);
21.52 + dijkstra.run(s);
21.53 +
21.54 + // This map returns true exactly for those edges which are
21.55 + // tight w.r.t the length funcion and the potential
21.56 + // given by the dijkstra algorithm.
21.57 + typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
21.58 + TightEdgeFilter;
21.59 + TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
21.60 +
21.61 +// ConstMap<Node, bool> const_true_map(true);
21.62 + // This graph contains exaclty the tight edges.
21.63 +// typedef SubGraphAdaptor<Graph, ConstMap<Node, bool>, TightEdgeFilter> SubGW;
21.64 + typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
21.65 + SubGW gw(g, tight_edge_filter);
21.66 +
21.67 + ConstMap<Edge, int> const_1_map(1);
21.68 + Graph::EdgeMap<int> flow(g, 0);
21.69 + // Max flow between s and t in the graph of tight edges.
21.70 + Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
21.71 + preflow(gw, s, t, const_1_map, flow);
21.72 + preflow.run();
21.73 +
21.74 + cout << "maximum number of edge-disjoint shortest path: "
21.75 + << preflow.flowValue() << endl;
21.76 + cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
21.77 + << endl;
21.78 + for(EdgeIt e(g); e!=INVALID; ++e)
21.79 + if (flow[e])
21.80 + cout << " " << g.id(e) << ", "
21.81 + << g.id(g.source(e)) << "--"
21.82 + << length[e] << "->" << g.id(g.target(e)) << endl;
21.83 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/demo/sub_graph_adaptor_demo.dim Mon May 23 04:48:14 2005 +0000
22.3 @@ -0,0 +1,14 @@
22.4 +c LEMON max flow problem
22.5 +p max 7 9
22.6 +n 1 s
22.7 +n 7 t
22.8 +a 1 2 3
22.9 +a 1 3 2
22.10 +a 1 4 1
22.11 +a 2 5 3
22.12 +a 3 5 2
22.13 +a 3 7 5
22.14 +a 3 6 3
22.15 +a 4 6 1
22.16 +a 5 7 2
22.17 +a 6 7 4
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/demo/tight_edge_filter_map.h Mon May 23 04:48:14 2005 +0000
23.3 @@ -0,0 +1,68 @@
23.4 +/* -*- C++ -*-
23.5 + * demo/tight_edge_filter_map.h - Part of LEMON, a generic C++ optimization
23.6 + * library
23.7 + *
23.8 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
23.9 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
23.10 + *
23.11 + * Permission to use, modify and distribute this software is granted
23.12 + * provided that this copyright notice appears in all copies. For
23.13 + * precise terms see the accompanying LICENSE file.
23.14 + *
23.15 + * This software is provided "AS IS" with no warranty of any kind,
23.16 + * express or implied, and with no claim as to its suitability for any
23.17 + * purpose.
23.18 + *
23.19 + */
23.20 +
23.21 +#ifndef LEMON_TIGHT_EDGE_FILTER_MAP_H
23.22 +#define LEMON_TIGHT_EDGE_FILTER_MAP_H
23.23 +
23.24 +#include <lemon/maps.h>
23.25 +
23.26 +// /// \file
23.27 +// /// \brief Maximum flow algorithms.
23.28 +// /// \ingroup galgs
23.29 +
23.30 +namespace lemon {
23.31 +
23.32 + /*!
23.33 + \brief A map for filtering the edge-set to those edges
23.34 + which are tight w.r.t. a node-potential and
23.35 + edge-distance.
23.36 +
23.37 + Let \f$G=(V,A)\f$ be a directed graph (graph for short) and
23.38 + let \f$\mathbb{F}\f$ be a number type.
23.39 + Given a distance function
23.40 + \f$d:E\to\mathbb{F}\f$,
23.41 + \f$\pi:V\to\mathbb{F}\f$ is said to be a potetial
23.42 + w.r.t. \f$d\f$
23.43 + if and only if
23.44 + \f$\pi(v)\le d(uv)+\pi(u)\f$ holds for each edge \f$uv\in E\f$
23.45 + (or the reverse inequality holds for each edge).
23.46 + An edge is said to be tight if this inequality holds with equality,
23.47 + and the map returns \c true exactly for those edges.
23.48 + To avoid rounding errors, it is recommended to use this class with exact
23.49 + number types, e.g. with \c int.
23.50 + */
23.51 + template<typename Graph,
23.52 + typename NodePotentialMap, typename EdgeDistanceMap>
23.53 + class TightEdgeFilterMap : public MapBase<typename Graph::Edge, bool> {
23.54 + protected:
23.55 + const Graph* g;
23.56 + NodePotentialMap* node_potential;
23.57 + EdgeDistanceMap* edge_distance;
23.58 + public:
23.59 + TightEdgeFilterMap(Graph& _g, NodePotentialMap& _node_potential,
23.60 + EdgeDistanceMap& _edge_distance) :
23.61 + g(&_g), node_potential(&_node_potential),
23.62 + edge_distance(&_edge_distance) { }
23.63 + bool operator[](const typename Graph::Edge& e) const {
23.64 + return ((*node_potential)[g->target(e)] ==
23.65 + (*edge_distance)[e]+(*node_potential)[g->source(e)]);
23.66 + }
23.67 + };
23.68 +
23.69 +} //namespace lemon
23.70 +
23.71 +#endif //LEMON_TIGHT_EDGE_FILTER_MAP_H
24.1 --- a/doc/Doxyfile.in Sat May 21 21:04:57 2005 +0000
24.2 +++ b/doc/Doxyfile.in Mon May 23 04:48:14 2005 +0000
24.3 @@ -115,7 +115,7 @@
24.4 # If left blank the directory from which doxygen is run is used as the
24.5 # path to strip.
24.6
24.7 -STRIP_FROM_PATH = @abs_top_srcdir@/src
24.8 +STRIP_FROM_PATH = @abs_top_srcdir@
24.9
24.10 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
24.11 # the path mentioned in the documentation of a class, which tells
24.12 @@ -124,7 +124,7 @@
24.13 # definition is used. Otherwise one should specify the include paths that
24.14 # are normally passed to the compiler using the -I flag.
24.15
24.16 -STRIP_FROM_INC_PATH = @abs_top_srcdir@/src
24.17 +STRIP_FROM_INC_PATH = @abs_top_srcdir@
24.18
24.19 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
24.20 # (but less readable) file names. This can be useful is your file systems
24.21 @@ -451,11 +451,11 @@
24.22 # with spaces.
24.23
24.24 INPUT = @abs_top_srcdir@/doc \
24.25 - @abs_top_srcdir@/src/lemon \
24.26 - @abs_top_srcdir@/src/lemon/bits \
24.27 - @abs_top_srcdir@/src/lemon/concept \
24.28 - @abs_top_srcdir@/src/demo \
24.29 - @abs_top_srcdir@/src/test/test_tools.h
24.30 + @abs_top_srcdir@/lemon \
24.31 + @abs_top_srcdir@/lemon/bits \
24.32 + @abs_top_srcdir@/lemon/concept \
24.33 + @abs_top_srcdir@/demo \
24.34 + @abs_top_srcdir@/test/test_tools.h
24.35
24.36 # If the value of the INPUT tag contains directories, you can use the
24.37 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
24.38 @@ -494,7 +494,7 @@
24.39 # directories that contain example code fragments that are included (see
24.40 # the \include command).
24.41
24.42 -EXAMPLE_PATH = ../src/demo \
24.43 +EXAMPLE_PATH = ../demo \
24.44 ../LICENSE \
24.45 .
24.46
25.1 --- a/doc/template.h Sat May 21 21:04:57 2005 +0000
25.2 +++ b/doc/template.h Mon May 23 04:48:14 2005 +0000
25.3 @@ -1,5 +1,5 @@
25.4 /* -*- C++ -*-
25.5 - * src/lemon/template.h - Part of LEMON, a generic C++ optimization library
25.6 + * lemon/template.h - Part of LEMON, a generic C++ optimization library
25.7 *
25.8 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
25.9 * (Egervary Research Group on Combinatorial Optimization, EGRES).
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/gui/Makefile.am Mon May 23 04:48:14 2005 +0000
26.3 @@ -0,0 +1,19 @@
26.4 +AM_CPPFLAGS = -I$(top_srcdir)
26.5 +LDADD = $(top_builddir)/lemon/libemon.la
26.6 +
26.7 +bin_PROGRAMS = gd
26.8 +
26.9 +gd_SOURCES = \
26.10 + all_include.h \
26.11 + graph_displayer_canvas.cc \
26.12 + graph_displayer_canvas.h \
26.13 + graph-displayer.cc \
26.14 + main_win.cc \
26.15 + main_win.h \
26.16 + mapstorage.cc \
26.17 + mapstorage.h \
26.18 + map_win.cc \
26.19 + map_win.h
26.20 +
26.21 +gd_CXXFLAGS = $(GTK_CFLAGS)
26.22 +gd_LDFLAGS = $(GTK_LIBS)
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/gui/all_include.h Mon May 23 04:48:14 2005 +0000
27.3 @@ -0,0 +1,39 @@
27.4 +// -*- C++ -*- //
27.5 +
27.6 +#ifndef ALL_INCLUDE_H
27.7 +#define ALL_INCLUDE_H
27.8 +
27.9 +#include <fstream>
27.10 +#include <iostream>
27.11 +
27.12 +#include <vector>
27.13 +
27.14 +#include <lemon/list_graph.h>
27.15 +#include <lemon/graph_reader.h>
27.16 +#include <lemon/graph_writer.h>
27.17 +#include <lemon/graph_utils.h>
27.18 +#include <lemon/maps.h>
27.19 +#include <lemon/error.h>
27.20 +#include <lemon/xy.h>
27.21 +
27.22 +enum {WIDTH, COLOR, TEXT, PROPERTY_NUM};// properties;
27.23 +#define RANGE 3
27.24 +#define WIN_WIDTH 900
27.25 +#define WIN_HEIGHT 600
27.26 +
27.27 +
27.28 +#ifndef MAIN_PART
27.29 +extern std::string * property_strings;
27.30 +extern double * property_defaults;
27.31 +#endif //MAIN_PART
27.32 +
27.33 +using namespace lemon;
27.34 +
27.35 +typedef xy<double> Coordinates;
27.36 +typedef ListGraph Graph;
27.37 +typedef Graph::NodeMap<Coordinates> CoordinatesMap;
27.38 +typedef Graph::Node Node;
27.39 +typedef Graph::EdgeIt EdgeIt;
27.40 +typedef Graph::NodeIt NodeIt;
27.41 +
27.42 +#endif // ALL_INCLUDE_H
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/gui/graph-displayer.cc Mon May 23 04:48:14 2005 +0000
28.3 @@ -0,0 +1,73 @@
28.4 +#include <all_include.h>
28.5 +#include <mapstorage.h>
28.6 +#include <main_win.h>
28.7 +#include <libgnomecanvasmm.h>
28.8 +#include <libgnomecanvasmm/polygon.h>
28.9 +
28.10 +#define MAIN_PART
28.11 +
28.12 +std::string * property_strings;
28.13 +double * property_defaults;
28.14 +
28.15 +
28.16 +int main(int argc, char *argv[])
28.17 +{
28.18 + property_strings=new std::string[PROPERTY_NUM];
28.19 + property_strings[WIDTH]="Width";
28.20 + property_strings[COLOR]="Color";
28.21 + property_strings[TEXT]="Text";
28.22 +
28.23 + property_defaults=new double[PROPERTY_NUM];
28.24 + property_defaults[WIDTH]=10.0;
28.25 + property_defaults[COLOR]=100;
28.26 + property_defaults[TEXT]=0;
28.27 +
28.28 + if(argc<2)
28.29 + {
28.30 + std::cerr << "USAGE: gd <input filename.lgf>" << std::endl;
28.31 + return 0;
28.32 + }
28.33 +
28.34 + Coordinates coosvector;
28.35 +
28.36 + Graph g;
28.37 +
28.38 + CoordinatesMap cm(g);
28.39 + Graph::EdgeMap<double> cap(g), map1(g), map2(g), map3(g), map4(g);
28.40 +
28.41 + //we create one object to read x coordinates
28.42 + //and one to read y coordinate of nodes and write them to cm NodeMap.
28.43 +
28.44 + XMap <CoordinatesMap> xreader (cm);
28.45 + YMap <CoordinatesMap> yreader (cm);
28.46 + Graph::NodeMap<double> nodedata (g);
28.47 +
28.48 + std::ifstream is(argv[1]);
28.49 +
28.50 + GraphReader<Graph> reader(is, g);
28.51 + reader.readNodeMap("coordinates_x", xreader);
28.52 + reader.readNodeMap("coordinates_y", yreader);
28.53 + reader.readNodeMap("data", nodedata);
28.54 + reader.readEdgeMap("cap", cap);
28.55 + reader.readEdgeMap("map1", map1);
28.56 + reader.readEdgeMap("map2", map2);
28.57 + reader.readEdgeMap("map3", map3);
28.58 + reader.readEdgeMap("map4", map4);
28.59 + reader.run();
28.60 +
28.61 + MapStorage ms(g);
28.62 + ms.addNodeMap("data",&nodedata);
28.63 + ms.addEdgeMap("cap",&cap);
28.64 + ms.addEdgeMap("map1",&map1);
28.65 + ms.addEdgeMap("map2",&map2);
28.66 + ms.addEdgeMap("map3",&map3);
28.67 + ms.addEdgeMap("map4",&map4);
28.68 +
28.69 + Gnome::Canvas::init();
28.70 + Gtk::Main app(argc, argv);
28.71 +
28.72 + MainWin mainwin("Displayed Graph", g, cm, ms);
28.73 + app.run(mainwin);
28.74 +
28.75 + return 0;
28.76 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/gui/graph_displayer_canvas.cc Mon May 23 04:48:14 2005 +0000
29.3 @@ -0,0 +1,259 @@
29.4 +#include <graph_displayer_canvas.h>
29.5 +
29.6 +GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm, MapStorage & ms):g(gr),nodesmap(g),edgesmap(g),edgetextmap(g),displayed_graph(*(root()), 0, 0),mapstorage(ms),isbutton(false),active_item(NULL)
29.7 +{
29.8 +
29.9 + for (EdgeIt i(g); i!=INVALID; ++i)
29.10 + {
29.11 + Gnome::Canvas::Points coos;
29.12 + coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));
29.13 + coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));
29.14 +
29.15 + edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);
29.16 + *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
29.17 + edgesmap[i]->property_width_pixels().set_value(10);
29.18 +
29.19 +
29.20 + double x1, x2, y1, y2;
29.21 + edgesmap[i]->get_bounds(x1, y1, x2, y2);
29.22 +
29.23 + edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");
29.24 + edgetextmap[i]->property_fill_color().set_value("black");
29.25 + }
29.26 +
29.27 + NodeIt i(g);
29.28 + int maxx=0, maxy=0, minx=(int)cm[i].x, miny=(int)cm[i].y;
29.29 +
29.30 + for (; i!=INVALID; ++i)
29.31 + {
29.32 + if(cm[i].x>maxx)maxx=(int)cm[i].x;
29.33 + if(cm[i].y>maxy)maxy=(int)cm[i].y;
29.34 + if(cm[i].x<minx)minx=(int)cm[i].x;
29.35 + if(cm[i].y<miny)miny=(int)cm[i].y;
29.36 +
29.37 + nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
29.38 + *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
29.39 + *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
29.40 + (nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));
29.41 + }
29.42 +
29.43 + double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);
29.44 + double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);
29.45 +
29.46 + set_pixels_per_unit((biggest_x>biggest_y)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));
29.47 + std::cout<<abs(maxx)<<" "<<abs(minx)<<" big x "<<biggest_x<<" "<<abs(maxy)<<" "<<abs(miny)<<" big y "<<biggest_y<<std::endl;
29.48 + std::cout<<maxx<<" "<<minx<<" big x "<<biggest_x<<" "<<maxy<<" "<<miny<<" big y "<<biggest_y<<std::endl;
29.49 + std::cout<<"dx "<<(maxx-minx)<<" dy "<<(maxy-miny)<<" xrate "<<((maxx-minx)/WIN_WIDTH)<<" yrate "<<((maxy-miny)/WIN_HEIGHT)<<std::endl;
29.50 +
29.51 +}
29.52 +
29.53 +GraphDisplayerCanvas::~GraphDisplayerCanvas()
29.54 +{
29.55 + Graph::NodeMap <int> id(g);
29.56 + Graph::NodeMap <double> xc(g);
29.57 + Graph::NodeMap <double> yc(g);
29.58 +
29.59 + int j=1;
29.60 +
29.61 + for (NodeIt i(g); i!=INVALID; ++i)
29.62 + {
29.63 + double x1,y1,x2,y2;
29.64 + nodesmap[i]->get_bounds(x1, y1, x2, y2);
29.65 +
29.66 + id[i]=j++;
29.67 + xc[i]=(x1+x2)/2;
29.68 + yc[i]=(y1+y2)/2;
29.69 + }
29.70 +
29.71 + GraphWriter<Graph> writer(std::cout,g);
29.72 +
29.73 + writer.writeNodeMap("id", id);
29.74 + writer.writeNodeMap("coordinates_x", xc);
29.75 + writer.writeNodeMap("coordinates_y", yc);
29.76 + writer.run();
29.77 +}
29.78 +
29.79 +int GraphDisplayerCanvas::changeLineWidth (std::string mapname)
29.80 +{
29.81 + for (EdgeIt i(g); i!=INVALID; ++i)
29.82 + {
29.83 + int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];
29.84 + edgesmap[i]->property_width_pixels().set_value(w);
29.85 + }
29.86 + return 0;
29.87 +};
29.88 +
29.89 +int GraphDisplayerCanvas::changeColor (std::string mapname)
29.90 +{
29.91 + for (EdgeIt i(g); i!=INVALID; ++i)
29.92 + {
29.93 + double w=(*(mapstorage.edgemap_storage)[mapname])[i];
29.94 + double max=mapstorage.maxOfEdgeMap(mapname);
29.95 + double min=mapstorage.minOfEdgeMap(mapname);
29.96 +
29.97 + //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(w-min)/(max-min)<<std::endl;
29.98 + Gdk::Color color;
29.99 + if(max!=min)
29.100 + {
29.101 + color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
29.102 + }
29.103 + else
29.104 + {
29.105 + color.set_rgb_p (0, 100, 0);
29.106 + }
29.107 +
29.108 + edgesmap[i]->property_fill_color_gdk().set_value(color);
29.109 + }
29.110 + return 0;
29.111 +};
29.112 +
29.113 +int GraphDisplayerCanvas::changeText (std::string mapname)
29.114 +{
29.115 + for (EdgeIt i(g); i!=INVALID; ++i)
29.116 + {
29.117 + if(mapname!="Text")
29.118 + {
29.119 + double number=(*(mapstorage.edgemap_storage)[mapname])[i];
29.120 + int length=(int)(floor(log(number)/log(10)))+1;
29.121 + int maxpos=(int)(pow(10,length-1));
29.122 + int strl=length+1+RANGE;
29.123 + char * str=new char[strl];
29.124 + str[length]='.';
29.125 + str[strl]='\0';
29.126 +
29.127 + for(int j=0;j<strl;j++)
29.128 + {
29.129 + if(j!=length)
29.130 + {
29.131 + int digit=(int)(number/maxpos);
29.132 + str[j]=(digit+'0');
29.133 + number-=digit*maxpos;
29.134 + number*=10;
29.135 + }
29.136 + }
29.137 +
29.138 + edgetextmap[i]->property_text().set_value(str);
29.139 + }
29.140 + else
29.141 + {
29.142 + edgetextmap[i]->property_text().set_value("");
29.143 + }
29.144 + }
29.145 + return 0;
29.146 +};
29.147 +
29.148 +
29.149 +int GraphDisplayerCanvas::rezoom ()
29.150 +{
29.151 + double x1, x2, y1, y2;
29.152 + int x,y;
29.153 +
29.154 + NodeIt i(g);
29.155 + nodesmap[i]->get_bounds(x1, y1, x2, y2);
29.156 +
29.157 + x=(int)((x1+x2)/2);
29.158 + y=(int)((y1+y2)/2);
29.159 +
29.160 + int maxx=0, maxy=0, minx=(int)x, miny=(int)y;
29.161 +
29.162 + for (; i!=INVALID; ++i)
29.163 + {
29.164 + nodesmap[i]->get_bounds(x1, y1, x2, y2);
29.165 +
29.166 + x=(int)((x1+x2)/2);
29.167 + y=(int)((y1+y2)/2);
29.168 +
29.169 + if(x>maxx)maxx=x;
29.170 + if(y>maxy)maxy=y;
29.171 + if(x<minx)minx=x;
29.172 + if(y<miny)miny=y;
29.173 + }
29.174 +
29.175 + double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);
29.176 + double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);
29.177 +
29.178 + set_pixels_per_unit((biggest_x-WIN_WIDTH>biggest_y-WIN_HEIGHT)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));
29.179 + return 0;
29.180 +};
29.181 +
29.182 +
29.183 +///This function moves only one node of displayed_graph,
29.184 +///but recalculate the location of weight point,
29.185 +///and also redraw the sides of the planefigure.
29.186 +bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
29.187 +{
29.188 + switch(e->type)
29.189 + {
29.190 + case GDK_BUTTON_PRESS:
29.191 + clicked_x=e->button.x;
29.192 + clicked_y=e->button.y;
29.193 + active_item=(get_item_at(e->button.x, e->button.y));
29.194 + isbutton=true;
29.195 + break;
29.196 + case GDK_BUTTON_RELEASE:
29.197 + isbutton=false;
29.198 + active_item=NULL;
29.199 + break;
29.200 + case GDK_MOTION_NOTIFY:
29.201 + if(isbutton)
29.202 + {
29.203 + double dx=e->motion.x-clicked_x;
29.204 + double dy=e->motion.y-clicked_y;
29.205 + active_item->move(dx, dy);
29.206 + clicked_x=e->motion.x;
29.207 + clicked_y=e->motion.y;
29.208 +
29.209 + EdgeIt e;
29.210 +
29.211 + g.firstOut(e,n);
29.212 + for(;e!=INVALID;g.nextOut(e))
29.213 + {
29.214 + Gnome::Canvas::Points coos;
29.215 + double x1, x2, y1, y2;
29.216 +
29.217 + nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
29.218 + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
29.219 +
29.220 + nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
29.221 + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
29.222 +
29.223 + edgesmap[e]->property_points().set_value(coos);
29.224 +
29.225 + edgesmap[e]->get_bounds(x1, y1, x2, y2);
29.226 +
29.227 + edgetextmap[e]->property_x().set_value((x1+x2)/2);
29.228 + edgetextmap[e]->property_y().set_value((y1+y2)/2);
29.229 + }
29.230 +
29.231 + g.firstIn(e,n);
29.232 + for(;e!=INVALID;g.nextIn(e))
29.233 + {
29.234 + Gnome::Canvas::Points coos;
29.235 + double x1, x2, y1, y2;
29.236 +
29.237 + nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
29.238 + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
29.239 +
29.240 + nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
29.241 + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
29.242 +
29.243 + edgesmap[e]->property_points().set_value(coos);
29.244 +
29.245 + edgesmap[e]->get_bounds(x1, y1, x2, y2);
29.246 +
29.247 + edgetextmap[e]->property_x().set_value((x1+x2)/2);
29.248 + edgetextmap[e]->property_y().set_value((y1+y2)/2);
29.249 + }
29.250 + }
29.251 + default: break;
29.252 + }
29.253 + return true;
29.254 +}
29.255 +
29.256 +bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
29.257 +{
29.258 + Gnome::Canvas::CanvasAA::on_expose_event(event);
29.259 + //usleep(10000);
29.260 + //rezoom();
29.261 + return true;
29.262 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/gui/graph_displayer_canvas.h Mon May 23 04:48:14 2005 +0000
30.3 @@ -0,0 +1,65 @@
30.4 +// -*- C++ -*- //
30.5 +
30.6 +#ifndef GRAPH_DISPLAYER_CANVAS_H
30.7 +#define GRAPH_DISPLAYER_CANVAS_H
30.8 +
30.9 +#include <all_include.h>
30.10 +#include <mapstorage.h>
30.11 +#include <libgnomecanvasmm.h>
30.12 +#include <libgnomecanvasmm/polygon.h>
30.13 +
30.14 +class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
30.15 +{
30.16 + typedef Gnome::Canvas::CanvasAA Parent;
30.17 +
30.18 +public:
30.19 + GraphDisplayerCanvas(Graph &, CoordinatesMap &, MapStorage &);
30.20 + virtual ~GraphDisplayerCanvas();
30.21 +
30.22 + int changeLineWidth (std::string mapname);
30.23 + int changeColor (std::string mapname);
30.24 + int changeText (std::string mapname);
30.25 + int rezoom();
30.26 +
30.27 +protected:
30.28 +
30.29 + virtual bool on_expose_event(GdkEventExpose *);
30.30 +
30.31 +private:
30.32 +
30.33 + ///Event handler function that handles dragging nodes of displayed_graph
30.34 + bool event_handler(GdkEvent* e, Node n);
30.35 +
30.36 + ///The graph, on which we work
30.37 + Graph g;
30.38 + ///Map of nodes of planefigure
30.39 + Graph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
30.40 + ///Map of edges of planefigure
30.41 + Graph::EdgeMap<Gnome::Canvas::Line *> edgesmap;
30.42 +
30.43 + ///Map of texts to write on edges
30.44 + Graph::EdgeMap<Gnome::Canvas::Text *> edgetextmap;
30.45 +
30.46 + ///Group of graphical elements of displayed_graph
30.47 + Gnome::Canvas::Group displayed_graph;
30.48 +
30.49 + ///Here we store the maps that can be displayed through properties.
30.50 + MapStorage mapstorage;
30.51 +
30.52 + ///Indicates whether the button of mouse is pressed or not
30.53 + bool isbutton;
30.54 +
30.55 + ///At this location was the mousebutton pressed.
30.56 + ///It helps to calculate the distance of dragging.
30.57 + double clicked_x, clicked_y;
30.58 +
30.59 + ///Remembers which Gnome::Canvas::Item was pressed.
30.60 + ///this variable is needed, because
30.61 + ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
30.62 + ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
30.63 + Gnome::Canvas::Item * active_item;
30.64 +
30.65 +
30.66 +};
30.67 +
30.68 +#endif //GRAPH_DISPLAYER_CANVAS_H
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/gui/graphocska.lgf Mon May 23 04:48:14 2005 +0000
31.3 @@ -0,0 +1,39 @@
31.4 +@nodeset
31.5 +id coordinates_x coordinates_y data
31.6 +1 230 -80 1
31.7 +2 230 100 3
31.8 +3 120 -80 5
31.9 +4 120 100 7
31.10 +5 20 100 9
31.11 +6 20 -80 11
31.12 +7 -40 10 13
31.13 +8 -100 100 15
31.14 +9 -100 10 17
31.15 +10 -100 -80 19
31.16 +11 -200 -80 21
31.17 +12 -200 10 23
31.18 +13 -200 100 25
31.19 +14 -300 100 27
31.20 +15 -300 -80 29
31.21 +
31.22 +@edgeset
31.23 + cap map1 map2 map3 map4
31.24 +15 14 1 21 111 231 3
31.25 +14 13 2 22 112 232 6
31.26 +13 12 3 23 113 233 9
31.27 +13 8 4 24 114 234 12
31.28 +12 11 5 25 115 235 15
31.29 +12 9 6 26 116 236 18
31.30 +11 10 7 27 117 237 21
31.31 +10 9 8 28 118 238 24
31.32 +10 7 9 29 119 239 27
31.33 +9 8 10 30 120 230 30
31.34 +7 6 11 31 121 241 33
31.35 +6 5 12 32 122 242 36
31.36 +6 3 13 33 123 243 39
31.37 +5 4 14 34 124 244 42
31.38 +4 3 15 35 125 245 45
31.39 +3 2 16 36 126 246 48
31.40 +2 1 17 37 127 247 51
31.41 +
31.42 +@end
31.43 \ No newline at end of file
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/gui/main_win.cc Mon May 23 04:48:14 2005 +0000
32.3 @@ -0,0 +1,69 @@
32.4 +#include <main_win.h>
32.5 +
32.6 +MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm, MapStorage & ms):mapwin("Map Setup", ms, gd_canvas),gd_canvas(graph, cm, ms)
32.7 +{
32.8 + set_title (title);
32.9 + set_default_size(WIN_WIDTH,WIN_HEIGHT);
32.10 + add(vbox);
32.11 +
32.12 + ag=Gtk::ActionGroup::create();
32.13 + ag->add( Gtk::Action::create("ShowMenu", "_Show") );
32.14 + ag->add( Gtk::Action::create("ShowMaps", "_Maps"), sigc::mem_fun(*this, &MainWin::showMaps));
32.15 + ag->add( Gtk::Action::create("FileMenu", "_File") );
32.16 + ag->add( Gtk::Action::create("FileQuit", "_Quit"), sigc::mem_fun(*this, &MainWin::quit));
32.17 + ag->add( Gtk::Action::create("ZoomMenu", "_Zoom") );
32.18 + ag->add( Gtk::Action::create("ZoomRezoom", "_Rezoom"), sigc::mem_fun(*this, &MainWin::rezoom)); //!!!!!!
32.19 +
32.20 + uim=Gtk::UIManager::create();
32.21 + uim->insert_action_group(ag);
32.22 + add_accel_group(uim->get_accel_group());
32.23 +
32.24 + try
32.25 + {
32.26 +
32.27 + Glib::ustring ui_info =
32.28 + "<ui>"
32.29 + " <menubar name='MenuBar'>"
32.30 + " <menu action='FileMenu'>"
32.31 + " <menuitem action='FileQuit'/>"
32.32 + " </menu>"
32.33 + " <menu action='ShowMenu'>"
32.34 + " <menuitem action='ShowMaps'/>"
32.35 + " </menu>"
32.36 + " <menu action='ZoomMenu'>"
32.37 + " <menuitem action='ZoomRezoom'/>"
32.38 + " </menu>"
32.39 + " </menubar>"
32.40 + "</ui>";
32.41 +
32.42 + uim->add_ui_from_string(ui_info);
32.43 +
32.44 + }
32.45 + catch(const Glib::Error& ex)
32.46 + {
32.47 + std::cerr << "building menus failed: " << ex.what();
32.48 + }
32.49 +
32.50 + Gtk::Widget* menubar = uim->get_widget("/MenuBar");
32.51 + if(menubar)vbox.pack_start(*menubar, Gtk::PACK_SHRINK);
32.52 +
32.53 + vbox.pack_start(gd_canvas);
32.54 +
32.55 + show_all_children();
32.56 +}
32.57 +
32.58 +void MainWin::showMaps()
32.59 +{
32.60 + mapwin.show();
32.61 +}
32.62 +
32.63 +void MainWin::quit()
32.64 +{
32.65 + hide();
32.66 +}
32.67 +
32.68 +void MainWin::rezoom()
32.69 +{
32.70 + gd_canvas.rezoom();
32.71 +}
32.72 +
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/gui/main_win.h Mon May 23 04:48:14 2005 +0000
33.3 @@ -0,0 +1,44 @@
33.4 +// -*- C++ -*- //
33.5 +
33.6 +#ifndef MAIN_WIN_H
33.7 +#define MAIN_WIN_H
33.8 +
33.9 +#include <all_include.h>
33.10 +#include <mapstorage.h>
33.11 +#include <map_win.h>
33.12 +#include <libgnomecanvasmm.h>
33.13 +#include <libgnomecanvasmm/polygon.h>
33.14 +
33.15 +class MainWin : public Gtk::Window
33.16 +{
33.17 +public:
33.18 + MainWin(const std::string& title, Graph &, CoordinatesMap &, MapStorage &);
33.19 +
33.20 +protected:
33.21 + //Window of map-showing setup
33.22 + MapWin mapwin;
33.23 +
33.24 + //Member widgets:
33.25 + GraphDisplayerCanvas gd_canvas;
33.26 +
33.27 + //ActionGroup for menu
33.28 + Glib::RefPtr<Gtk::ActionGroup> ag;
33.29 +
33.30 + //UIManager for menu
33.31 + Glib::RefPtr<Gtk::UIManager> uim;
33.32 +
33.33 + //Container
33.34 + Gtk::VBox vbox;
33.35 +
33.36 + //Pops up map-setup window
33.37 + virtual void showMaps();
33.38 +
33.39 + //Exit
33.40 + virtual void quit();
33.41 +
33.42 + //Refit screen
33.43 + virtual void rezoom();
33.44 +
33.45 +};
33.46 +
33.47 +#endif //MAIN_WIN_H
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/gui/map_win.cc Mon May 23 04:48:14 2005 +0000
34.3 @@ -0,0 +1,116 @@
34.4 +#include <map_win.h>
34.5 +#include <set>
34.6 +
34.7 +MapWin::MapWin(const std::string& title, MapStorage & mapst, GraphDisplayerCanvas & grdispc):gdc(grdispc),ms(mapst)
34.8 +{
34.9 + set_title(title);
34.10 + set_default_size(400, 200);
34.11 +
34.12 + rb_array=new Gtk::RadioButton * [PROPERTY_NUM];
34.13 + vbox_r1=new Gtk::VBox[PROPERTY_NUM];
34.14 + vbox_r2=new Gtk::VBox[PROPERTY_NUM];
34.15 + radios=new Gtk::HBox[PROPERTY_NUM];
34.16 + for(int i=0;i<PROPERTY_NUM;i++)
34.17 + {
34.18 + rb_array[i]=new Gtk::RadioButton[ms.numOfEdgeMaps()+1];
34.19 +
34.20 + Gtk::RadioButton::Group group;
34.21 +
34.22 + std::map< std::string,Graph::EdgeMap<double> * >::iterator emsi=ms.beginOfEdgeMaps();
34.23 + std::set<int> props;
34.24 +
34.25 + int actprop;
34.26 + for(int j=0;j<ms.numOfEdgeMaps();j++)
34.27 + {
34.28 +
34.29 + if(emsi->second==&(ms.default_edgemaps[i]))
34.30 + {
34.31 + actprop=j;
34.32 + }
34.33 + for(int k=0;k<PROPERTY_NUM;k++)
34.34 + {
34.35 + if(emsi->second==&(ms.default_edgemaps[k]))
34.36 + {
34.37 + props.insert(j);
34.38 + }
34.39 + }
34.40 + emsi++;
34.41 + }
34.42 +
34.43 + rb_array[i][0].set_group(group);
34.44 + rb_array[i][0].set_label("Default");
34.45 + rb_array[i][0].signal_clicked().connect( sigc::bind( sigc::bind( sigc::mem_fun(*this, &MapWin::radio_click), 0), i) );
34.46 + vbox_r1[i].pack_start(rb_array[i][0]);
34.47 +
34.48 +
34.49 + emsi=ms.beginOfEdgeMaps();
34.50 + int actpos=1;
34.51 + for(int j=0;j<ms.numOfEdgeMaps();j++)
34.52 + {
34.53 + if( ( props.find(j) )==( props.end() ) )
34.54 + {
34.55 + rb_array[i][actpos].set_group(group);
34.56 + rb_array[i][actpos].set_label(emsi->first);
34.57 + rb_array[i][actpos].signal_clicked().connect
34.58 + (
34.59 + sigc::bind(
34.60 + sigc::bind(
34.61 + sigc::mem_fun(*this, &MapWin::radio_click),
34.62 + actpos
34.63 + ),
34.64 + i
34.65 + )
34.66 + );
34.67 +
34.68 + if(actpos<(ms.numOfEdgeMaps()-PROPERTY_NUM+1)/2)
34.69 + {
34.70 + vbox_r1[i].pack_start(rb_array[i][actpos]);
34.71 + }
34.72 + else
34.73 + {
34.74 + vbox_r2[i].pack_start(rb_array[i][actpos]);
34.75 + }
34.76 + actpos++;
34.77 + }
34.78 + emsi++;
34.79 + }
34.80 + radios[i].pack_start(vbox_r1[i]);
34.81 + radios[i].pack_start(vbox_r2[i]);
34.82 + notebook.append_page(radios[i], property_strings[i]);
34.83 + }
34.84 +
34.85 + add(vbox_b);
34.86 + vbox_b.pack_start(notebook);
34.87 +
34.88 + show_all_children();
34.89 +
34.90 +}
34.91 +
34.92 +void MapWin::radio_click(int prop, int actpos)
34.93 +{
34.94 + if(rb_array[prop][actpos].get_active())
34.95 + {
34.96 +
34.97 + std::string mapname=rb_array[prop][actpos].get_label();
34.98 +
34.99 + if(mapname=="Default")
34.100 + {
34.101 + mapname=property_strings[prop];
34.102 + }
34.103 +
34.104 + switch(prop)
34.105 + {
34.106 + case WIDTH:
34.107 + gdc.changeLineWidth(mapname);
34.108 + break;
34.109 + case COLOR:
34.110 + gdc.changeColor(mapname);
34.111 + break;
34.112 + case TEXT:
34.113 + gdc.changeText(mapname);
34.114 + break;
34.115 + default:
34.116 + std::cout<<"Error\n";
34.117 + }
34.118 + }
34.119 +};
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/gui/map_win.h Mon May 23 04:48:14 2005 +0000
35.3 @@ -0,0 +1,30 @@
35.4 +// -*- C++ -*- //
35.5 +
35.6 +#ifndef MAP_WIN_H
35.7 +#define MAP_WIN_H
35.8 +
35.9 +#include <all_include.h>
35.10 +#include <mapstorage.h>
35.11 +#include <graph_displayer_canvas.h>
35.12 +#include <libgnomecanvasmm.h>
35.13 +#include <libgnomecanvasmm/polygon.h>
35.14 +
35.15 +class MapWin : public Gtk::Window
35.16 +{
35.17 +protected:
35.18 + GraphDisplayerCanvas & gdc;
35.19 + MapStorage & ms;
35.20 +
35.21 + Gtk::HBox * radios;
35.22 + Gtk::RadioButton ** rb_array;
35.23 +
35.24 + Gtk::VBox vbox_b, * vbox_r1, * vbox_r2;
35.25 + Gtk::Notebook notebook;
35.26 + Gtk::Label * labels;
35.27 +
35.28 +public:
35.29 + MapWin(const std::string& title, MapStorage &, GraphDisplayerCanvas &);
35.30 + virtual void radio_click(int, int);
35.31 +};
35.32 +
35.33 +#endif //MAP_WIN_H
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/gui/mapstorage.cc Mon May 23 04:48:14 2005 +0000
36.3 @@ -0,0 +1,89 @@
36.4 +#include <mapstorage.h>
36.5 +
36.6 +MapStorage::MapStorage(Graph & graph):g(graph)
36.7 +{
36.8 + for(int i=0;i<PROPERTY_NUM;i++)
36.9 + {
36.10 + Graph::EdgeMap<double> emd(g);
36.11 + default_edgemaps.push_back(emd);
36.12 + Graph::NodeMap<double> nmd(g);
36.13 + default_nodemaps.push_back(nmd);
36.14 + }
36.15 +
36.16 + //std::string defaultstr="Default ";
36.17 + for(int i=0;i<PROPERTY_NUM;i++)
36.18 + {
36.19 + for (EdgeIt j(g); j!=INVALID; ++j)
36.20 + {
36.21 + (default_edgemaps[i])[j]=property_defaults[i];
36.22 + }
36.23 + addEdgeMap(property_strings[i],&(default_edgemaps[i]));
36.24 + }
36.25 +
36.26 +};
36.27 +
36.28 +int MapStorage::addNodeMap(const std::string & name, Graph::NodeMap<double> *nodemap)
36.29 +{
36.30 + nodemap_storage[name]=nodemap;
36.31 + return 0;
36.32 +}
36.33 +int MapStorage::addEdgeMap(const std::string & name, Graph::EdgeMap<double> *edgemap)
36.34 +{
36.35 + edgemap_storage[name]=edgemap;
36.36 + return 0;
36.37 +}
36.38 +
36.39 +double MapStorage::maxOfNodeMap(const std::string & name)
36.40 +{
36.41 + double max=0;
36.42 + for (NodeIt j(g); j!=INVALID; ++j)
36.43 + {
36.44 + if( (*nodemap_storage[name])[j]>max )
36.45 + {
36.46 + max=(*nodemap_storage[name])[j];
36.47 + }
36.48 + }
36.49 + return max;
36.50 +}
36.51 +
36.52 +double MapStorage::maxOfEdgeMap(const std::string & name)
36.53 +{
36.54 + double max=0;
36.55 + for (EdgeIt j(g); j!=INVALID; ++j)
36.56 + {
36.57 + if( (*edgemap_storage[name])[j]>max )
36.58 + {
36.59 + max=(*edgemap_storage[name])[j];
36.60 + }
36.61 + }
36.62 + return max;
36.63 +}
36.64 +
36.65 +double MapStorage::minOfNodeMap(const std::string & name)
36.66 +{
36.67 + NodeIt j(g);
36.68 + double min=(*nodemap_storage[name])[j];
36.69 + for (; j!=INVALID; ++j)
36.70 + {
36.71 + if( (*nodemap_storage[name])[j]<min )
36.72 + {
36.73 + min=(*nodemap_storage[name])[j];
36.74 + }
36.75 + }
36.76 + return min;
36.77 +}
36.78 +
36.79 +double MapStorage::minOfEdgeMap(const std::string & name)
36.80 +{
36.81 + EdgeIt j(g);
36.82 + double min=(*edgemap_storage[name])[j];
36.83 + for (EdgeIt j(g); j!=INVALID; ++j)
36.84 + {
36.85 + if( (*edgemap_storage[name])[j]<min )
36.86 + {
36.87 + min=(*edgemap_storage[name])[j];
36.88 + }
36.89 + }
36.90 + return min;
36.91 +}
36.92 +
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/gui/mapstorage.h Mon May 23 04:48:14 2005 +0000
37.3 @@ -0,0 +1,37 @@
37.4 +// -*- C++ -*- //
37.5 +
37.6 +#ifndef MAPSTORAGE_H
37.7 +#define MAPSTORAGE_H
37.8 +
37.9 +#include <all_include.h>
37.10 +
37.11 +class MapStorage
37.12 +{
37.13 +
37.14 +public: ///!!!!!!!!
37.15 + Graph g;
37.16 + std::map< std::string,Graph::NodeMap<double> * > nodemap_storage;
37.17 + std::map< std::string,Graph::EdgeMap<double> * > edgemap_storage;
37.18 +
37.19 + std::vector<Graph::NodeMap<double> > default_nodemaps;
37.20 + std::vector<Graph::EdgeMap<double> > default_edgemaps;
37.21 +
37.22 +public:
37.23 + MapStorage(Graph &);
37.24 + int addNodeMap(const std::string &,Graph::NodeMap<double> *);
37.25 + int addEdgeMap(const std::string &,Graph::EdgeMap<double> *);
37.26 +
37.27 + int numOfNodeMaps() {return nodemap_storage.size();};
37.28 + int numOfEdgeMaps() {return edgemap_storage.size();};
37.29 +
37.30 + double maxOfNodeMap(const std::string &);
37.31 + double maxOfEdgeMap(const std::string &);
37.32 +
37.33 + double minOfNodeMap(const std::string &);
37.34 + double minOfEdgeMap(const std::string &);
37.35 +
37.36 + std::map< std::string,Graph::NodeMap<double> * >::iterator beginOfNodeMaps(){return nodemap_storage.begin();};
37.37 + std::map< std::string,Graph::EdgeMap<double> * >::iterator beginOfEdgeMaps(){return edgemap_storage.begin();};
37.38 +};
37.39 +
37.40 +#endif //MAPSTORAGE_H
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/gui/xml.h Mon May 23 04:48:14 2005 +0000
38.3 @@ -0,0 +1,442 @@
38.4 +/* -*- C++ -*- */
38.5 +
38.6 +#include <iostream>
38.7 +#include <string>
38.8 +#include <vector>
38.9 +#include <list>
38.10 +#include <map>
38.11 +#include <lemon/xy.h>
38.12 +
38.13 +class XmlWriter
38.14 +{
38.15 + std::ostream& os;
38.16 + int level;
38.17 +
38.18 +protected:
38.19 + void indent(int level) {
38.20 + os << std::endl;
38.21 + for(int i=0;i<level;i++) os << ' ';
38.22 + }
38.23 + void tag(const std::string &_tag) {
38.24 + os << '<' << _tag << '>';
38.25 + }
38.26 + void etag(const std::string &_tag) {
38.27 + os << "</" << _tag << '>';
38.28 + }
38.29 + void itag(const std::string &_tag) { indent();tag(_tag); }
38.30 + void ietag(const std::string &_tag) { indent();etag(_tag); }
38.31 +
38.32 + void beginTag(const std::string &_tag) {
38.33 + itag(_tag);
38.34 + level++;
38.35 + }
38.36 + void endTag(const std::string &_tag) {
38.37 + level--;
38.38 + ietag(_tag);
38.39 + }
38.40 +
38.41 +public:
38.42 +
38.43 + void indent()
38.44 + {
38.45 + if(level>=0) indent(level);
38.46 + else level=0;
38.47 + }
38.48 +
38.49 + ///\e
38.50 +
38.51 + ///\e
38.52 + ///
38.53 + class ContTag
38.54 + {
38.55 + XmlWriter &ix;
38.56 + const std::string _tag;
38.57 + public:
38.58 + ///\e
38.59 +
38.60 + ///\e
38.61 + ///
38.62 + ContTag(XmlWriter &_ix,const std::string &_t) :
38.63 + ix(_ix), _tag(_t)
38.64 + {
38.65 + ix.tag(_tag);
38.66 + }
38.67 + ~ContTag() { ix.etag(_tag);}
38.68 + };
38.69 +
38.70 + class LineTag
38.71 + {
38.72 + XmlWriter &ix;
38.73 + const std::string _tag;
38.74 + public:
38.75 + ///\e
38.76 +
38.77 + ///\e
38.78 + ///
38.79 + LineTag(XmlWriter &_ix,const std::string &_t) :
38.80 + ix(_ix), _tag(_t)
38.81 + {
38.82 + ix.itag(_tag);
38.83 + }
38.84 + ~LineTag() { ix.etag(_tag);}
38.85 + };
38.86 +
38.87 + ///\e
38.88 +
38.89 + ///\e
38.90 + ///
38.91 + class Tag
38.92 + {
38.93 + XmlWriter &ix;
38.94 + const std::string _tag;
38.95 + public:
38.96 + ///\e
38.97 +
38.98 + ///\e
38.99 + ///
38.100 + Tag(XmlWriter &_ix,const std::string &_t) :
38.101 + ix(_ix), _tag(_t)
38.102 + {
38.103 + ix.beginTag(_tag);
38.104 + }
38.105 + ~Tag() {
38.106 + ix.endTag(_tag);
38.107 + }
38.108 + };
38.109 +
38.110 + ///\e
38.111 +
38.112 + ///\e
38.113 + ///
38.114 + XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
38.115 + ~XmlWriter() { os<< std::endl; }
38.116 +
38.117 + XmlWriter &operator()(int v)
38.118 + {
38.119 + if(!(os << v)) throw (std::ios::failure ("data format error"));
38.120 + return *this;
38.121 + }
38.122 + XmlWriter &operator()(const std::string &_tag,int v)
38.123 + {
38.124 + LineTag t(*this,_tag);
38.125 + if(!(os << v)) throw (std::ios::failure ("data format error"));
38.126 + return *this;
38.127 + }
38.128 + XmlWriter &operator()(const std::string &_tag,double v)
38.129 + {
38.130 + LineTag t(*this,_tag);
38.131 + if(os << v) throw (std::ios::failure ("data format error"));
38.132 + return *this;
38.133 + }
38.134 + XmlWriter &operator()(double v)
38.135 + {
38.136 + os << v;
38.137 + return *this;
38.138 + }
38.139 + XmlWriter &operator()(const std::string &v)
38.140 + {
38.141 + for(std::string::const_iterator i=v.begin();i!=v.end();++i)
38.142 + switch(*i) {
38.143 + case '\\':
38.144 + os << "\\\\";
38.145 + break;
38.146 + case '<':
38.147 + os << "\\<";
38.148 + break;
38.149 + case '&':
38.150 + os << "\\&";
38.151 + break;
38.152 + case '\n':
38.153 + os << "\\n";
38.154 + break;
38.155 + default:
38.156 + os<<*i;
38.157 + break;
38.158 + }
38.159 + return *this;
38.160 + }
38.161 + XmlWriter &operator()(const std::string &_tag,const std::string &v)
38.162 + {
38.163 + LineTag t(*this,_tag);
38.164 + (*this)(v);
38.165 + return *this;
38.166 + }
38.167 + ///\e
38.168 +
38.169 + ///\e
38.170 + ///
38.171 + template<class V>
38.172 + XmlWriter &operator()(const std::string &_tag,const V &v)
38.173 + {
38.174 + Tag t(*this,_tag);
38.175 + out(*this,v);
38.176 + return *this;
38.177 + }
38.178 + ///\e
38.179 +
38.180 + ///\e
38.181 + ///
38.182 + template<class V>
38.183 + XmlWriter &operator()(const V &v)
38.184 + {
38.185 + out(*this,v);
38.186 + return *this;
38.187 + }
38.188 +};
38.189 +
38.190 +//////////////////////////////////////////////////////////////////////
38.191 +
38.192 +class XmlReader
38.193 +{
38.194 + std::istream& is;
38.195 +
38.196 + std::string next_tag;
38.197 + void skipWhiteSpaces()
38.198 + {
38.199 + char c;
38.200 + while (is.get(c) && std::isspace(c,is.getloc()));
38.201 + is.unget();
38.202 + }
38.203 +protected:
38.204 + ///\e
38.205 +
38.206 + ///\e
38.207 + ///
38.208 + void useTag() {next_tag.clear();}
38.209 +
38.210 + void useTag(const std::string &_tag) {
38.211 + if(nextTag()==_tag) useTag();
38.212 + else throw (std::ios::failure ("data format error"));
38.213 + }
38.214 +public:
38.215 + ///\e
38.216 +
38.217 + ///\e
38.218 + ///
38.219 + const std::string &nextTag()
38.220 + {
38.221 + if(next_tag.empty()) {
38.222 + char c;
38.223 + skipWhiteSpaces();
38.224 + if(!is.get(c) || c!='<')
38.225 + throw (std::ios::failure ("data format error"));
38.226 + next_tag.clear();
38.227 + while (is.get(c) && c!='>') next_tag.push_back(c);
38.228 + if(c!='>')
38.229 + throw (std::ios::failure ("data format error"));
38.230 + }
38.231 + return next_tag;
38.232 + }
38.233 +
38.234 + ///\e
38.235 +
38.236 + ///\e
38.237 + ///
38.238 + class Tag
38.239 + {
38.240 + XmlReader &ix;
38.241 + const std::string tag;
38.242 + public:
38.243 + ///\e
38.244 +
38.245 + ///\e
38.246 + ///
38.247 + Tag(XmlReader &_ix,const std::string &_tag) :
38.248 + ix(_ix), tag(_tag)
38.249 + {
38.250 + ix.useTag(_tag);
38.251 + }
38.252 + ~Tag() {
38.253 + if(!std::uncaught_exception())
38.254 + ix.useTag('/'+tag);
38.255 + }
38.256 + };
38.257 +
38.258 + ///\e
38.259 +
38.260 + ///\e
38.261 + ///
38.262 + XmlReader(std::istream& _is) : is(_is) {}
38.263 +
38.264 + int operator()(const std::string &tag,int &v)
38.265 + {
38.266 + Tag t(*this,tag);
38.267 + if(!(is >> v)) throw (std::ios::failure ("data format error"));
38.268 + return v;
38.269 + }
38.270 + double operator()(const std::string &tag,double &v)
38.271 + {
38.272 + Tag t(*this,tag);
38.273 + if(!(is >> v)) throw (std::ios::failure ("data format error"));
38.274 + return v;
38.275 + }
38.276 + std::string &operator()(const std::string &tag,std::string &v)
38.277 + {
38.278 + Tag t(*this,tag);
38.279 + v.clear();
38.280 + char c;
38.281 + while (is.get(c) && c!='<')
38.282 + if(c=='\\')
38.283 + if(!is.get(c)) throw (std::ios::failure ("data format error"));
38.284 + else switch(c) {
38.285 + case 'n':
38.286 + v.push_back('\n');
38.287 + break;
38.288 + default:
38.289 + v.push_back(c);
38.290 + break;
38.291 + }
38.292 + else v.push_back(c);
38.293 + if(c!='<')
38.294 + throw (std::ios::failure ("data format error"));
38.295 + is.unget();
38.296 + return v;
38.297 + }
38.298 + ///\e
38.299 +
38.300 + ///\e
38.301 + ///
38.302 + template<class V>
38.303 + V &operator()(const std::string &tag,V &v)
38.304 + {
38.305 + Tag t(*this,tag);
38.306 + in(*this,v);
38.307 + return v;
38.308 + }
38.309 + ///\e
38.310 +
38.311 + ///\e
38.312 + ///
38.313 + template<class V>
38.314 + V &operator()(V &v)
38.315 + {
38.316 + in(*this,v);
38.317 + return v;
38.318 + }
38.319 + ///\e
38.320 +
38.321 + ///\e
38.322 + ///
38.323 + template<class V>
38.324 + V load(const std::string &tag)
38.325 + {
38.326 + Tag t(*this,tag);
38.327 + V v;
38.328 + (*this)(tag,v);
38.329 + return v;
38.330 + }
38.331 +};
38.332 +
38.333 +//////////////////////////////////////////////////////////////////////
38.334 +
38.335 +template<class A,class B>
38.336 +void out(XmlWriter &i,const std::pair<A,B> &v)
38.337 +{
38.338 + i("first",v.first);
38.339 + i("second",v.second);
38.340 +}
38.341 +
38.342 +template<class A,class B>
38.343 +void in(XmlReader &i,std::pair<A,B> &v)
38.344 +{
38.345 + i("first",v.first);
38.346 + i("second",v.second);
38.347 +}
38.348 +
38.349 +//////////////////////////////
38.350 +
38.351 +template<class T>
38.352 +void out(XmlWriter &i,const std::list<T> &v)
38.353 +{
38.354 + for(typename std::list<T>::const_iterator it=v.begin();
38.355 + it!=v.end();++it) i("item",*it);
38.356 +}
38.357 +
38.358 +template<class T>
38.359 +void in(XmlReader &i,std::list<T> &v)
38.360 +{
38.361 + while(i.nextTag()=="item")
38.362 + {
38.363 + v.push_back(T());
38.364 + i("item",v.back());
38.365 + }
38.366 +}
38.367 +
38.368 +//////////////////////////////
38.369 +
38.370 +template<class T>
38.371 +void out(XmlWriter &i,const std::vector<T> &v)
38.372 +{
38.373 + for(typename std::vector<T>::const_iterator it=v.begin();
38.374 + it!=v.end();++it) i("item",*it);
38.375 +}
38.376 +
38.377 +template<class T>
38.378 +void in(XmlReader &i,std::vector<T> &v)
38.379 +{
38.380 + while(i.nextTag()=="item")
38.381 + {
38.382 + v.push_back(T());
38.383 + i("item",v.back());
38.384 + }
38.385 +}
38.386 +
38.387 +//////////////////////////////
38.388 +
38.389 +template<class K,class V>
38.390 +void out(XmlWriter &i,const std::map<K,V> &v)
38.391 +{
38.392 + for(typename std::map<K,V>::const_iterator it=v.begin();
38.393 + it!=v.end();++it) i("item",*it);
38.394 +}
38.395 +
38.396 +template<class K,class V>
38.397 +void in(XmlReader &i,std::map<K,V> &v)
38.398 +{
38.399 + while(i.nextTag()=="item")
38.400 + {
38.401 + typename std::map<K,V>::value_type it;
38.402 + i("item",it);
38.403 + v.insert(it);
38.404 + }
38.405 +}
38.406 +
38.407 +//////////////////////////////
38.408 +
38.409 +template<class T>
38.410 +void out(XmlWriter &i,const lemon::xy<T> &v)
38.411 +{
38.412 +// i("x",v.x);
38.413 +// i("y",v.y);
38.414 + { XmlWriter::LineTag t(i,"x"); i(v.x); }
38.415 + { XmlWriter::ContTag t(i,"y"); i(v.y); }
38.416 +}
38.417 +
38.418 +template<class T>
38.419 +void in(XmlReader &i,lemon::xy<T> &v)
38.420 +{
38.421 + i("x",v.x);
38.422 + i("y",v.y);
38.423 +}
38.424 +
38.425 +//////////////////////////////
38.426 +
38.427 +template<class T>
38.428 +void out(XmlWriter &i,const lemon::BoundingBox<T> &v)
38.429 +{
38.430 + if(!v.empty()) {
38.431 + i("point",v.bottomLeft());
38.432 + if(v.bottomLeft()!=v.topRight()) i("point",v.topRight());
38.433 + }
38.434 +}
38.435 +
38.436 +template<class T>
38.437 +void in(XmlReader &i,lemon::BoundingBox<T> &v)
38.438 +{
38.439 + v.clear();
38.440 + while(i.nextTag()=="point") {
38.441 + lemon::xy<T> co;
38.442 + i("point",co);
38.443 + v+=co;
38.444 + }
38.445 +}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/lemon/Makefile.am Mon May 23 04:48:14 2005 +0000
39.3 @@ -0,0 +1,81 @@
39.4 +AM_CPPFLAGS = -I$(top_srcdir)
39.5 +
39.6 +pkgconfigdir = $(libdir)/pkgconfig
39.7 +pkgconfig_DATA = lemon.pc
39.8 +
39.9 +lib_LTLIBRARIES = libemon.la
39.10 +
39.11 +libemon_la_SOURCES = \
39.12 + lp_base.cc \
39.13 + lp_skeleton.cc
39.14 +libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
39.15 +libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS)
39.16 +
39.17 +if HAVE_GLPK
39.18 +libemon_la_SOURCES += lp_glpk.cc
39.19 +endif
39.20 +
39.21 +if HAVE_CPLEX
39.22 +libemon_la_SOURCES += lp_cplex.cc
39.23 +endif
39.24 +
39.25 +nobase_pkginclude_HEADERS = \
39.26 + bezier.h \
39.27 + bfs.h \
39.28 + dfs.h \
39.29 + bin_heap.h \
39.30 + config.h \
39.31 + dijkstra.h \
39.32 + dimacs.h \
39.33 + error.h \
39.34 + fib_heap.h \
39.35 + full_graph.h \
39.36 + graph_adaptor.h \
39.37 + graph_utils.h \
39.38 + graph_to_eps.h \
39.39 + invalid.h \
39.40 + kruskal.h \
39.41 + list_graph.h \
39.42 + lp_base.h \
39.43 + lp_cplex.h \
39.44 + lp_glpk.h \
39.45 + lp_skeleton.h \
39.46 + maps.h \
39.47 + max_matching.h \
39.48 + min_cost_flow.h \
39.49 + suurballe.h \
39.50 + preflow.h \
39.51 + path.h \
39.52 + radix_heap.h \
39.53 + smart_graph.h \
39.54 + time_measure.h \
39.55 + unionfind.h \
39.56 + xy.h \
39.57 + concept_check.h \
39.58 + utility.h \
39.59 + lemon_reader.h \
39.60 + lemon_writer.h \
39.61 + graph_reader.h \
39.62 + graph_writer.h \
39.63 + bits/alteration_notifier.h \
39.64 + bits/map_iterator.h \
39.65 + bits/array_map.h \
39.66 + bits/default_map.h \
39.67 + bits/extended_pair.h \
39.68 + bits/vector_map.h \
39.69 + bits/iterable_graph_extender.h \
39.70 + bits/extendable_graph_extender.h \
39.71 + bits/clearable_graph_extender.h \
39.72 + bits/erasable_graph_extender.h \
39.73 + bits/undir_graph_extender.h \
39.74 + bits/item_reader.h \
39.75 + bits/item_writer.h
39.76 +
39.77 +noinst_HEADERS = \
39.78 + concept/graph.h \
39.79 + concept/graph_component.h \
39.80 + concept/undir_graph.h \
39.81 + concept/sym_graph.h \
39.82 + concept/maps.h \
39.83 + concept/heap.h \
39.84 + concept/path.h
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/lemon/attic/debug.h Mon May 23 04:48:14 2005 +0000
40.3 @@ -0,0 +1,70 @@
40.4 +/* -*- C++ -*-
40.5 + * lemon/debug.h - Part of LEMON, a generic C++ optimization library
40.6 + *
40.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
40.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
40.9 + *
40.10 + * Permission to use, modify and distribute this software is granted
40.11 + * provided that this copyright notice appears in all copies. For
40.12 + * precise terms see the accompanying LICENSE file.
40.13 + *
40.14 + * This software is provided "AS IS" with no warranty of any kind,
40.15 + * express or implied, and with no claim as to its suitability for any
40.16 + * purpose.
40.17 + *
40.18 + */
40.19 +
40.20 +#ifndef LEMON_DEBUG_H
40.21 +#define LEMON_DEBUG_H
40.22 +
40.23 +//! \file
40.24 +//! \brief Basic definitions for debug control.
40.25 +
40.26 +namespace lemon {
40.27 +
40.28 + //! Debug mode for testing/debugging
40.29 +
40.30 + //! Use this debug mode if you want exhaustive range and consistency checks.
40.31 + //! It also produces verbose debug messages.
40.32 + struct DebugOn {
40.33 + //! Example: check whether the edges added to a path are adjacent
40.34 + static const bool consistensy_check = true;
40.35 +
40.36 + static const bool range_check = true;
40.37 +
40.38 + //! Examples: initialize maps with some value;
40.39 + //! after deleting an item from UnionFindEnum set its value in the
40.40 + //! corresponding map to NULL...
40.41 + static const bool ensure_safe_state = true;
40.42 +
40.43 + static const int verbose = 5;
40.44 + };
40.45 +
40.46 + //! Debug mode for turning off debug aids.
40.47 +
40.48 + //! This debud mode switches off all range and consistency checks,
40.49 + //! as well as the debug messages.
40.50 + //!
40.51 + struct DebugOff {
40.52 + static const bool consistensy_check = false;
40.53 + static const bool range_check = false;
40.54 + static const bool ensure_safe_state = false;
40.55 + static const int verbose = 0;
40.56 + };
40.57 +
40.58 +#ifdef DEBUG
40.59 + //! The default debug mode.
40.60 +
40.61 + //! The default debug mode.
40.62 + //!
40.63 + typedef DebugOn DefaultDebugMode;
40.64 +#else
40.65 + //! The default debug mode.
40.66 +
40.67 + //! The default debug mode.
40.68 + //!
40.69 + typedef DebugOff DefaultDebugMode;
40.70 +#endif
40.71 +
40.72 +}
40.73 +#endif // LEMON_DEBUG_H
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/lemon/bezier.h Mon May 23 04:48:14 2005 +0000
41.3 @@ -0,0 +1,147 @@
41.4 +/* -*- C++ -*-
41.5 + * lemon/bezier.h - Part of LEMON, a generic C++ optimization library
41.6 + *
41.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
41.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
41.9 + *
41.10 + * Permission to use, modify and distribute this software is granted
41.11 + * provided that this copyright notice appears in all copies. For
41.12 + * precise terms see the accompanying LICENSE file.
41.13 + *
41.14 + * This software is provided "AS IS" with no warranty of any kind,
41.15 + * express or implied, and with no claim as to its suitability for any
41.16 + * purpose.
41.17 + *
41.18 + */
41.19 +
41.20 +#ifndef LEMON_BEZIER_H
41.21 +#define LEMON_BEZIER_H
41.22 +
41.23 +///\ingroup misc
41.24 +///\file
41.25 +///\brief Classes to compute with Bezier curves.
41.26 +///
41.27 +///Up to now this file is used internally by \ref graph_to_eps.h
41.28 +///
41.29 +///\author Alpar Juttner
41.30 +
41.31 +#include<lemon/xy.h>
41.32 +
41.33 +namespace lemon {
41.34 +
41.35 +class BezierBase {
41.36 +public:
41.37 + typedef xy<double> xy;
41.38 +protected:
41.39 + static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
41.40 +};
41.41 +
41.42 +class Bezier1 : public BezierBase
41.43 +{
41.44 +public:
41.45 + xy p1,p2;
41.46 +
41.47 + Bezier1() {}
41.48 + Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
41.49 +
41.50 + xy operator()(double t) const
41.51 + {
41.52 + // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
41.53 + return conv(p1,p2,t);
41.54 + }
41.55 + Bezier1 before(double t) const
41.56 + {
41.57 + return Bezier1(p1,conv(p1,p2,t));
41.58 + }
41.59 +
41.60 + Bezier1 after(double t) const
41.61 + {
41.62 + return Bezier1(conv(p1,p2,t),p2);
41.63 + }
41.64 + Bezier1 revert() { return Bezier1(p2,p1);}
41.65 + Bezier1 operator()(double a,double b) { return before(b).after(a/b); }
41.66 + xy grad() { return p2-p1; }
41.67 + xy grad(double t) { return grad(); }
41.68 +
41.69 +};
41.70 +
41.71 +class Bezier2 : public BezierBase
41.72 +{
41.73 +public:
41.74 + xy p1,p2,p3;
41.75 +
41.76 + Bezier2() {}
41.77 + Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
41.78 + Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
41.79 + xy operator()(double t) const
41.80 + {
41.81 + // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
41.82 + return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
41.83 + }
41.84 + Bezier2 before(double t) const
41.85 + {
41.86 + xy q(conv(p1,p2,t));
41.87 + xy r(conv(p2,p3,t));
41.88 + return Bezier2(p1,q,conv(q,r,t));
41.89 + }
41.90 +
41.91 + Bezier2 after(double t) const
41.92 + {
41.93 + xy q(conv(p1,p2,t));
41.94 + xy r(conv(p2,p3,t));
41.95 + return Bezier2(conv(q,r,t),r,p3);
41.96 + }
41.97 + Bezier2 revert() { return Bezier2(p3,p2,p1);}
41.98 + Bezier2 operator()(double a,double b) { return before(b).after(a/b); }
41.99 + Bezier1 grad() { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
41.100 + xy grad(double t) { return grad()(t); }
41.101 +};
41.102 +
41.103 +class Bezier3 : public BezierBase
41.104 +{
41.105 +public:
41.106 + xy p1,p2,p3,p4;
41.107 +
41.108 + Bezier3() {}
41.109 + Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
41.110 + Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
41.111 + p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
41.112 + Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
41.113 + p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
41.114 +
41.115 + xy operator()(double t) const
41.116 + {
41.117 + // return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
41.118 + return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
41.119 + (3*t*t*(1-t))*p3+(t*t*t)*p4;
41.120 + }
41.121 + Bezier3 before(double t) const
41.122 + {
41.123 + xy p(conv(p1,p2,t));
41.124 + xy q(conv(p2,p3,t));
41.125 + xy r(conv(p3,p4,t));
41.126 + xy a(conv(p,q,t));
41.127 + xy b(conv(q,r,t));
41.128 + xy c(conv(a,b,t));
41.129 + return Bezier3(p1,p,a,c);
41.130 + }
41.131 +
41.132 + Bezier3 after(double t) const
41.133 + {
41.134 + xy p(conv(p1,p2,t));
41.135 + xy q(conv(p2,p3,t));
41.136 + xy r(conv(p3,p4,t));
41.137 + xy a(conv(p,q,t));
41.138 + xy b(conv(q,r,t));
41.139 + xy c(conv(a,b,t));
41.140 + return Bezier3(c,b,r,p4);
41.141 + }
41.142 + Bezier3 revert() { return Bezier3(p4,p3,p2,p1);}
41.143 + Bezier3 operator()(double a,double b) { return before(b).after(a/b); }
41.144 + Bezier2 grad() { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
41.145 + xy grad(double t) { return grad()(t); }
41.146 +};
41.147 +
41.148 +} //END OF NAMESPACE LEMON
41.149 +
41.150 +#endif // LEMON_BEZIER_H
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/lemon/bfs.h Mon May 23 04:48:14 2005 +0000
42.3 @@ -0,0 +1,1130 @@
42.4 +/* -*- C++ -*-
42.5 + * lemon/bfs.h - Part of LEMON, a generic C++ optimization library
42.6 + *
42.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
42.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
42.9 + *
42.10 + * Permission to use, modify and distribute this software is granted
42.11 + * provided that this copyright notice appears in all copies. For
42.12 + * precise terms see the accompanying LICENSE file.
42.13 + *
42.14 + * This software is provided "AS IS" with no warranty of any kind,
42.15 + * express or implied, and with no claim as to its suitability for any
42.16 + * purpose.
42.17 + *
42.18 + */
42.19 +
42.20 +#ifndef LEMON_BFS_H
42.21 +#define LEMON_BFS_H
42.22 +
42.23 +///\ingroup flowalgs
42.24 +///\file
42.25 +///\brief Bfs algorithm.
42.26 +
42.27 +#include <lemon/list_graph.h>
42.28 +#include <lemon/graph_utils.h>
42.29 +#include <lemon/invalid.h>
42.30 +#include <lemon/error.h>
42.31 +#include <lemon/maps.h>
42.32 +
42.33 +namespace lemon {
42.34 +
42.35 +
42.36 +
42.37 + ///Default traits class of Bfs class.
42.38 +
42.39 + ///Default traits class of Bfs class.
42.40 + ///\param GR Graph type.
42.41 + template<class GR>
42.42 + struct BfsDefaultTraits
42.43 + {
42.44 + ///The graph type the algorithm runs on.
42.45 + typedef GR Graph;
42.46 + ///\brief The type of the map that stores the last
42.47 + ///edges of the shortest paths.
42.48 + ///
42.49 + ///The type of the map that stores the last
42.50 + ///edges of the shortest paths.
42.51 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.52 + ///
42.53 + typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
42.54 + ///Instantiates a PredMap.
42.55 +
42.56 + ///This function instantiates a \ref PredMap.
42.57 + ///\param G is the graph, to which we would like to define the PredMap.
42.58 + ///\todo The graph alone may be insufficient to initialize
42.59 + static PredMap *createPredMap(const GR &G)
42.60 + {
42.61 + return new PredMap(G);
42.62 + }
42.63 +// ///\brief The type of the map that stores the last but one
42.64 +// ///nodes of the shortest paths.
42.65 +// ///
42.66 +// ///The type of the map that stores the last but one
42.67 +// ///nodes of the shortest paths.
42.68 +// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.69 +// ///
42.70 +// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
42.71 +// ///Instantiates a PredNodeMap.
42.72 +
42.73 +// ///This function instantiates a \ref PredNodeMap.
42.74 +// ///\param G is the graph, to which
42.75 +// ///we would like to define the \ref PredNodeMap
42.76 +// static PredNodeMap *createPredNodeMap(const GR &G)
42.77 +// {
42.78 +// return new PredNodeMap();
42.79 +// }
42.80 +
42.81 + ///The type of the map that indicates which nodes are processed.
42.82 +
42.83 + ///The type of the map that indicates which nodes are processed.
42.84 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.85 + ///\todo named parameter to set this type, function to read and write.
42.86 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
42.87 + ///Instantiates a ProcessedMap.
42.88 +
42.89 + ///This function instantiates a \ref ProcessedMap.
42.90 + ///\param G is the graph, to which
42.91 + ///we would like to define the \ref ProcessedMap
42.92 + static ProcessedMap *createProcessedMap(const GR &)
42.93 + {
42.94 + return new ProcessedMap();
42.95 + }
42.96 + ///The type of the map that indicates which nodes are reached.
42.97 +
42.98 + ///The type of the map that indicates which nodes are reached.
42.99 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.100 + ///\todo named parameter to set this type, function to read and write.
42.101 + typedef typename Graph::template NodeMap<bool> ReachedMap;
42.102 + ///Instantiates a ReachedMap.
42.103 +
42.104 + ///This function instantiates a \ref ReachedMap.
42.105 + ///\param G is the graph, to which
42.106 + ///we would like to define the \ref ReachedMap.
42.107 + static ReachedMap *createReachedMap(const GR &G)
42.108 + {
42.109 + return new ReachedMap(G);
42.110 + }
42.111 + ///The type of the map that stores the dists of the nodes.
42.112 +
42.113 + ///The type of the map that stores the dists of the nodes.
42.114 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.115 + ///
42.116 + typedef typename Graph::template NodeMap<int> DistMap;
42.117 + ///Instantiates a DistMap.
42.118 +
42.119 + ///This function instantiates a \ref DistMap.
42.120 + ///\param G is the graph, to which we would like to define the \ref DistMap
42.121 + static DistMap *createDistMap(const GR &G)
42.122 + {
42.123 + return new DistMap(G);
42.124 + }
42.125 + };
42.126 +
42.127 + ///%BFS algorithm class.
42.128 +
42.129 + ///\ingroup flowalgs
42.130 + ///This class provides an efficient implementation of the %BFS algorithm.
42.131 + ///
42.132 + ///\param GR The graph type the algorithm runs on. The default value is
42.133 + ///\ref ListGraph. The value of GR is not used directly by Bfs, it
42.134 + ///is only passed to \ref BfsDefaultTraits.
42.135 + ///\param TR Traits class to set various data types used by the algorithm.
42.136 + ///The default traits class is
42.137 + ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
42.138 + ///See \ref BfsDefaultTraits for the documentation of
42.139 + ///a Bfs traits class.
42.140 + ///
42.141 + ///\author Alpar Juttner
42.142 + ///\todo A compare object would be nice.
42.143 +
42.144 +#ifdef DOXYGEN
42.145 + template <typename GR,
42.146 + typename TR>
42.147 +#else
42.148 + template <typename GR=ListGraph,
42.149 + typename TR=BfsDefaultTraits<GR> >
42.150 +#endif
42.151 + class Bfs {
42.152 + public:
42.153 + /**
42.154 + * \brief \ref Exception for uninitialized parameters.
42.155 + *
42.156 + * This error represents problems in the initialization
42.157 + * of the parameters of the algorithms.
42.158 + */
42.159 + class UninitializedParameter : public lemon::UninitializedParameter {
42.160 + public:
42.161 + virtual const char* exceptionName() const {
42.162 + return "lemon::Bfs::UninitializedParameter";
42.163 + }
42.164 + };
42.165 +
42.166 + typedef TR Traits;
42.167 + ///The type of the underlying graph.
42.168 + typedef typename TR::Graph Graph;
42.169 + ///\e
42.170 + typedef typename Graph::Node Node;
42.171 + ///\e
42.172 + typedef typename Graph::NodeIt NodeIt;
42.173 + ///\e
42.174 + typedef typename Graph::Edge Edge;
42.175 + ///\e
42.176 + typedef typename Graph::OutEdgeIt OutEdgeIt;
42.177 +
42.178 + ///\brief The type of the map that stores the last
42.179 + ///edges of the shortest paths.
42.180 + typedef typename TR::PredMap PredMap;
42.181 +// ///\brief The type of the map that stores the last but one
42.182 +// ///nodes of the shortest paths.
42.183 +// typedef typename TR::PredNodeMap PredNodeMap;
42.184 + ///The type of the map indicating which nodes are reached.
42.185 + typedef typename TR::ReachedMap ReachedMap;
42.186 + ///The type of the map indicating which nodes are processed.
42.187 + typedef typename TR::ProcessedMap ProcessedMap;
42.188 + ///The type of the map that stores the dists of the nodes.
42.189 + typedef typename TR::DistMap DistMap;
42.190 + private:
42.191 + /// Pointer to the underlying graph.
42.192 + const Graph *G;
42.193 + ///Pointer to the map of predecessors edges.
42.194 + PredMap *_pred;
42.195 + ///Indicates if \ref _pred is locally allocated (\c true) or not.
42.196 + bool local_pred;
42.197 +// ///Pointer to the map of predecessors nodes.
42.198 +// PredNodeMap *_predNode;
42.199 +// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
42.200 +// bool local_predNode;
42.201 + ///Pointer to the map of distances.
42.202 + DistMap *_dist;
42.203 + ///Indicates if \ref _dist is locally allocated (\c true) or not.
42.204 + bool local_dist;
42.205 + ///Pointer to the map of reached status of the nodes.
42.206 + ReachedMap *_reached;
42.207 + ///Indicates if \ref _reached is locally allocated (\c true) or not.
42.208 + bool local_reached;
42.209 + ///Pointer to the map of processed status of the nodes.
42.210 + ProcessedMap *_processed;
42.211 + ///Indicates if \ref _processed is locally allocated (\c true) or not.
42.212 + bool local_processed;
42.213 +
42.214 + std::vector<typename Graph::Node> _queue;
42.215 + int _queue_head,_queue_tail,_queue_next_dist;
42.216 + int _curr_dist;
42.217 +// ///The source node of the last execution.
42.218 +// Node source;
42.219 +
42.220 + ///Creates the maps if necessary.
42.221 +
42.222 + ///\todo Error if \c G are \c NULL.
42.223 + ///\todo Better memory allocation (instead of new).
42.224 + void create_maps()
42.225 + {
42.226 + if(!_pred) {
42.227 + local_pred = true;
42.228 + _pred = Traits::createPredMap(*G);
42.229 + }
42.230 +// if(!_predNode) {
42.231 +// local_predNode = true;
42.232 +// _predNode = Traits::createPredNodeMap(*G);
42.233 +// }
42.234 + if(!_dist) {
42.235 + local_dist = true;
42.236 + _dist = Traits::createDistMap(*G);
42.237 + }
42.238 + if(!_reached) {
42.239 + local_reached = true;
42.240 + _reached = Traits::createReachedMap(*G);
42.241 + }
42.242 + if(!_processed) {
42.243 + local_processed = true;
42.244 + _processed = Traits::createProcessedMap(*G);
42.245 + }
42.246 + }
42.247 +
42.248 + public :
42.249 +
42.250 + ///\name Named template parameters
42.251 +
42.252 + ///@{
42.253 +
42.254 + template <class T>
42.255 + struct DefPredMapTraits : public Traits {
42.256 + typedef T PredMap;
42.257 + static PredMap *createPredMap(const Graph &G)
42.258 + {
42.259 + throw UninitializedParameter();
42.260 + }
42.261 + };
42.262 + ///\ref named-templ-param "Named parameter" for setting PredMap type
42.263 +
42.264 + ///\ref named-templ-param "Named parameter" for setting PredMap type
42.265 + ///
42.266 + template <class T>
42.267 + class DefPredMap : public Bfs< Graph,
42.268 + DefPredMapTraits<T> > { };
42.269 +
42.270 +// template <class T>
42.271 +// struct DefPredNodeMapTraits : public Traits {
42.272 +// typedef T PredNodeMap;
42.273 +// static PredNodeMap *createPredNodeMap(const Graph &G)
42.274 +// {
42.275 +// throw UninitializedParameter();
42.276 +// }
42.277 +// };
42.278 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
42.279 +
42.280 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
42.281 +// ///
42.282 +// template <class T>
42.283 +// class DefPredNodeMap : public Bfs< Graph,
42.284 +// LengthMap,
42.285 +// DefPredNodeMapTraits<T> > { };
42.286 +
42.287 + template <class T>
42.288 + struct DefDistMapTraits : public Traits {
42.289 + typedef T DistMap;
42.290 + static DistMap *createDistMap(const Graph &G)
42.291 + {
42.292 + throw UninitializedParameter();
42.293 + }
42.294 + };
42.295 + ///\ref named-templ-param "Named parameter" for setting DistMap type
42.296 +
42.297 + ///\ref named-templ-param "Named parameter" for setting DistMap type
42.298 + ///
42.299 + template <class T>
42.300 + class DefDistMap : public Bfs< Graph,
42.301 + DefDistMapTraits<T> > { };
42.302 +
42.303 + template <class T>
42.304 + struct DefReachedMapTraits : public Traits {
42.305 + typedef T ReachedMap;
42.306 + static ReachedMap *createReachedMap(const Graph &G)
42.307 + {
42.308 + throw UninitializedParameter();
42.309 + }
42.310 + };
42.311 + ///\ref named-templ-param "Named parameter" for setting ReachedMap type
42.312 +
42.313 + ///\ref named-templ-param "Named parameter" for setting ReachedMap type
42.314 + ///
42.315 + template <class T>
42.316 + class DefReachedMap : public Bfs< Graph,
42.317 + DefReachedMapTraits<T> > { };
42.318 +
42.319 + struct DefGraphReachedMapTraits : public Traits {
42.320 + typedef typename Graph::template NodeMap<bool> ReachedMap;
42.321 + static ReachedMap *createReachedMap(const Graph &G)
42.322 + {
42.323 + return new ReachedMap(G);
42.324 + }
42.325 + };
42.326 + template <class T>
42.327 + struct DefProcessedMapTraits : public Traits {
42.328 + typedef T ProcessedMap;
42.329 + static ProcessedMap *createProcessedMap(const Graph &G)
42.330 + {
42.331 + throw UninitializedParameter();
42.332 + }
42.333 + };
42.334 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
42.335 +
42.336 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
42.337 + ///
42.338 + template <class T>
42.339 + class DefProcessedMap : public Bfs< Graph,
42.340 + DefProcessedMapTraits<T> > { };
42.341 +
42.342 + struct DefGraphProcessedMapTraits : public Traits {
42.343 + typedef typename Graph::template NodeMap<bool> ProcessedMap;
42.344 + static ProcessedMap *createProcessedMap(const Graph &G)
42.345 + {
42.346 + return new ProcessedMap(G);
42.347 + }
42.348 + };
42.349 + ///\brief \ref named-templ-param "Named parameter"
42.350 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
42.351 + ///
42.352 + ///\ref named-templ-param "Named parameter"
42.353 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
42.354 + ///If you don't set it explicitly, it will be automatically allocated.
42.355 + template <class T>
42.356 + class DefProcessedMapToBeDefaultMap :
42.357 + public Bfs< Graph,
42.358 + DefGraphProcessedMapTraits> { };
42.359 +
42.360 + ///@}
42.361 +
42.362 + public:
42.363 +
42.364 + ///Constructor.
42.365 +
42.366 + ///\param _G the graph the algorithm will run on.
42.367 + ///
42.368 + Bfs(const Graph& _G) :
42.369 + G(&_G),
42.370 + _pred(NULL), local_pred(false),
42.371 +// _predNode(NULL), local_predNode(false),
42.372 + _dist(NULL), local_dist(false),
42.373 + _reached(NULL), local_reached(false),
42.374 + _processed(NULL), local_processed(false)
42.375 + { }
42.376 +
42.377 + ///Destructor.
42.378 + ~Bfs()
42.379 + {
42.380 + if(local_pred) delete _pred;
42.381 +// if(local_predNode) delete _predNode;
42.382 + if(local_dist) delete _dist;
42.383 + if(local_reached) delete _reached;
42.384 + if(local_processed) delete _processed;
42.385 + }
42.386 +
42.387 + ///Sets the map storing the predecessor edges.
42.388 +
42.389 + ///Sets the map storing the predecessor edges.
42.390 + ///If you don't use this function before calling \ref run(),
42.391 + ///it will allocate one. The destructor deallocates this
42.392 + ///automatically allocated map, of course.
42.393 + ///\return <tt> (*this) </tt>
42.394 + Bfs &predMap(PredMap &m)
42.395 + {
42.396 + if(local_pred) {
42.397 + delete _pred;
42.398 + local_pred=false;
42.399 + }
42.400 + _pred = &m;
42.401 + return *this;
42.402 + }
42.403 +
42.404 + ///Sets the map indicating the reached nodes.
42.405 +
42.406 + ///Sets the map indicating the reached nodes.
42.407 + ///If you don't use this function before calling \ref run(),
42.408 + ///it will allocate one. The destructor deallocates this
42.409 + ///automatically allocated map, of course.
42.410 + ///\return <tt> (*this) </tt>
42.411 + Bfs &reachedMap(ReachedMap &m)
42.412 + {
42.413 + if(local_reached) {
42.414 + delete _reached;
42.415 + local_reached=false;
42.416 + }
42.417 + _reached = &m;
42.418 + return *this;
42.419 + }
42.420 +
42.421 + ///Sets the map indicating the processed nodes.
42.422 +
42.423 + ///Sets the map indicating the processed nodes.
42.424 + ///If you don't use this function before calling \ref run(),
42.425 + ///it will allocate one. The destructor deallocates this
42.426 + ///automatically allocated map, of course.
42.427 + ///\return <tt> (*this) </tt>
42.428 + Bfs &processedMap(ProcessedMap &m)
42.429 + {
42.430 + if(local_processed) {
42.431 + delete _processed;
42.432 + local_processed=false;
42.433 + }
42.434 + _processed = &m;
42.435 + return *this;
42.436 + }
42.437 +
42.438 +// ///Sets the map storing the predecessor nodes.
42.439 +
42.440 +// ///Sets the map storing the predecessor nodes.
42.441 +// ///If you don't use this function before calling \ref run(),
42.442 +// ///it will allocate one. The destructor deallocates this
42.443 +// ///automatically allocated map, of course.
42.444 +// ///\return <tt> (*this) </tt>
42.445 +// Bfs &predNodeMap(PredNodeMap &m)
42.446 +// {
42.447 +// if(local_predNode) {
42.448 +// delete _predNode;
42.449 +// local_predNode=false;
42.450 +// }
42.451 +// _predNode = &m;
42.452 +// return *this;
42.453 +// }
42.454 +
42.455 + ///Sets the map storing the distances calculated by the algorithm.
42.456 +
42.457 + ///Sets the map storing the distances calculated by the algorithm.
42.458 + ///If you don't use this function before calling \ref run(),
42.459 + ///it will allocate one. The destructor deallocates this
42.460 + ///automatically allocated map, of course.
42.461 + ///\return <tt> (*this) </tt>
42.462 + Bfs &distMap(DistMap &m)
42.463 + {
42.464 + if(local_dist) {
42.465 + delete _dist;
42.466 + local_dist=false;
42.467 + }
42.468 + _dist = &m;
42.469 + return *this;
42.470 + }
42.471 +
42.472 + public:
42.473 + ///\name Execution control
42.474 + ///The simplest way to execute the algorithm is to use
42.475 + ///one of the member functions called \c run(...).
42.476 + ///\n
42.477 + ///If you need more control on the execution,
42.478 + ///first you must call \ref init(), then you can add several source nodes
42.479 + ///with \ref addSource().
42.480 + ///Finally \ref start() will perform the actual path
42.481 + ///computation.
42.482 +
42.483 + ///@{
42.484 +
42.485 + ///Initializes the internal data structures.
42.486 +
42.487 + ///Initializes the internal data structures.
42.488 + ///
42.489 + void init()
42.490 + {
42.491 + create_maps();
42.492 + _queue.resize(countNodes(*G));
42.493 + _queue_head=_queue_tail=0;
42.494 + _curr_dist=1;
42.495 + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
42.496 + _pred->set(u,INVALID);
42.497 +// _predNode->set(u,INVALID);
42.498 + _reached->set(u,false);
42.499 + _processed->set(u,false);
42.500 + }
42.501 + }
42.502 +
42.503 + ///Adds a new source node.
42.504 +
42.505 + ///Adds a new source node to the set of nodes to be processed.
42.506 + ///
42.507 + void addSource(Node s)
42.508 + {
42.509 + if(!(*_reached)[s])
42.510 + {
42.511 + _reached->set(s,true);
42.512 + _pred->set(s,INVALID);
42.513 + _dist->set(s,0);
42.514 + _queue[_queue_head++]=s;
42.515 + _queue_next_dist=_queue_head;
42.516 + }
42.517 + }
42.518 +
42.519 + ///Processes the next node.
42.520 +
42.521 + ///Processes the next node.
42.522 + ///
42.523 + ///\warning The queue must not be empty!
42.524 + void processNextNode()
42.525 + {
42.526 + if(_queue_tail==_queue_next_dist) {
42.527 + _curr_dist++;
42.528 + _queue_next_dist=_queue_head;
42.529 + }
42.530 + Node n=_queue[_queue_tail++];
42.531 + _processed->set(n,true);
42.532 + Node m;
42.533 + for(OutEdgeIt e(*G,n);e!=INVALID;++e)
42.534 + if(!(*_reached)[m=G->target(e)]) {
42.535 + _queue[_queue_head++]=m;
42.536 + _reached->set(m,true);
42.537 + _pred->set(m,e);
42.538 +// _pred_node->set(m,n);
42.539 + _dist->set(m,_curr_dist);
42.540 + }
42.541 + }
42.542 +
42.543 + ///\brief Returns \c false if there are nodes
42.544 + ///to be processed in the queue
42.545 + ///
42.546 + ///Returns \c false if there are nodes
42.547 + ///to be processed in the queue
42.548 + bool emptyQueue() { return _queue_tail==_queue_head; }
42.549 + ///Returns the number of the nodes to be processed.
42.550 +
42.551 + ///Returns the number of the nodes to be processed in the queue.
42.552 + ///
42.553 + int queueSize() { return _queue_head-_queue_tail; }
42.554 +
42.555 + ///Executes the algorithm.
42.556 +
42.557 + ///Executes the algorithm.
42.558 + ///
42.559 + ///\pre init() must be called and at least one node should be added
42.560 + ///with addSource() before using this function.
42.561 + ///
42.562 + ///This method runs the %BFS algorithm from the root node(s)
42.563 + ///in order to
42.564 + ///compute the
42.565 + ///shortest path to each node. The algorithm computes
42.566 + ///- The shortest path tree.
42.567 + ///- The distance of each node from the root(s).
42.568 + ///
42.569 + void start()
42.570 + {
42.571 + while ( !emptyQueue() ) processNextNode();
42.572 + }
42.573 +
42.574 + ///Executes the algorithm until \c dest is reached.
42.575 +
42.576 + ///Executes the algorithm until \c dest is reached.
42.577 + ///
42.578 + ///\pre init() must be called and at least one node should be added
42.579 + ///with addSource() before using this function.
42.580 + ///
42.581 + ///This method runs the %BFS algorithm from the root node(s)
42.582 + ///in order to
42.583 + ///compute the
42.584 + ///shortest path to \c dest. The algorithm computes
42.585 + ///- The shortest path to \c dest.
42.586 + ///- The distance of \c dest from the root(s).
42.587 + ///
42.588 + void start(Node dest)
42.589 + {
42.590 + while ( !emptyQueue() && _queue[_queue_tail]!=dest ) processNextNode();
42.591 + }
42.592 +
42.593 + ///Executes the algorithm until a condition is met.
42.594 +
42.595 + ///Executes the algorithm until a condition is met.
42.596 + ///
42.597 + ///\pre init() must be called and at least one node should be added
42.598 + ///with addSource() before using this function.
42.599 + ///
42.600 + ///\param nm must be a bool (or convertible) node map. The algorithm
42.601 + ///will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
42.602 + template<class NM>
42.603 + void start(const NM &nm)
42.604 + {
42.605 + while ( !emptyQueue() && !nm[_queue[_queue_tail]] ) processNextNode();
42.606 + }
42.607 +
42.608 + ///Runs %BFS algorithm from node \c s.
42.609 +
42.610 + ///This method runs the %BFS algorithm from a root node \c s
42.611 + ///in order to
42.612 + ///compute the
42.613 + ///shortest path to each node. The algorithm computes
42.614 + ///- The shortest path tree.
42.615 + ///- The distance of each node from the root.
42.616 + ///
42.617 + ///\note d.run(s) is just a shortcut of the following code.
42.618 + ///\code
42.619 + /// d.init();
42.620 + /// d.addSource(s);
42.621 + /// d.start();
42.622 + ///\endcode
42.623 + void run(Node s) {
42.624 + init();
42.625 + addSource(s);
42.626 + start();
42.627 + }
42.628 +
42.629 + ///Finds the shortest path between \c s and \c t.
42.630 +
42.631 + ///Finds the shortest path between \c s and \c t.
42.632 + ///
42.633 + ///\return The length of the shortest s---t path if there exists one,
42.634 + ///0 otherwise.
42.635 + ///\note Apart from the return value, d.run(s) is
42.636 + ///just a shortcut of the following code.
42.637 + ///\code
42.638 + /// d.init();
42.639 + /// d.addSource(s);
42.640 + /// d.start(t);
42.641 + ///\endcode
42.642 + int run(Node s,Node t) {
42.643 + init();
42.644 + addSource(s);
42.645 + start(t);
42.646 + return reached(t)?_curr_dist-1+(_queue_tail==_queue_next_dist):0;
42.647 + }
42.648 +
42.649 + ///@}
42.650 +
42.651 + ///\name Query Functions
42.652 + ///The result of the %BFS algorithm can be obtained using these
42.653 + ///functions.\n
42.654 + ///Before the use of these functions,
42.655 + ///either run() or start() must be called.
42.656 +
42.657 + ///@{
42.658 +
42.659 + ///Copies the shortest path to \c t into \c p
42.660 +
42.661 + ///This function copies the shortest path to \c t into \c p.
42.662 + ///If it \c \t is a source itself or unreachable, then it does not
42.663 + ///alter \c p.
42.664 + ///\todo Is it the right way to handle unreachable nodes?
42.665 + ///\return Returns \c true if a path to \c t was actually copied to \c p,
42.666 + ///\c false otherwise.
42.667 + ///\sa DirPath
42.668 + template<class P>
42.669 + bool getPath(P &p,Node t)
42.670 + {
42.671 + if(reached(t)) {
42.672 + p.clear();
42.673 + typename P::Builder b(p);
42.674 + for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
42.675 + b.pushFront(pred(t));
42.676 + b.commit();
42.677 + return true;
42.678 + }
42.679 + return false;
42.680 + }
42.681 +
42.682 + ///The distance of a node from the root(s).
42.683 +
42.684 + ///Returns the distance of a node from the root(s).
42.685 + ///\pre \ref run() must be called before using this function.
42.686 + ///\warning If node \c v in unreachable from the root(s) the return value
42.687 + ///of this function is undefined.
42.688 + int dist(Node v) const { return (*_dist)[v]; }
42.689 +
42.690 + ///Returns the 'previous edge' of the shortest path tree.
42.691 +
42.692 + ///For a node \c v it returns the 'previous edge'
42.693 + ///of the shortest path tree,
42.694 + ///i.e. it returns the last edge of a shortest path from the root(s) to \c
42.695 + ///v. It is \ref INVALID
42.696 + ///if \c v is unreachable from the root(s) or \c v is a root. The
42.697 + ///shortest path tree used here is equal to the shortest path tree used in
42.698 + ///\ref predNode(Node v).
42.699 + ///\pre Either \ref run() or \ref start() must be called before using
42.700 + ///this function.
42.701 + ///\todo predEdge could be a better name.
42.702 + Edge pred(Node v) const { return (*_pred)[v];}
42.703 +
42.704 + ///Returns the 'previous node' of the shortest path tree.
42.705 +
42.706 + ///For a node \c v it returns the 'previous node'
42.707 + ///of the shortest path tree,
42.708 + ///i.e. it returns the last but one node from a shortest path from the
42.709 + ///root(a) to \c /v.
42.710 + ///It is INVALID if \c v is unreachable from the root(s) or
42.711 + ///if \c v itself a root.
42.712 + ///The shortest path tree used here is equal to the shortest path
42.713 + ///tree used in \ref pred(Node v).
42.714 + ///\pre Either \ref run() or \ref start() must be called before
42.715 + ///using this function.
42.716 + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
42.717 + G->source((*_pred)[v]); }
42.718 +
42.719 + ///Returns a reference to the NodeMap of distances.
42.720 +
42.721 + ///Returns a reference to the NodeMap of distances.
42.722 + ///\pre Either \ref run() or \ref init() must
42.723 + ///be called before using this function.
42.724 + const DistMap &distMap() const { return *_dist;}
42.725 +
42.726 + ///Returns a reference to the shortest path tree map.
42.727 +
42.728 + ///Returns a reference to the NodeMap of the edges of the
42.729 + ///shortest path tree.
42.730 + ///\pre Either \ref run() or \ref init()
42.731 + ///must be called before using this function.
42.732 + const PredMap &predMap() const { return *_pred;}
42.733 +
42.734 +// ///Returns a reference to the map of nodes of shortest paths.
42.735 +
42.736 +// ///Returns a reference to the NodeMap of the last but one nodes of the
42.737 +// ///shortest path tree.
42.738 +// ///\pre \ref run() must be called before using this function.
42.739 +// const PredNodeMap &predNodeMap() const { return *_predNode;}
42.740 +
42.741 + ///Checks if a node is reachable from the root.
42.742 +
42.743 + ///Returns \c true if \c v is reachable from the root.
42.744 + ///\warning The source nodes are indicated as unreached.
42.745 + ///\pre Either \ref run() or \ref start()
42.746 + ///must be called before using this function.
42.747 + ///
42.748 + bool reached(Node v) { return (*_reached)[v]; }
42.749 +
42.750 + ///@}
42.751 + };
42.752 +
42.753 + ///Default traits class of Bfs function.
42.754 +
42.755 + ///Default traits class of Bfs function.
42.756 + ///\param GR Graph type.
42.757 + template<class GR>
42.758 + struct BfsWizardDefaultTraits
42.759 + {
42.760 + ///The graph type the algorithm runs on.
42.761 + typedef GR Graph;
42.762 + ///\brief The type of the map that stores the last
42.763 + ///edges of the shortest paths.
42.764 + ///
42.765 + ///The type of the map that stores the last
42.766 + ///edges of the shortest paths.
42.767 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.768 + ///
42.769 + typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
42.770 + ///Instantiates a PredMap.
42.771 +
42.772 + ///This function instantiates a \ref PredMap.
42.773 + ///\param G is the graph, to which we would like to define the PredMap.
42.774 + ///\todo The graph alone may be insufficient to initialize
42.775 + static PredMap *createPredMap(const GR &)
42.776 + {
42.777 + return new PredMap();
42.778 + }
42.779 +// ///\brief The type of the map that stores the last but one
42.780 +// ///nodes of the shortest paths.
42.781 +// ///
42.782 +// ///The type of the map that stores the last but one
42.783 +// ///nodes of the shortest paths.
42.784 +// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.785 +// ///
42.786 +// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
42.787 +// ///Instantiates a PredNodeMap.
42.788 +
42.789 +// ///This function instantiates a \ref PredNodeMap.
42.790 +// ///\param G is the graph, to which
42.791 +// ///we would like to define the \ref PredNodeMap
42.792 +// static PredNodeMap *createPredNodeMap(const GR &G)
42.793 +// {
42.794 +// return new PredNodeMap();
42.795 +// }
42.796 +
42.797 + ///The type of the map that indicates which nodes are processed.
42.798 +
42.799 + ///The type of the map that indicates which nodes are processed.
42.800 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.801 + ///\todo named parameter to set this type, function to read and write.
42.802 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
42.803 + ///Instantiates a ProcessedMap.
42.804 +
42.805 + ///This function instantiates a \ref ProcessedMap.
42.806 + ///\param G is the graph, to which
42.807 + ///we would like to define the \ref ProcessedMap
42.808 + static ProcessedMap *createProcessedMap(const GR &)
42.809 + {
42.810 + return new ProcessedMap();
42.811 + }
42.812 + ///The type of the map that indicates which nodes are reached.
42.813 +
42.814 + ///The type of the map that indicates which nodes are reached.
42.815 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.816 + ///\todo named parameter to set this type, function to read and write.
42.817 + typedef typename Graph::template NodeMap<bool> ReachedMap;
42.818 + ///Instantiates a ReachedMap.
42.819 +
42.820 + ///This function instantiates a \ref ReachedMap.
42.821 + ///\param G is the graph, to which
42.822 + ///we would like to define the \ref ReachedMap.
42.823 + static ReachedMap *createReachedMap(const GR &G)
42.824 + {
42.825 + return new ReachedMap(G);
42.826 + }
42.827 + ///The type of the map that stores the dists of the nodes.
42.828 +
42.829 + ///The type of the map that stores the dists of the nodes.
42.830 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
42.831 + ///
42.832 + typedef NullMap<typename Graph::Node,int> DistMap;
42.833 + ///Instantiates a DistMap.
42.834 +
42.835 + ///This function instantiates a \ref DistMap.
42.836 + ///\param G is the graph, to which we would like to define the \ref DistMap
42.837 + static DistMap *createDistMap(const GR &)
42.838 + {
42.839 + return new DistMap();
42.840 + }
42.841 + };
42.842 +
42.843 + /// Default traits used by \ref BfsWizard
42.844 +
42.845 + /// To make it easier to use Bfs algorithm
42.846 + ///we have created a wizard class.
42.847 + /// This \ref BfsWizard class needs default traits,
42.848 + ///as well as the \ref Bfs class.
42.849 + /// The \ref BfsWizardBase is a class to be the default traits of the
42.850 + /// \ref BfsWizard class.
42.851 + template<class GR>
42.852 + class BfsWizardBase : public BfsWizardDefaultTraits<GR>
42.853 + {
42.854 +
42.855 + typedef BfsWizardDefaultTraits<GR> Base;
42.856 + protected:
42.857 + /// Type of the nodes in the graph.
42.858 + typedef typename Base::Graph::Node Node;
42.859 +
42.860 + /// Pointer to the underlying graph.
42.861 + void *_g;
42.862 + ///Pointer to the map of reached nodes.
42.863 + void *_reached;
42.864 + ///Pointer to the map of processed nodes.
42.865 + void *_processed;
42.866 + ///Pointer to the map of predecessors edges.
42.867 + void *_pred;
42.868 +// ///Pointer to the map of predecessors nodes.
42.869 +// void *_predNode;
42.870 + ///Pointer to the map of distances.
42.871 + void *_dist;
42.872 + ///Pointer to the source node.
42.873 + Node _source;
42.874 +
42.875 + public:
42.876 + /// Constructor.
42.877 +
42.878 + /// This constructor does not require parameters, therefore it initiates
42.879 + /// all of the attributes to default values (0, INVALID).
42.880 + BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
42.881 +// _predNode(0),
42.882 + _dist(0), _source(INVALID) {}
42.883 +
42.884 + /// Constructor.
42.885 +
42.886 + /// This constructor requires some parameters,
42.887 + /// listed in the parameters list.
42.888 + /// Others are initiated to 0.
42.889 + /// \param g is the initial value of \ref _g
42.890 + /// \param s is the initial value of \ref _source
42.891 + BfsWizardBase(const GR &g, Node s=INVALID) :
42.892 + _g((void *)&g), _reached(0), _processed(0), _pred(0),
42.893 +// _predNode(0),
42.894 + _dist(0), _source(s) {}
42.895 +
42.896 + };
42.897 +
42.898 + /// A class to make the usage of Bfs algorithm easier
42.899 +
42.900 + /// This class is created to make it easier to use Bfs algorithm.
42.901 + /// It uses the functions and features of the plain \ref Bfs,
42.902 + /// but it is much simpler to use it.
42.903 + ///
42.904 + /// Simplicity means that the way to change the types defined
42.905 + /// in the traits class is based on functions that returns the new class
42.906 + /// and not on templatable built-in classes.
42.907 + /// When using the plain \ref Bfs
42.908 + /// the new class with the modified type comes from
42.909 + /// the original class by using the ::
42.910 + /// operator. In the case of \ref BfsWizard only
42.911 + /// a function have to be called and it will
42.912 + /// return the needed class.
42.913 + ///
42.914 + /// It does not have own \ref run method. When its \ref run method is called
42.915 + /// it initiates a plain \ref Bfs class, and calls the \ref Bfs::run
42.916 + /// method of it.
42.917 + template<class TR>
42.918 + class BfsWizard : public TR
42.919 + {
42.920 + typedef TR Base;
42.921 +
42.922 + ///The type of the underlying graph.
42.923 + typedef typename TR::Graph Graph;
42.924 + //\e
42.925 + typedef typename Graph::Node Node;
42.926 + //\e
42.927 + typedef typename Graph::NodeIt NodeIt;
42.928 + //\e
42.929 + typedef typename Graph::Edge Edge;
42.930 + //\e
42.931 + typedef typename Graph::OutEdgeIt OutEdgeIt;
42.932 +
42.933 + ///\brief The type of the map that stores
42.934 + ///the reached nodes
42.935 + typedef typename TR::ReachedMap ReachedMap;
42.936 + ///\brief The type of the map that stores
42.937 + ///the processed nodes
42.938 + typedef typename TR::ProcessedMap ProcessedMap;
42.939 + ///\brief The type of the map that stores the last
42.940 + ///edges of the shortest paths.
42.941 + typedef typename TR::PredMap PredMap;
42.942 +// ///\brief The type of the map that stores the last but one
42.943 +// ///nodes of the shortest paths.
42.944 +// typedef typename TR::PredNodeMap PredNodeMap;
42.945 + ///The type of the map that stores the dists of the nodes.
42.946 + typedef typename TR::DistMap DistMap;
42.947 +
42.948 +public:
42.949 + /// Constructor.
42.950 + BfsWizard() : TR() {}
42.951 +
42.952 + /// Constructor that requires parameters.
42.953 +
42.954 + /// Constructor that requires parameters.
42.955 + /// These parameters will be the default values for the traits class.
42.956 + BfsWizard(const Graph &g, Node s=INVALID) :
42.957 + TR(g,s) {}
42.958 +
42.959 + ///Copy constructor
42.960 + BfsWizard(const TR &b) : TR(b) {}
42.961 +
42.962 + ~BfsWizard() {}
42.963 +
42.964 + ///Runs Bfs algorithm from a given node.
42.965 +
42.966 + ///Runs Bfs algorithm from a given node.
42.967 + ///The node can be given by the \ref source function.
42.968 + void run()
42.969 + {
42.970 + if(Base::_source==INVALID) throw UninitializedParameter();
42.971 + Bfs<Graph,TR> alg(*(Graph*)Base::_g);
42.972 + if(Base::_reached)
42.973 + alg.reachedMap(*(ReachedMap*)Base::_reached);
42.974 + if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
42.975 + if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
42.976 +// if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
42.977 + if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
42.978 + alg.run(Base::_source);
42.979 + }
42.980 +
42.981 + ///Runs Bfs algorithm from the given node.
42.982 +
42.983 + ///Runs Bfs algorithm from the given node.
42.984 + ///\param s is the given source.
42.985 + void run(Node s)
42.986 + {
42.987 + Base::_source=s;
42.988 + run();
42.989 + }
42.990 +
42.991 + template<class T>
42.992 + struct DefPredMapBase : public Base {
42.993 + typedef T PredMap;
42.994 + static PredMap *createPredMap(const Graph &) { return 0; };
42.995 + DefPredMapBase(const TR &b) : TR(b) {}
42.996 + };
42.997 +
42.998 + ///\brief \ref named-templ-param "Named parameter"
42.999 + ///function for setting PredMap
42.1000 + ///
42.1001 + /// \ref named-templ-param "Named parameter"
42.1002 + ///function for setting PredMap
42.1003 + ///
42.1004 + template<class T>
42.1005 + BfsWizard<DefPredMapBase<T> > predMap(const T &t)
42.1006 + {
42.1007 + Base::_pred=(void *)&t;
42.1008 + return BfsWizard<DefPredMapBase<T> >(*this);
42.1009 + }
42.1010 +
42.1011 +
42.1012 + template<class T>
42.1013 + struct DefReachedMapBase : public Base {
42.1014 + typedef T ReachedMap;
42.1015 + static ReachedMap *createReachedMap(const Graph &) { return 0; };
42.1016 + DefReachedMapBase(const TR &b) : TR(b) {}
42.1017 + };
42.1018 +
42.1019 + ///\brief \ref named-templ-param "Named parameter"
42.1020 + ///function for setting ReachedMap
42.1021 + ///
42.1022 + /// \ref named-templ-param "Named parameter"
42.1023 + ///function for setting ReachedMap
42.1024 + ///
42.1025 + template<class T>
42.1026 + BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
42.1027 + {
42.1028 + Base::_pred=(void *)&t;
42.1029 + return BfsWizard<DefReachedMapBase<T> >(*this);
42.1030 + }
42.1031 +
42.1032 +
42.1033 + template<class T>
42.1034 + struct DefProcessedMapBase : public Base {
42.1035 + typedef T ProcessedMap;
42.1036 + static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
42.1037 + DefProcessedMapBase(const TR &b) : TR(b) {}
42.1038 + };
42.1039 +
42.1040 + ///\brief \ref named-templ-param "Named parameter"
42.1041 + ///function for setting ProcessedMap
42.1042 + ///
42.1043 + /// \ref named-templ-param "Named parameter"
42.1044 + ///function for setting ProcessedMap
42.1045 + ///
42.1046 + template<class T>
42.1047 + BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
42.1048 + {
42.1049 + Base::_pred=(void *)&t;
42.1050 + return BfsWizard<DefProcessedMapBase<T> >(*this);
42.1051 + }
42.1052 +
42.1053 +
42.1054 +// template<class T>
42.1055 +// struct DefPredNodeMapBase : public Base {
42.1056 +// typedef T PredNodeMap;
42.1057 +// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
42.1058 +// DefPredNodeMapBase(const TR &b) : TR(b) {}
42.1059 +// };
42.1060 +
42.1061 +// ///\brief \ref named-templ-param "Named parameter"
42.1062 +// ///function for setting PredNodeMap type
42.1063 +// ///
42.1064 +// /// \ref named-templ-param "Named parameter"
42.1065 +// ///function for setting PredNodeMap type
42.1066 +// ///
42.1067 +// template<class T>
42.1068 +// BfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
42.1069 +// {
42.1070 +// Base::_predNode=(void *)&t;
42.1071 +// return BfsWizard<DefPredNodeMapBase<T> >(*this);
42.1072 +// }
42.1073 +
42.1074 + template<class T>
42.1075 + struct DefDistMapBase : public Base {
42.1076 + typedef T DistMap;
42.1077 + static DistMap *createDistMap(const Graph &) { return 0; };
42.1078 + DefDistMapBase(const TR &b) : TR(b) {}
42.1079 + };
42.1080 +
42.1081 + ///\brief \ref named-templ-param "Named parameter"
42.1082 + ///function for setting DistMap type
42.1083 + ///
42.1084 + /// \ref named-templ-param "Named parameter"
42.1085 + ///function for setting DistMap type
42.1086 + ///
42.1087 + template<class T>
42.1088 + BfsWizard<DefDistMapBase<T> > distMap(const T &t)
42.1089 + {
42.1090 + Base::_dist=(void *)&t;
42.1091 + return BfsWizard<DefDistMapBase<T> >(*this);
42.1092 + }
42.1093 +
42.1094 + /// Sets the source node, from which the Bfs algorithm runs.
42.1095 +
42.1096 + /// Sets the source node, from which the Bfs algorithm runs.
42.1097 + /// \param s is the source node.
42.1098 + BfsWizard<TR> &source(Node s)
42.1099 + {
42.1100 + Base::_source=s;
42.1101 + return *this;
42.1102 + }
42.1103 +
42.1104 + };
42.1105 +
42.1106 + ///Function type interface for Bfs algorithm.
42.1107 +
42.1108 + /// \ingroup flowalgs
42.1109 + ///Function type interface for Bfs algorithm.
42.1110 + ///
42.1111 + ///This function also has several
42.1112 + ///\ref named-templ-func-param "named parameters",
42.1113 + ///they are declared as the members of class \ref BfsWizard.
42.1114 + ///The following
42.1115 + ///example shows how to use these parameters.
42.1116 + ///\code
42.1117 + /// bfs(g,source).predMap(preds).run();
42.1118 + ///\endcode
42.1119 + ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
42.1120 + ///to the end of the parameter list.
42.1121 + ///\sa BfsWizard
42.1122 + ///\sa Bfs
42.1123 + template<class GR>
42.1124 + BfsWizard<BfsWizardBase<GR> >
42.1125 + bfs(const GR &g,typename GR::Node s=INVALID)
42.1126 + {
42.1127 + return BfsWizard<BfsWizardBase<GR> >(g,s);
42.1128 + }
42.1129 +
42.1130 +} //END OF NAMESPACE LEMON
42.1131 +
42.1132 +#endif
42.1133 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/lemon/bin_heap.h Mon May 23 04:48:14 2005 +0000
43.3 @@ -0,0 +1,303 @@
43.4 +/* -*- C++ -*-
43.5 + * lemon/bin_heap.h - Part of LEMON, a generic C++ optimization library
43.6 + *
43.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
43.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
43.9 + *
43.10 + * Permission to use, modify and distribute this software is granted
43.11 + * provided that this copyright notice appears in all copies. For
43.12 + * precise terms see the accompanying LICENSE file.
43.13 + *
43.14 + * This software is provided "AS IS" with no warranty of any kind,
43.15 + * express or implied, and with no claim as to its suitability for any
43.16 + * purpose.
43.17 + *
43.18 + */
43.19 +
43.20 +#ifndef LEMON_BIN_HEAP_H
43.21 +#define LEMON_BIN_HEAP_H
43.22 +
43.23 +///\ingroup auxdat
43.24 +///\file
43.25 +///\brief Binary Heap implementation.
43.26 +
43.27 +#include <vector>
43.28 +#include <utility>
43.29 +#include <functional>
43.30 +
43.31 +namespace lemon {
43.32 +
43.33 + /// \addtogroup auxdat
43.34 + /// @{
43.35 +
43.36 + /// A Binary Heap implementation.
43.37 +
43.38 + ///This class implements the \e binary \e heap data structure. A \e heap
43.39 + ///is a data structure for storing items with specified values called \e
43.40 + ///priorities in such a way that finding the item with minimum priority is
43.41 + ///efficient. \c Compare specifies the ordering of the priorities. In a heap
43.42 + ///one can change the priority of an item, add or erase an item, etc.
43.43 + ///
43.44 + ///\param Item Type of the items to be stored.
43.45 + ///\param Prio Type of the priority of the items.
43.46 + ///\param ItemIntMap A read and writable Item int map, used internally
43.47 + ///to handle the cross references.
43.48 + ///\param Compare A class for the ordering of the priorities. The
43.49 + ///default is \c std::less<Prio>.
43.50 + ///
43.51 + ///\sa FibHeap
43.52 + ///\sa Dijkstra
43.53 + template <typename Item, typename Prio, typename ItemIntMap,
43.54 + typename Compare = std::less<Prio> >
43.55 + class BinHeap {
43.56 +
43.57 + public:
43.58 + typedef Item ItemType;
43.59 + // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot...
43.60 + typedef Prio PrioType;
43.61 + typedef std::pair<ItemType,PrioType> PairType;
43.62 + typedef ItemIntMap ItemIntMapType;
43.63 + typedef Compare PrioCompare;
43.64 +
43.65 + /// \brief Type to represent the items states.
43.66 + ///
43.67 + /// Each Item element have a state associated to it. It may be "in heap",
43.68 + /// "pre heap" or "post heap". The latter two are indifferent from the
43.69 + /// heap's point of view, but may be useful to the user.
43.70 + ///
43.71 + /// The ItemIntMap \e should be initialized in such way that it maps
43.72 + /// PRE_HEAP (-1) to any element to be put in the heap...
43.73 + enum state_enum {
43.74 + IN_HEAP = 0,
43.75 + PRE_HEAP = -1,
43.76 + POST_HEAP = -2
43.77 + };
43.78 +
43.79 + private:
43.80 + std::vector<PairType> data;
43.81 + Compare comp;
43.82 + ItemIntMap &iim;
43.83 +
43.84 + public:
43.85 + /// \brief The constructor.
43.86 + ///
43.87 + /// The constructor.
43.88 + /// \param _iim should be given to the constructor, since it is used
43.89 + /// internally to handle the cross references. The value of the map
43.90 + /// should be PRE_HEAP (-1) for each element.
43.91 + explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
43.92 +
43.93 + /// \brief The constructor.
43.94 + ///
43.95 + /// The constructor.
43.96 + /// \param _iim should be given to the constructor, since it is used
43.97 + /// internally to handle the cross references. The value of the map
43.98 + /// should be PRE_HEAP (-1) for each element.
43.99 + ///
43.100 + /// \param _comp The comparator function object.
43.101 + BinHeap(ItemIntMap &_iim, const Compare &_comp)
43.102 + : iim(_iim), comp(_comp) {}
43.103 +
43.104 +
43.105 + /// The number of items stored in the heap.
43.106 + ///
43.107 + /// \brief Returns the number of items stored in the heap.
43.108 + int size() const { return data.size(); }
43.109 +
43.110 + /// \brief Checks if the heap stores no items.
43.111 + ///
43.112 + /// Returns \c true if and only if the heap stores no items.
43.113 + bool empty() const { return data.empty(); }
43.114 +
43.115 + private:
43.116 + static int parent(int i) { return (i-1)/2; }
43.117 + static int second_child(int i) { return 2*i+2; }
43.118 + bool less(const PairType &p1, const PairType &p2) const {
43.119 + return comp(p1.second, p2.second);
43.120 + }
43.121 +
43.122 + int bubble_up(int hole, PairType p);
43.123 + int bubble_down(int hole, PairType p, int length);
43.124 +
43.125 + void move(const PairType &p, int i) {
43.126 + data[i] = p;
43.127 + iim.set(p.first, i);
43.128 + }
43.129 +
43.130 + void rmidx(int h) {
43.131 + int n = data.size()-1;
43.132 + if( h>=0 && h<=n ) {
43.133 + iim.set(data[h].first, POST_HEAP);
43.134 + if ( h<n ) {
43.135 + bubble_down(h, data[n], n);
43.136 + }
43.137 + data.pop_back();
43.138 + }
43.139 + }
43.140 +
43.141 + public:
43.142 + /// \brief Insert a pair of item and priority into the heap.
43.143 + ///
43.144 + /// Adds \c p.first to the heap with priority \c p.second.
43.145 + /// \param p The pair to insert.
43.146 + void push(const PairType &p) {
43.147 + int n = data.size();
43.148 + data.resize(n+1);
43.149 + bubble_up(n, p);
43.150 + }
43.151 +
43.152 + /// \brief Insert an item into the heap with the given heap.
43.153 + ///
43.154 + /// Adds \c i to the heap with priority \c p.
43.155 + /// \param i The item to insert.
43.156 + /// \param p The priority of the item.
43.157 + void push(const Item &i, const Prio &p) { push(PairType(i,p)); }
43.158 +
43.159 + /// \brief Returns the item with minimum priority relative to \c Compare.
43.160 + ///
43.161 + /// This method returns the item with minimum priority relative to \c
43.162 + /// Compare.
43.163 + /// \pre The heap must be nonempty.
43.164 + Item top() const {
43.165 + return data[0].first;
43.166 + }
43.167 +
43.168 + /// \brief Returns the minimum priority relative to \c Compare.
43.169 + ///
43.170 + /// It returns the minimum priority relative to \c Compare.
43.171 + /// \pre The heap must be nonempty.
43.172 + Prio prio() const {
43.173 + return data[0].second;
43.174 + }
43.175 +
43.176 + /// \brief Deletes the item with minimum priority relative to \c Compare.
43.177 + ///
43.178 + /// This method deletes the item with minimum priority relative to \c
43.179 + /// Compare from the heap.
43.180 + /// \pre The heap must be non-empty.
43.181 + void pop() {
43.182 + rmidx(0);
43.183 + }
43.184 +
43.185 + /// \brief Deletes \c i from the heap.
43.186 + ///
43.187 + /// This method deletes item \c i from the heap, if \c i was
43.188 + /// already stored in the heap.
43.189 + /// \param i The item to erase.
43.190 + void erase(const Item &i) {
43.191 + rmidx(iim[i]);
43.192 + }
43.193 +
43.194 +
43.195 + /// \brief Returns the priority of \c i.
43.196 + ///
43.197 + /// This function returns the priority of item \c i.
43.198 + /// \pre \c i must be in the heap.
43.199 + /// \param i The item.
43.200 + Prio operator[](const Item &i) const {
43.201 + int idx = iim[i];
43.202 + return data[idx].second;
43.203 + }
43.204 +
43.205 + /// \brief \c i gets to the heap with priority \c p independently
43.206 + /// if \c i was already there.
43.207 + ///
43.208 + /// This method calls \ref push(\c i, \c p) if \c i is not stored
43.209 + /// in the heap and sets the priority of \c i to \c p otherwise.
43.210 + /// \param i The item.
43.211 + /// \param p The priority.
43.212 + void set(const Item &i, const Prio &p) {
43.213 + int idx = iim[i];
43.214 + if( idx < 0 ) {
43.215 + push(i,p);
43.216 + }
43.217 + else if( comp(p, data[idx].second) ) {
43.218 + bubble_up(idx, PairType(i,p));
43.219 + }
43.220 + else {
43.221 + bubble_down(idx, PairType(i,p), data.size());
43.222 + }
43.223 + }
43.224 +
43.225 + /// \brief Decreases the priority of \c i to \c p.
43.226 +
43.227 + /// This method decreases the priority of item \c i to \c p.
43.228 + /// \pre \c i must be stored in the heap with priority at least \c
43.229 + /// p relative to \c Compare.
43.230 + /// \param i The item.
43.231 + /// \param p The priority.
43.232 + void decrease(const Item &i, const Prio &p) {
43.233 + int idx = iim[i];
43.234 + bubble_up(idx, PairType(i,p));
43.235 + }
43.236 +
43.237 + /// \brief Increases the priority of \c i to \c p.
43.238 + ///
43.239 + /// This method sets the priority of item \c i to \c p.
43.240 + /// \pre \c i must be stored in the heap with priority at most \c
43.241 + /// p relative to \c Compare.
43.242 + /// \param i The item.
43.243 + /// \param p The priority.
43.244 + void increase(const Item &i, const Prio &p) {
43.245 + int idx = iim[i];
43.246 + bubble_down(idx, PairType(i,p), data.size());
43.247 + }
43.248 +
43.249 + /// \brief Returns if \c item is in, has already been in, or has
43.250 + /// never been in the heap.
43.251 + ///
43.252 + /// This method returns PRE_HEAP if \c item has never been in the
43.253 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
43.254 + /// otherwise. In the latter case it is possible that \c item will
43.255 + /// get back to the heap again.
43.256 + /// \param i The item.
43.257 + state_enum state(const Item &i) const {
43.258 + int s = iim[i];
43.259 + if( s>=0 )
43.260 + s=0;
43.261 + return state_enum(s);
43.262 + }
43.263 +
43.264 + }; // class BinHeap
43.265 +
43.266 +
43.267 + template <typename K, typename V, typename M, typename C>
43.268 + int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) {
43.269 + int par = parent(hole);
43.270 + while( hole>0 && less(p,data[par]) ) {
43.271 + move(data[par],hole);
43.272 + hole = par;
43.273 + par = parent(hole);
43.274 + }
43.275 + move(p, hole);
43.276 + return hole;
43.277 + }
43.278 +
43.279 + template <typename K, typename V, typename M, typename C>
43.280 + int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) {
43.281 + int child = second_child(hole);
43.282 + while(child < length) {
43.283 + if( less(data[child-1], data[child]) ) {
43.284 + --child;
43.285 + }
43.286 + if( !less(data[child], p) )
43.287 + goto ok;
43.288 + move(data[child], hole);
43.289 + hole = child;
43.290 + child = second_child(hole);
43.291 + }
43.292 + child--;
43.293 + if( child<length && less(data[child], p) ) {
43.294 + move(data[child], hole);
43.295 + hole=child;
43.296 + }
43.297 + ok:
43.298 + move(p, hole);
43.299 + return hole;
43.300 + }
43.301 +
43.302 + ///@}
43.303 +
43.304 +} // namespace lemon
43.305 +
43.306 +#endif // LEMON_BIN_HEAP_H
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/lemon/bits/alteration_notifier.h Mon May 23 04:48:14 2005 +0000
44.3 @@ -0,0 +1,438 @@
44.4 +/* -*- C++ -*-
44.5 + * lemon/notifier.h - Part of LEMON, a generic C++ optimization library
44.6 + *
44.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
44.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
44.9 + *
44.10 + * Permission to use, modify and distribute this software is granted
44.11 + * provided that this copyright notice appears in all copies. For
44.12 + * precise terms see the accompanying LICENSE file.
44.13 + *
44.14 + * This software is provided "AS IS" with no warranty of any kind,
44.15 + * express or implied, and with no claim as to its suitability for any
44.16 + * purpose.
44.17 + *
44.18 + */
44.19 +
44.20 +#ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
44.21 +#define LEMON_ALTERATION_OBSERVER_REGISTRY_H
44.22 +
44.23 +#include <vector>
44.24 +#include <algorithm>
44.25 +
44.26 +///\ingroup graphmaps
44.27 +///\file
44.28 +///\brief Observer registry for graph alteration observers.
44.29 +
44.30 +namespace lemon {
44.31 +
44.32 + /// \addtogroup graphmaps
44.33 + /// @{
44.34 +
44.35 + /// \brief Registry class to register objects observes alterations in
44.36 + /// the graph.
44.37 + ///
44.38 + /// This class is a registry for the objects which observe the
44.39 + /// alterations in a container. The alteration observers can be attached
44.40 + /// to and detached from the registry. The observers have to inherit
44.41 + /// from the \ref AlterationNotifier::ObserverBase and override
44.42 + /// the virtual functions in that.
44.43 + ///
44.44 + /// The most important application of the alteration observing is the
44.45 + /// dynamic map implementation.
44.46 + ///
44.47 + /// \param _Item The item type what the observers are observing, usually
44.48 + /// edge or node.
44.49 + ///
44.50 + /// \author Balazs Dezso
44.51 +
44.52 + template <typename _Item>
44.53 + class AlterationNotifier {
44.54 + public:
44.55 + typedef _Item Item;
44.56 +
44.57 + /// ObserverBase is the base class for the observers.
44.58 +
44.59 + /// ObserverBase is the abstract base class for the observers.
44.60 + /// It will be notified about an item was inserted into or
44.61 + /// erased from the graph.
44.62 + ///
44.63 + /// The observer interface contains some pure virtual functions
44.64 + /// to override. The add() and erase() functions are
44.65 + /// to notify the oberver when one item is added or
44.66 + /// erased.
44.67 + ///
44.68 + /// The build() and clear() members are to notify the observer
44.69 + /// about the container is built from an empty container or
44.70 + /// is cleared to an empty container.
44.71 + ///
44.72 + /// \author Balazs Dezso
44.73 +
44.74 + class ObserverBase {
44.75 + protected:
44.76 + typedef AlterationNotifier Registry;
44.77 +
44.78 + friend class AlterationNotifier;
44.79 +
44.80 + /// \brief Default constructor.
44.81 + ///
44.82 + /// Default constructor for ObserverBase.
44.83 + ///
44.84 + ObserverBase() : registry(0) {}
44.85 +
44.86 + virtual ~ObserverBase() {}
44.87 +
44.88 + /// \brief Attaches the observer into an AlterationNotifier.
44.89 + ///
44.90 + /// This member attaches the observer into an AlterationNotifier.
44.91 + ///
44.92 + void attach(AlterationNotifier& r) {
44.93 + registry = &r;
44.94 + registry->attach(*this);
44.95 + }
44.96 +
44.97 + /// \brief Detaches the observer into an AlterationNotifier.
44.98 + ///
44.99 + /// This member detaches the observer from an AlterationNotifier.
44.100 + ///
44.101 + void detach() {
44.102 + if (registry) {
44.103 + registry->detach(*this);
44.104 + }
44.105 + }
44.106 +
44.107 +
44.108 + /// Gives back a pointer to the registry what the map attached into.
44.109 +
44.110 + /// This function gives back a pointer to the registry what the map
44.111 + /// attached into.
44.112 + ///
44.113 + Registry* getRegistry() const { return const_cast<Registry*>(registry); }
44.114 +
44.115 + /// Gives back true when the observer is attached into a registry.
44.116 + bool attached() const { return registry != 0; }
44.117 +
44.118 + private:
44.119 +
44.120 + ObserverBase(const ObserverBase& copy);
44.121 + ObserverBase& operator=(const ObserverBase& copy);
44.122 +
44.123 + protected:
44.124 +
44.125 + Registry* registry;
44.126 + int registry_index;
44.127 +
44.128 + public:
44.129 +
44.130 + /// \brief The member function to notificate the observer about an
44.131 + /// item is added to the container.
44.132 + ///
44.133 + /// The add() member function notificates the observer about an item
44.134 + /// is added to the container. It have to be overrided in the
44.135 + /// subclasses.
44.136 +
44.137 + virtual void add(const Item&) = 0;
44.138 +
44.139 + /// \brief The member function to notificate the observer about
44.140 + /// simulitem is added to the container.
44.141 + ///
44.142 + /// The add() member function notificates the observer about an item
44.143 + /// is added to the container. It have to be overrided in the
44.144 + /// subclasses.
44.145 +
44.146 + virtual void add(const std::vector<Item>& items) {
44.147 + for (int i = 0; i < (int)items.size(); ++i) {
44.148 + add(items[i]);
44.149 + }
44.150 + }
44.151 +
44.152 + /// \brief The member function to notificate the observer about an
44.153 + /// item is erased from the container.
44.154 + ///
44.155 + /// The erase() member function notificates the observer about an
44.156 + /// item is erased from the container. It have to be overrided in
44.157 + /// the subclasses.
44.158 +
44.159 + virtual void erase(const Item&) = 0;
44.160 +
44.161 + virtual void erase(const std::vector<Item>& items) {
44.162 + for (int i = 0; i < (int)items.size(); ++i) {
44.163 + add(items[i]);
44.164 + }
44.165 + }
44.166 +
44.167 + /// \brief The member function to notificate the observer about the
44.168 + /// container is built.
44.169 + ///
44.170 + /// The build() member function notificates the observer about the
44.171 + /// container is built from an empty container. It have to be
44.172 + /// overrided in the subclasses.
44.173 +
44.174 + virtual void build() = 0;
44.175 +
44.176 + /// \brief The member function to notificate the observer about all
44.177 + /// items are erased from the container.
44.178 + ///
44.179 + /// The clear() member function notificates the observer about all
44.180 + /// items are erased from the container. It have to be overrided in
44.181 + /// the subclasses.
44.182 +
44.183 + virtual void clear() = 0;
44.184 +
44.185 + };
44.186 +
44.187 + protected:
44.188 +
44.189 +
44.190 + typedef std::vector<ObserverBase*> Container;
44.191 +
44.192 + Container container;
44.193 +
44.194 +
44.195 + public:
44.196 +
44.197 + /// Default constructor.
44.198 +
44.199 + ///
44.200 + /// The default constructor of the AlterationNotifier.
44.201 + /// It creates an empty registry.
44.202 + AlterationNotifier() {}
44.203 +
44.204 + /// Copy Constructor of the AlterationNotifier.
44.205 +
44.206 + /// Copy constructor of the AlterationNotifier.
44.207 + /// It creates only an empty registry because the copiable
44.208 + /// registry's observers have to be registered still into that registry.
44.209 + AlterationNotifier(const AlterationNotifier&) {}
44.210 +
44.211 + /// Assign operator.
44.212 +
44.213 + /// Assign operator for the AlterationNotifier.
44.214 + /// It makes the notifier only empty because the copiable
44.215 + /// notifier's observers have to be registered still into that registry.
44.216 + AlterationNotifier& operator=(const AlterationNotifier&) {
44.217 + typename Container::iterator it;
44.218 + for (it = container.begin(); it != container.end(); ++it) {
44.219 + (*it)->registry = 0;
44.220 + }
44.221 + }
44.222 +
44.223 + /// Destructor.
44.224 +
44.225 + /// Destructor of the AlterationNotifier.
44.226 + ///
44.227 + ~AlterationNotifier() {
44.228 + typename Container::iterator it;
44.229 + for (it = container.begin(); it != container.end(); ++it) {
44.230 + (*it)->registry = 0;
44.231 + }
44.232 + }
44.233 +
44.234 +
44.235 + protected:
44.236 +
44.237 + void attach(ObserverBase& observer) {
44.238 + container.push_back(&observer);
44.239 + observer.registry = this;
44.240 + observer.registry_index = container.size()-1;
44.241 + }
44.242 +
44.243 + void detach(ObserverBase& base) {
44.244 + container.back()->registry_index = base.registry_index;
44.245 + container[base.registry_index] = container.back();
44.246 + container.pop_back();
44.247 + base.registry = 0;
44.248 + }
44.249 +
44.250 + public:
44.251 +
44.252 + /// \brief Notifies all the registered observers about an Item added to
44.253 + /// the container.
44.254 + ///
44.255 + /// It notifies all the registered observers about an Item added to
44.256 + /// the container.
44.257 + ///
44.258 + void add(const Item& item) {
44.259 + typename Container::iterator it;
44.260 + for (it = container.begin(); it != container.end(); ++it) {
44.261 + (*it)->add(item);
44.262 + }
44.263 + }
44.264 +
44.265 + /// \brief Notifies all the registered observers about more Item added to
44.266 + /// the container.
44.267 + ///
44.268 + /// It notifies all the registered observers about more Item added to
44.269 + /// the container.
44.270 + ///
44.271 + void add(const std::vector<Item>& items) {
44.272 + typename Container::iterator it;
44.273 + for (it = container.begin(); it != container.end(); ++it) {
44.274 + (*it)->add(items);
44.275 + }
44.276 + }
44.277 +
44.278 + /// \brief Notifies all the registered observers about an Item erased from
44.279 + /// the container.
44.280 + ///
44.281 + /// It notifies all the registered observers about an Item erased from
44.282 + /// the container.
44.283 + ///
44.284 + void erase(const Item& key) {
44.285 + typename Container::iterator it;
44.286 + for (it = container.begin(); it != container.end(); ++it) {
44.287 + (*it)->erase(key);
44.288 + }
44.289 + }
44.290 +
44.291 + /// \brief Notifies all the registered observers about more Item erased
44.292 + /// from the container.
44.293 + ///
44.294 + /// It notifies all the registered observers about more Item erased from
44.295 + /// the container.
44.296 + ///
44.297 + void erase(const std::vector<Item>& items) {
44.298 + typename Container::iterator it;
44.299 + for (it = container.begin(); it != container.end(); ++it) {
44.300 + (*it)->erase(items);
44.301 + }
44.302 + }
44.303 +
44.304 +
44.305 + /// \brief Notifies all the registered observers about the container is
44.306 + /// built.
44.307 + ///
44.308 + /// Notifies all the registered observers about the container is built
44.309 + /// from an empty container.
44.310 + void build() {
44.311 + typename Container::iterator it;
44.312 + for (it = container.begin(); it != container.end(); ++it) {
44.313 + (*it)->build();
44.314 + }
44.315 + }
44.316 +
44.317 +
44.318 + /// \brief Notifies all the registered observers about all Items are
44.319 + /// erased.
44.320 + ///
44.321 + /// Notifies all the registered observers about all Items are erased
44.322 + /// from the container.
44.323 + void clear() {
44.324 + typename Container::iterator it;
44.325 + for (it = container.begin(); it != container.end(); ++it) {
44.326 + (*it)->clear();
44.327 + }
44.328 + }
44.329 + };
44.330 +
44.331 +
44.332 + /// \brief Class to extend a graph with the functionality of alteration
44.333 + /// observing.
44.334 + ///
44.335 + /// AlterableGraphExtender extends the _Base graphs functionality with
44.336 + /// the possibility of alteration observing. It defines two observer
44.337 + /// registrys for the nodes and mapes.
44.338 + ///
44.339 + /// \todo Document what "alteration observing" is. And probably find a
44.340 + /// better (shorter) name.
44.341 + ///
44.342 + /// \param _Base is the base class to extend.
44.343 + ///
44.344 + /// \pre _Base is conform to the BaseGraphComponent concept.
44.345 + ///
44.346 + /// \post AlterableGraphExtender<_Base> is conform to the
44.347 + /// AlterableGraphComponent concept.
44.348 + ///
44.349 + /// \author Balazs Dezso
44.350 +
44.351 + template <typename _Base>
44.352 + class AlterableGraphExtender : public _Base {
44.353 + public:
44.354 +
44.355 + typedef AlterableGraphExtender Graph;
44.356 + typedef _Base Parent;
44.357 +
44.358 + typedef typename Parent::Node Node;
44.359 + typedef typename Parent::Edge Edge;
44.360 +
44.361 + /// The edge observer registry.
44.362 + typedef AlterationNotifier<Edge> EdgeNotifier;
44.363 + /// The node observer registry.
44.364 + typedef AlterationNotifier<Node> NodeNotifier;
44.365 +
44.366 +
44.367 + protected:
44.368 +
44.369 + mutable EdgeNotifier edge_notifier;
44.370 +
44.371 + mutable NodeNotifier node_notifier;
44.372 +
44.373 + public:
44.374 +
44.375 + /// \brief Gives back the edge alteration notifier.
44.376 + ///
44.377 + /// Gives back the edge alteration notifier.
44.378 + EdgeNotifier& getNotifier(Edge) const {
44.379 + return edge_notifier;
44.380 + }
44.381 +
44.382 + /// \brief Gives back the node alteration notifier.
44.383 + ///
44.384 + /// Gives back the node alteration notifier.
44.385 + NodeNotifier& getNotifier(Node) const {
44.386 + return node_notifier;
44.387 + }
44.388 +
44.389 + ~AlterableGraphExtender() {
44.390 + node_notifier.clear();
44.391 + edge_notifier.clear();
44.392 + }
44.393 +
44.394 + };
44.395 +
44.396 + /// \brief Class to extend an undirected graph with the functionality of
44.397 + /// alteration observing.
44.398 + ///
44.399 + /// \todo Document.
44.400 + ///
44.401 + /// \sa AlterableGraphExtender
44.402 + ///
44.403 + /// \bug This should be done some other way. Possibilities: template
44.404 + /// specialization (not very easy, if at all possible); some kind of
44.405 + /// enable_if boost technique?
44.406 +
44.407 + template <typename _Base>
44.408 + class AlterableUndirGraphExtender
44.409 + : public AlterableGraphExtender<_Base> {
44.410 + public:
44.411 +
44.412 + typedef AlterableUndirGraphExtender Graph;
44.413 + typedef AlterableGraphExtender<_Base> Parent;
44.414 +
44.415 + typedef typename Parent::UndirEdge UndirEdge;
44.416 +
44.417 + /// The edge observer registry.
44.418 + typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
44.419 +
44.420 + protected:
44.421 +
44.422 + mutable UndirEdgeNotifier undir_edge_notifier;
44.423 +
44.424 + public:
44.425 +
44.426 + using Parent::getNotifier;
44.427 + UndirEdgeNotifier& getNotifier(UndirEdge) const {
44.428 + return undir_edge_notifier;
44.429 + }
44.430 +
44.431 + ~AlterableUndirGraphExtender() {
44.432 + undir_edge_notifier.clear();
44.433 + }
44.434 + };
44.435 +
44.436 +/// @}
44.437 +
44.438 +
44.439 +}
44.440 +
44.441 +#endif
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/lemon/bits/array_map.h Mon May 23 04:48:14 2005 +0000
45.3 @@ -0,0 +1,369 @@
45.4 +/* -*- C++ -*-
45.5 + * lemon/bits/array_map.h - Part of LEMON, a generic C++ optimization library
45.6 + *
45.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
45.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
45.9 + *
45.10 + * Permission to use, modify and distribute this software is granted
45.11 + * provided that this copyright notice appears in all copies. For
45.12 + * precise terms see the accompanying LICENSE file.
45.13 + *
45.14 + * This software is provided "AS IS" with no warranty of any kind,
45.15 + * express or implied, and with no claim as to its suitability for any
45.16 + * purpose.
45.17 + *
45.18 + */
45.19 +
45.20 +#ifndef LEMON_ARRAY_MAP_H
45.21 +#define LEMON_ARRAY_MAP_H
45.22 +
45.23 +#include <memory>
45.24 +#include <lemon/bits/map_iterator.h>
45.25 +
45.26 +///\ingroup graphmaps
45.27 +///\file
45.28 +///\brief Graph maps that construates and destruates
45.29 +///their elements dynamically.
45.30 +
45.31 +namespace lemon {
45.32 +
45.33 +
45.34 + /// \addtogroup graphmaps
45.35 + /// @{
45.36 +
45.37 + /// The ArrayMap template class is graph map structure what
45.38 + /// automatically updates the map when a key is added to or erased from
45.39 + /// the map. This map factory uses the allocators to implement
45.40 + /// the container functionality.
45.41 + ///
45.42 + /// The template parameter is the AlterationNotifier that the maps
45.43 + /// will belong to and the Value.
45.44 +
45.45 +
45.46 + template <typename _Graph,
45.47 + typename _Item,
45.48 + typename _Value>
45.49 + class ArrayMap : public AlterationNotifier<_Item>::ObserverBase {
45.50 +
45.51 + typedef _Item Item;
45.52 + public:
45.53 +
45.54 + /// The graph type of the maps.
45.55 + typedef _Graph Graph;
45.56 + /// The key type of the maps.
45.57 + typedef _Item Key;
45.58 +
45.59 + typedef AlterationNotifier<_Item> Registry;
45.60 +
45.61 + /// The MapBase of the Map which imlements the core regisitry function.
45.62 + typedef typename Registry::ObserverBase Parent;
45.63 +
45.64 + /// The value type of the map.
45.65 + typedef _Value Value;
45.66 +
45.67 +
45.68 + private:
45.69 + typedef std::allocator<Value> Allocator;
45.70 +
45.71 +
45.72 + public:
45.73 +
45.74 + /// Graph and Registry initialized map constructor.
45.75 +
45.76 + ArrayMap(const Graph& _g) : graph(&_g) {
45.77 + Item it;
45.78 + attach(_g.getNotifier(Item()));
45.79 + allocate_memory();
45.80 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.81 + int id = graph->id(it);;
45.82 + allocator.construct(&(values[id]), Value());
45.83 + }
45.84 + }
45.85 +
45.86 + /// Constructor to use default value to initialize the map.
45.87 +
45.88 + /// It constrates a map and initialize all of the the map.
45.89 +
45.90 + ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
45.91 + Item it;
45.92 + attach(_g.getNotifier(_Item()));
45.93 + allocate_memory();
45.94 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.95 + int id = graph->id(it);;
45.96 + allocator.construct(&(values[id]), _v);
45.97 + }
45.98 + }
45.99 +
45.100 + /// Constructor to copy a map of the same map type.
45.101 +
45.102 + ArrayMap(const ArrayMap& copy) : Parent() {
45.103 + if (copy.attached()) {
45.104 + attach(*copy.getRegistry());
45.105 + }
45.106 + capacity = copy.capacity;
45.107 + if (capacity == 0) return;
45.108 + values = allocator.allocate(capacity);
45.109 + Item it;
45.110 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.111 + int id = graph->id(it);;
45.112 + allocator.construct(&(values[id]), copy.values[id]);
45.113 + }
45.114 + }
45.115 +
45.116 + using Parent::attach;
45.117 + using Parent::detach;
45.118 + using Parent::attached;
45.119 +
45.120 + /// Assign operator to copy a map of the same map type.
45.121 +
45.122 + ArrayMap& operator=(const ArrayMap& copy) {
45.123 + if (© == this) return *this;
45.124 +
45.125 + if (graph != copy.graph) {
45.126 + if (attached()) {
45.127 + clear();
45.128 + detach();
45.129 + }
45.130 + if (copy.attached()) {
45.131 + attach(*copy.getRegistry());
45.132 + }
45.133 + capacity = copy.capacity;
45.134 + if (capacity == 0) return *this;
45.135 + values = allocator.allocate(capacity);
45.136 + }
45.137 +
45.138 + Item it;
45.139 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.140 + int id = graph->id(it);;
45.141 + allocator.construct(&(values[id]), copy.values[id]);
45.142 + }
45.143 +
45.144 + return *this;
45.145 + }
45.146 +
45.147 + /// The destructor of the map.
45.148 +
45.149 + virtual ~ArrayMap() {
45.150 + if (attached()) {
45.151 + clear();
45.152 + detach();
45.153 + }
45.154 + }
45.155 +
45.156 +
45.157 + ///The subscript operator. The map can be subscripted by the
45.158 + ///actual keys of the graph.
45.159 +
45.160 + Value& operator[](const Key& key) {
45.161 + int id = graph->id(key);
45.162 + return values[id];
45.163 + }
45.164 +
45.165 +
45.166 + ///The const subscript operator. The map can be subscripted by the
45.167 + ///actual keys of the graph.
45.168 +
45.169 + const Value& operator[](const Key& key) const {
45.170 + int id = graph->id(key);
45.171 + return values[id];
45.172 + }
45.173 +
45.174 + /// Setter function of the map. Equivalent with map[key] = val.
45.175 + /// This is a compatibility feature with the not dereferable maps.
45.176 +
45.177 + void set(const Key& key, const Value& val) {
45.178 + (*this)[key] = val;
45.179 + }
45.180 +
45.181 + /// Add a new key to the map. It called by the map registry.
45.182 +
45.183 + void add(const Key& key) {
45.184 + int id = graph->id(key);
45.185 + if (id >= capacity) {
45.186 + int new_capacity = (capacity == 0 ? 1 : capacity);
45.187 + while (new_capacity <= id) {
45.188 + new_capacity <<= 1;
45.189 + }
45.190 + Value* new_values = allocator.allocate(new_capacity);
45.191 + Item it;
45.192 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.193 + int jd = graph->id(it);;
45.194 + if (id != jd) {
45.195 + allocator.construct(&(new_values[jd]), values[jd]);
45.196 + allocator.destroy(&(values[jd]));
45.197 + }
45.198 + }
45.199 + if (capacity != 0) allocator.deallocate(values, capacity);
45.200 + values = new_values;
45.201 + capacity = new_capacity;
45.202 + }
45.203 + allocator.construct(&(values[id]), Value());
45.204 + }
45.205 +
45.206 + void add(const std::vector<Key>& keys) {
45.207 + int max_id = -1;
45.208 + for (int i = 0; i < (int)keys.size(); ++i) {
45.209 + int id = graph->id(keys[i]);
45.210 + if (id > max_id) {
45.211 + max_id = id;
45.212 + }
45.213 + }
45.214 + if (max_id >= capacity) {
45.215 + int new_capacity = (capacity == 0 ? 1 : capacity);
45.216 + while (new_capacity <= max_id) {
45.217 + new_capacity <<= 1;
45.218 + }
45.219 + Value* new_values = allocator.allocate(new_capacity);
45.220 + Item it;
45.221 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.222 + int id = graph->id(it);
45.223 + bool found = false;
45.224 + for (int i = 0; i < (int)keys.size(); ++i) {
45.225 + int jd = graph->id(keys[i]);
45.226 + if (id == jd) {
45.227 + found = true;
45.228 + break;
45.229 + }
45.230 + }
45.231 + if (found) continue;
45.232 + allocator.construct(&(new_values[id]), values[id]);
45.233 + allocator.destroy(&(values[id]));
45.234 + }
45.235 + if (capacity != 0) allocator.deallocate(values, capacity);
45.236 + values = new_values;
45.237 + capacity = new_capacity;
45.238 + }
45.239 + for (int i = 0; i < (int)keys.size(); ++i) {
45.240 + int id = graph->id(keys[i]);
45.241 + allocator.construct(&(values[id]), Value());
45.242 + }
45.243 + }
45.244 +
45.245 + /// Erase a key from the map. It called by the map registry.
45.246 +
45.247 + void erase(const Key& key) {
45.248 + int id = graph->id(key);
45.249 + allocator.destroy(&(values[id]));
45.250 + }
45.251 +
45.252 + void erase(const std::vector<Key>& keys) {
45.253 + for (int i = 0; i < (int)keys.size(); ++i) {
45.254 + int id = graph->id(keys[i]);
45.255 + allocator.destroy(&(values[id]));
45.256 + }
45.257 + }
45.258 +
45.259 + void build() {
45.260 + allocate_memory();
45.261 + Item it;
45.262 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.263 + int id = graph->id(it);;
45.264 + allocator.construct(&(values[id]), Value());
45.265 + }
45.266 + }
45.267 +
45.268 + void clear() {
45.269 + if (capacity != 0) {
45.270 + Item it;
45.271 + for (graph->first(it); it != INVALID; graph->next(it)) {
45.272 + int id = graph->id(it);
45.273 + allocator.destroy(&(values[id]));
45.274 + }
45.275 + allocator.deallocate(values, capacity);
45.276 + capacity = 0;
45.277 + }
45.278 + }
45.279 +
45.280 + const Graph* getGraph() {
45.281 + return graph;
45.282 + }
45.283 +
45.284 + private:
45.285 +
45.286 + void allocate_memory() {
45.287 + int max_id = graph->maxId(_Item());
45.288 + if (max_id == -1) {
45.289 + capacity = 0;
45.290 + values = 0;
45.291 + return;
45.292 + }
45.293 + capacity = 1;
45.294 + while (capacity <= max_id) {
45.295 + capacity <<= 1;
45.296 + }
45.297 + values = allocator.allocate(capacity);
45.298 + }
45.299 +
45.300 + const Graph* graph;
45.301 + int capacity;
45.302 + Value* values;
45.303 + Allocator allocator;
45.304 +
45.305 + };
45.306 +
45.307 + template <typename _Base>
45.308 + class ArrayMappableGraphExtender : public _Base {
45.309 + public:
45.310 +
45.311 + typedef ArrayMappableGraphExtender<_Base> Graph;
45.312 + typedef _Base Parent;
45.313 +
45.314 + typedef typename Parent::Node Node;
45.315 + typedef typename Parent::NodeIt NodeIt;
45.316 + typedef typename Parent::NodeNotifier NodeObserverRegistry;
45.317 +
45.318 + typedef typename Parent::Edge Edge;
45.319 + typedef typename Parent::EdgeIt EdgeIt;
45.320 + typedef typename Parent::EdgeNotifier EdgeObserverRegistry;
45.321 +
45.322 +
45.323 +
45.324 + template <typename _Value>
45.325 + class NodeMap
45.326 + : public IterableMapExtender<ArrayMap<Graph, Node, _Value> > {
45.327 + public:
45.328 + typedef ArrayMappableGraphExtender<_Base> Graph;
45.329 +
45.330 + typedef typename Graph::Node Node;
45.331 + typedef typename Graph::NodeIt NodeIt;
45.332 +
45.333 + typedef IterableMapExtender<ArrayMap<Graph, Node, _Value> > Parent;
45.334 +
45.335 + //typedef typename Parent::Graph Graph;
45.336 + typedef typename Parent::Value Value;
45.337 +
45.338 + NodeMap(const Graph& g)
45.339 + : Parent(g) {}
45.340 + NodeMap(const Graph& g, const Value& v)
45.341 + : Parent(g, v) {}
45.342 +
45.343 + };
45.344 +
45.345 + template <typename _Value>
45.346 + class EdgeMap
45.347 + : public IterableMapExtender<ArrayMap<Graph, Edge, _Value> > {
45.348 + public:
45.349 + typedef ArrayMappableGraphExtender<_Base> Graph;
45.350 +
45.351 + typedef typename Graph::Edge Edge;
45.352 + typedef typename Graph::EdgeIt EdgeIt;
45.353 +
45.354 + typedef IterableMapExtender<ArrayMap<Graph, Edge, _Value> > Parent;
45.355 +
45.356 + //typedef typename Parent::Graph Graph;
45.357 + typedef typename Parent::Value Value;
45.358 +
45.359 + EdgeMap(const Graph& g)
45.360 + : Parent(g) {}
45.361 + EdgeMap(const Graph& g, const Value& v)
45.362 + : Parent(g, v) {}
45.363 +
45.364 + };
45.365 +
45.366 + };
45.367 +
45.368 +/// @}
45.369 +
45.370 +}
45.371 +
45.372 +#endif //LEMON_ARRAY_MAP_H
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/lemon/bits/clearable_graph_extender.h Mon May 23 04:48:14 2005 +0000
46.3 @@ -0,0 +1,49 @@
46.4 +// -*- c++ -*-
46.5 +
46.6 +#ifndef LEMON_CLEARABLE_GRAPH_EXTENDER_H
46.7 +#define LEMON_CLEARABLE_GRAPH_EXTENDER_H
46.8 +
46.9 +#include <lemon/invalid.h>
46.10 +
46.11 +
46.12 +namespace lemon {
46.13 +
46.14 + template <typename _Base>
46.15 + class ClearableGraphExtender : public _Base {
46.16 + public:
46.17 +
46.18 + typedef ClearableGraphExtender Graph;
46.19 + typedef _Base Parent;
46.20 + typedef typename Parent::Node Node;
46.21 + typedef typename Parent::Edge Edge;
46.22 +
46.23 + void clear() {
46.24 + Parent::getNotifier(Node()).clear();
46.25 + Parent::getNotifier(Edge()).clear();
46.26 + Parent::clear();
46.27 + }
46.28 +
46.29 + };
46.30 +
46.31 + template <typename _Base>
46.32 + class ClearableUndirGraphExtender : public _Base {
46.33 + public:
46.34 +
46.35 + typedef ClearableUndirGraphExtender Graph;
46.36 + typedef _Base Parent;
46.37 + typedef typename Parent::Node Node;
46.38 + typedef typename Parent::UndirEdge UndirEdge;
46.39 + typedef typename Parent::Edge Edge;
46.40 +
46.41 + void clear() {
46.42 + Parent::getNotifier(Node()).clear();
46.43 + Parent::getNotifier(UndirEdge()).clear();
46.44 + Parent::getNotifier(Edge()).clear();
46.45 + Parent::clear();
46.46 + }
46.47 +
46.48 + };
46.49 +
46.50 +}
46.51 +
46.52 +#endif
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/lemon/bits/default_map.h Mon May 23 04:48:14 2005 +0000
47.3 @@ -0,0 +1,230 @@
47.4 +/* -*- C++ -*-
47.5 + * lemon/default_map.h - Part of LEMON, a generic C++ optimization library
47.6 + *
47.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
47.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
47.9 + *
47.10 + * Permission to use, modify and distribute this software is granted
47.11 + * provided that this copyright notice appears in all copies. For
47.12 + * precise terms see the accompanying LICENSE file.
47.13 + *
47.14 + * This software is provided "AS IS" with no warranty of any kind,
47.15 + * express or implied, and with no claim as to its suitability for any
47.16 + * purpose.
47.17 + *
47.18 + */
47.19 +
47.20 +#ifndef LEMON_DEFAULT_MAP_H
47.21 +#define LEMON_DEFAULT_MAP_H
47.22 +
47.23 +
47.24 +#include <lemon/bits/array_map.h>
47.25 +#include <lemon/bits/vector_map.h>
47.26 +
47.27 +///\ingroup graphmaps
47.28 +///\file
47.29 +///\brief Graph maps that construct and destruct
47.30 +///their elements dynamically.
47.31 +
47.32 +namespace lemon {
47.33 +
47.34 +/// \addtogroup graphmaps
47.35 +/// @{
47.36 +
47.37 + /** The ArrayMap template class is graph map structure what
47.38 + * automatically updates the map when a key is added to or erased from
47.39 + * the map. This map uses the VectorMap if the Value is a primitive
47.40 + * type and the ArrayMap for the other cases.
47.41 + *
47.42 + * The template parameter is the MapRegistry that the maps
47.43 + * will belong to and the Value.
47.44 + */
47.45 +
47.46 +
47.47 +
47.48 + template <typename _Graph, typename _Item, typename _Value>
47.49 + struct DefaultMapSelector {
47.50 + typedef ArrayMap<_Graph, _Item, _Value> Map;
47.51 + };
47.52 +
47.53 + // bool
47.54 + template <typename _Graph, typename _Item>
47.55 + struct DefaultMapSelector<_Graph, _Item, bool> {
47.56 + typedef VectorMap<_Graph, _Item, bool> Map;
47.57 + };
47.58 +
47.59 + // char
47.60 + template <typename _Graph, typename _Item>
47.61 + struct DefaultMapSelector<_Graph, _Item, char> {
47.62 + typedef VectorMap<_Graph, _Item, char> Map;
47.63 + };
47.64 +
47.65 + template <typename _Graph, typename _Item>
47.66 + struct DefaultMapSelector<_Graph, _Item, signed char> {
47.67 + typedef VectorMap<_Graph, _Item, signed char> Map;
47.68 + };
47.69 +
47.70 + template <typename _Graph, typename _Item>
47.71 + struct DefaultMapSelector<_Graph, _Item, unsigned char> {
47.72 + typedef VectorMap<_Graph, _Item, unsigned char> Map;
47.73 + };
47.74 +
47.75 +
47.76 + // int
47.77 + template <typename _Graph, typename _Item>
47.78 + struct DefaultMapSelector<_Graph, _Item, signed int> {
47.79 + typedef VectorMap<_Graph, _Item, signed int> Map;
47.80 + };
47.81 +
47.82 + template <typename _Graph, typename _Item>
47.83 + struct DefaultMapSelector<_Graph, _Item, unsigned int> {
47.84 + typedef VectorMap<_Graph, _Item, unsigned int> Map;
47.85 + };
47.86 +
47.87 +
47.88 + // short
47.89 + template <typename _Graph, typename _Item>
47.90 + struct DefaultMapSelector<_Graph, _Item, signed short> {
47.91 + typedef VectorMap<_Graph, _Item, signed short> Map;
47.92 + };
47.93 +
47.94 + template <typename _Graph, typename _Item>
47.95 + struct DefaultMapSelector<_Graph, _Item, unsigned short> {
47.96 + typedef VectorMap<_Graph, _Item, unsigned short> Map;
47.97 + };
47.98 +
47.99 +
47.100 + // long
47.101 + template <typename _Graph, typename _Item>
47.102 + struct DefaultMapSelector<_Graph, _Item, signed long> {
47.103 + typedef VectorMap<_Graph, _Item, signed long> Map;
47.104 + };
47.105 +
47.106 + template <typename _Graph, typename _Item>
47.107 + struct DefaultMapSelector<_Graph, _Item, unsigned long> {
47.108 + typedef VectorMap<_Graph, _Item, unsigned long> Map;
47.109 + };
47.110 +
47.111 + // \todo handling long long type
47.112 +
47.113 +
47.114 + // float
47.115 + template <typename _Graph, typename _Item>
47.116 + struct DefaultMapSelector<_Graph, _Item, float> {
47.117 + typedef VectorMap<_Graph, _Item, float> Map;
47.118 + };
47.119 +
47.120 +
47.121 + // double
47.122 + template <typename _Graph, typename _Item>
47.123 + struct DefaultMapSelector<_Graph, _Item, double> {
47.124 + typedef VectorMap<_Graph, _Item, double> Map;
47.125 + };
47.126 +
47.127 +
47.128 + // long double
47.129 + template <typename _Graph, typename _Item>
47.130 + struct DefaultMapSelector<_Graph, _Item, long double> {
47.131 + typedef VectorMap<_Graph, _Item, long double> Map;
47.132 + };
47.133 +
47.134 +
47.135 + // pointer
47.136 + template <typename _Graph, typename _Item, typename _Ptr>
47.137 + struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
47.138 + typedef VectorMap<_Graph, _Item, _Ptr*> Map;
47.139 + };
47.140 +
47.141 +
47.142 +
47.143 + template <
47.144 + typename _Graph,
47.145 + typename _Item,
47.146 + typename _Value>
47.147 + class DefaultMap
47.148 + : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
47.149 + public:
47.150 + typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
47.151 + typedef DefaultMap<_Graph, _Item, _Value> Map;
47.152 +
47.153 + typedef typename Parent::Graph Graph;
47.154 + typedef typename Parent::Value Value;
47.155 +
47.156 + DefaultMap(const Graph& _g) : Parent(_g) {}
47.157 + DefaultMap(const Graph& _g, const Value& _v) : Parent(_g, _v) {}
47.158 + };
47.159 +
47.160 +
47.161 +
47.162 + template <typename _Base>
47.163 + class DefaultMappableGraphExtender : public _Base {
47.164 + public:
47.165 +
47.166 + typedef DefaultMappableGraphExtender<_Base> Graph;
47.167 + typedef _Base Parent;
47.168 +
47.169 + typedef typename Parent::Node Node;
47.170 + typedef typename Parent::NodeIt NodeIt;
47.171 +
47.172 + typedef typename Parent::Edge Edge;
47.173 + typedef typename Parent::EdgeIt EdgeIt;
47.174 +
47.175 +
47.176 + template <typename _Value>
47.177 + class NodeMap
47.178 + : public IterableMapExtender<DefaultMap<Graph, Node, _Value> > {
47.179 + public:
47.180 + typedef DefaultMappableGraphExtender Graph;
47.181 + typedef IterableMapExtender<DefaultMap<Graph, Node, _Value> > Parent;
47.182 +
47.183 + NodeMap(const Graph& _g)
47.184 + : Parent(_g) {}
47.185 + NodeMap(const Graph& _g, const _Value& _v)
47.186 + : Parent(_g, _v) {}
47.187 + };
47.188 +
47.189 + template <typename _Value>
47.190 + class EdgeMap
47.191 + : public IterableMapExtender<DefaultMap<Graph, Edge, _Value> > {
47.192 + public:
47.193 + typedef DefaultMappableGraphExtender Graph;
47.194 + typedef IterableMapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
47.195 +
47.196 + EdgeMap(const Graph& _g)
47.197 + : Parent(_g) {}
47.198 + EdgeMap(const Graph& _g, const _Value& _v)
47.199 + : Parent(_g, _v) {}
47.200 + };
47.201 +
47.202 + };
47.203 +
47.204 + template <typename _Base>
47.205 + class MappableUndirGraphExtender :
47.206 + public DefaultMappableGraphExtender<_Base> {
47.207 + public:
47.208 +
47.209 + typedef MappableUndirGraphExtender Graph;
47.210 + typedef DefaultMappableGraphExtender<_Base> Parent;
47.211 +
47.212 + typedef typename Parent::UndirEdge UndirEdge;
47.213 +
47.214 + template <typename _Value>
47.215 + class UndirEdgeMap
47.216 + : public IterableMapExtender<DefaultMap<Graph, UndirEdge, _Value> > {
47.217 + public:
47.218 + typedef MappableUndirGraphExtender Graph;
47.219 + typedef IterableMapExtender<
47.220 + DefaultMap<Graph, UndirEdge, _Value> > Parent;
47.221 +
47.222 + UndirEdgeMap(const Graph& _g)
47.223 + : Parent(_g) {}
47.224 + UndirEdgeMap(const Graph& _g, const _Value& _v)
47.225 + : Parent(_g, _v) {}
47.226 + };
47.227 +
47.228 +
47.229 + };
47.230 +
47.231 +}
47.232 +
47.233 +#endif
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/lemon/bits/erasable_graph_extender.h Mon May 23 04:48:14 2005 +0000
48.3 @@ -0,0 +1,84 @@
48.4 +// -*- c++ -*-
48.5 +
48.6 +#ifndef LEMON_ERASABLE_GRAPH_EXTENDER_H
48.7 +#define LEMON_ERASABLE_GRAPH_EXTENDER_H
48.8 +
48.9 +#include <vector>
48.10 +
48.11 +#include <lemon/invalid.h>
48.12 +
48.13 +
48.14 +namespace lemon {
48.15 +
48.16 + template <typename _Base>
48.17 + class ErasableGraphExtender : public _Base {
48.18 + public:
48.19 +
48.20 + typedef ErasableGraphExtender Graph;
48.21 + typedef _Base Parent;
48.22 +
48.23 + typedef typename Parent::Node Node;
48.24 + typedef typename Parent::Edge Edge;
48.25 +
48.26 + void erase(const Node& node) {
48.27 + Edge edge;
48.28 + Parent::firstOut(edge, node);
48.29 + while (edge != INVALID ) {
48.30 + erase(edge);
48.31 + Parent::firstOut(edge, node);
48.32 + }
48.33 +
48.34 + Parent::firstIn(edge, node);
48.35 + while (edge != INVALID ) {
48.36 + erase(edge);
48.37 + Parent::firstIn(edge, node);
48.38 + }
48.39 +
48.40 + Parent::getNotifier(Node()).erase(node);
48.41 + Parent::erase(node);
48.42 + }
48.43 +
48.44 + void erase(const Edge& edge) {
48.45 + Parent::getNotifier(Edge()).erase(edge);
48.46 + Parent::erase(edge);
48.47 + }
48.48 +
48.49 + };
48.50 +
48.51 + template <typename _Base>
48.52 + class ErasableUndirGraphExtender : public _Base {
48.53 + public:
48.54 +
48.55 + typedef ErasableUndirGraphExtender Graph;
48.56 + typedef _Base Parent;
48.57 +
48.58 + typedef typename Parent::Node Node;
48.59 + typedef typename Parent::UndirEdge UndirEdge;
48.60 + typedef typename Parent::Edge Edge;
48.61 +
48.62 + void erase(const Node& node) {
48.63 + Edge edge;
48.64 + Parent::firstOut(edge, node);
48.65 + while (edge != INVALID ) {
48.66 + erase(edge);
48.67 + Parent::firstOut(edge, node);
48.68 + }
48.69 +
48.70 + Parent::getNotifier(Node()).erase(node);
48.71 + Parent::erase(node);
48.72 + }
48.73 +
48.74 + void erase(const UndirEdge& uedge) {
48.75 + std::vector<Edge> edges;
48.76 + edges.push_back(Edge(uedge,true));
48.77 + edges.push_back(Edge(uedge,false));
48.78 + Parent::getNotifier(Edge()).erase(edges);
48.79 + Parent::getNotifier(UndirEdge()).erase(uedge);
48.80 + Parent::erase(uedge);
48.81 + }
48.82 +
48.83 + };
48.84 +
48.85 +}
48.86 +
48.87 +#endif
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/lemon/bits/extendable_graph_extender.h Mon May 23 04:48:14 2005 +0000
49.3 @@ -0,0 +1,65 @@
49.4 +// -*- c++ -*-
49.5 +
49.6 +#ifndef LEMON_EXTENDABLE_GRAPH_EXTENDER_H
49.7 +#define LEMON_EXTENDABLE_GRAPH_EXTENDER_H
49.8 +
49.9 +namespace lemon {
49.10 +
49.11 + template <typename _Base>
49.12 + class ExtendableGraphExtender : public _Base {
49.13 + public:
49.14 +
49.15 + typedef ExtendableGraphExtender Graph;
49.16 + typedef _Base Parent;
49.17 +
49.18 + typedef typename Parent::Node Node;
49.19 + typedef typename Parent::Edge Edge;
49.20 +
49.21 + Node addNode() {
49.22 + Node node = Parent::addNode();
49.23 + Parent::getNotifier(Node()).add(node);
49.24 + return node;
49.25 + }
49.26 +
49.27 + Edge addEdge(const Node& from, const Node& to) {
49.28 + Edge edge = Parent::addEdge(from, to);
49.29 + Parent::getNotifier(Edge()).add(edge);
49.30 + return edge;
49.31 + }
49.32 +
49.33 + };
49.34 +
49.35 + template <typename _Base>
49.36 + class ExtendableUndirGraphExtender : public _Base {
49.37 + public:
49.38 +
49.39 + typedef ExtendableUndirGraphExtender Graph;
49.40 + typedef _Base Parent;
49.41 +
49.42 + typedef typename Parent::Node Node;
49.43 + typedef typename Parent::Edge Edge;
49.44 + typedef typename Parent::UndirEdge UndirEdge;
49.45 +
49.46 + Node addNode() {
49.47 + Node node = Parent::addNode();
49.48 + Parent::getNotifier(Node()).add(node);
49.49 + return node;
49.50 + }
49.51 +
49.52 + UndirEdge addEdge(const Node& from, const Node& to) {
49.53 + UndirEdge uedge = Parent::addEdge(from, to);
49.54 + Parent::getNotifier(UndirEdge()).add(uedge);
49.55 +
49.56 + std::vector<Edge> edges;
49.57 + edges.push_back(Edge(uedge, true));
49.58 + edges.push_back(Edge(uedge, false));
49.59 + Parent::getNotifier(Edge()).add(edges);
49.60 +
49.61 + return uedge;
49.62 + }
49.63 +
49.64 + };
49.65 +
49.66 +}
49.67 +
49.68 +#endif
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/lemon/bits/extended_pair.h Mon May 23 04:48:14 2005 +0000
50.3 @@ -0,0 +1,146 @@
50.4 +/* -*- C++ -*-
50.5 + * lemon/bits/extended_pair.h - Part of LEMON, a generic C++ optimization library
50.6 + *
50.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
50.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
50.9 + *
50.10 + * Permission to use, modify and distribute this software is granted
50.11 + * provided that this copyright notice appears in all copies. For
50.12 + * precise terms see the accompanying LICENSE file.
50.13 + *
50.14 + * This software is provided "AS IS" with no warranty of any kind,
50.15 + * express or implied, and with no claim as to its suitability for any
50.16 + * purpose.
50.17 + *
50.18 + */
50.19 +
50.20 +#ifndef LEMON_EXTENDED_PAIR_H
50.21 +#define LEMON_EXTENDED_PAIR_H
50.22 +
50.23 +///\ingroup misc
50.24 +///\file
50.25 +///\brief A more customizable pair type than std::pair.
50.26 +
50.27 +namespace lemon {
50.28 +
50.29 + /// \brief A more customizable pair type than std::pair.
50.30 + ///
50.31 + /// This type is a customizable pair type. The main goal
50.32 + /// is that the constructor's parameter type does not depend
50.33 + /// on the stored data type. This way it is possible to store
50.34 + /// references in the extended_pair.
50.35 + /// \code
50.36 + /// int a; char b;
50.37 + /// typedef extended_pair<int&, int&, char&, char&> ICPair;
50.38 + /// ICPair p(a, b);
50.39 + /// // like a real reference to an std::pair<int, char>
50.40 + /// // but the pair does not exist
50.41 + /// p.first = 42;
50.42 + /// p.second = '@';
50.43 + /// \endcode
50.44 + /// \param T1 The type of first.
50.45 + /// \param A1 The parameter type for first.
50.46 + /// \param T2 The type of second.
50.47 + /// \param A2 The parameter type for second.
50.48 + template <typename T1, typename A1, typename T2, typename A2>
50.49 + struct extended_pair {
50.50 + /// \brief The type of first.
50.51 + ///
50.52 + /// The type of first.
50.53 + typedef T1 first_type;
50.54 + /// \brief The type of second.
50.55 + ///
50.56 + /// The type of second.
50.57 + typedef T2 second_type;
50.58 +
50.59 + /// \brief Default constructor.
50.60 + ///
50.61 + /// Default constructor. It calls the default constructor of
50.62 + /// first and second.
50.63 + extended_pair() : first(), second() {}
50.64 +
50.65 + /// \brief Constructor.
50.66 + ///
50.67 + /// Constructor.
50.68 + extended_pair(A1 f, A2 s) : first(f), second(s) {}
50.69 +
50.70 + /// \brief Template constructor.
50.71 + ///
50.72 + /// Template constructor. It copies everything which has
50.73 + /// \c first and \c second member.
50.74 + template <class Pair>
50.75 + extended_pair(const Pair& pair) : first(pair.first), second(pair.second) {}
50.76 +
50.77 + /// \brief The first value
50.78 + ///
50.79 + /// The first value
50.80 + T1 first;
50.81 + /// \brief The second value
50.82 + ///
50.83 + /// The second value
50.84 + T2 second;
50.85 + };
50.86 +
50.87 + /// \brief Equality operator
50.88 + ///
50.89 + /// Equality operator
50.90 + template <typename T1, typename T2,
50.91 + typename LA1, typename LA2, typename RA1, typename RA2>
50.92 + bool operator==(const extended_pair<T1, LA1, T2, LA2>& left,
50.93 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.94 + return left.first == right.first && left.second == right.second;
50.95 + }
50.96 +
50.97 + /// \brief Inequality operator.
50.98 + ///
50.99 + /// Inequality operator.
50.100 + template <typename T1, typename T2,
50.101 + typename LA1, typename LA2, typename RA1, typename RA2>
50.102 + bool operator!=(const extended_pair<T1, LA1, T2, LA2>& left,
50.103 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.104 + return !(left == right);
50.105 + }
50.106 +
50.107 + /// \brief Less operator.
50.108 + ///
50.109 + /// Less operator.
50.110 + template <typename T1, typename T2,
50.111 + typename LA1, typename LA2, typename RA1, typename RA2>
50.112 + bool operator<(const extended_pair<T1, LA1, T2, LA2>& left,
50.113 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.114 + return left.first < right.first ||
50.115 + (!(right.first<left.first) && left.second < right.second);
50.116 + }
50.117 +
50.118 + /// \brief Greater operator.
50.119 + ///
50.120 + /// Greater operator.
50.121 + template <typename T1, typename T2,
50.122 + typename LA1, typename LA2, typename RA1, typename RA2>
50.123 + bool operator>(const extended_pair<T1, LA1, T2, LA2>& left,
50.124 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.125 + return right < left;
50.126 + }
50.127 +
50.128 + /// \brief Less or equal operator.
50.129 + ///
50.130 + /// Less or equal operator.
50.131 + template <typename T1, typename T2,
50.132 + typename LA1, typename LA2, typename RA1, typename RA2>
50.133 + bool operator<=(const extended_pair<T1, LA1, T2, LA2>& left,
50.134 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.135 + return !(right > left);
50.136 + }
50.137 +
50.138 + /// \brief Greater or equal operator.
50.139 + ///
50.140 + /// Greater or equal operator.
50.141 + template <typename T1, typename T2,
50.142 + typename LA1, typename LA2, typename RA1, typename RA2>
50.143 + bool operator>=(const extended_pair<T1, LA1, T2, LA2>& left,
50.144 + const extended_pair<T1, RA1, T2, RA2>& right) {
50.145 + return !(right < left);
50.146 + }
50.147 +
50.148 +}
50.149 +#endif
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/lemon/bits/item_reader.h Mon May 23 04:48:14 2005 +0000
51.3 @@ -0,0 +1,414 @@
51.4 +/* -*- C++ -*-
51.5 + * lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
51.6 + *
51.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
51.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
51.9 + *
51.10 + * Permission to use, modify and distribute this software is granted
51.11 + * provided that this copyright notice appears in all copies. For
51.12 + * precise terms see the accompanying LICENSE file.
51.13 + *
51.14 + * This software is provided "AS IS" with no warranty of any kind,
51.15 + * express or implied, and with no claim as to its suitability for any
51.16 + * purpose.
51.17 + *
51.18 + */
51.19 +
51.20 +/// @defgroup item_io Item Readers and Writers
51.21 +/// @ingroup io_group
51.22 +/// \brief Item Readers and Writers
51.23 +///
51.24 +/// The Input-Output classes can handle more data type by example
51.25 +/// as map or attribute value. Each of these should be written and
51.26 +/// read some way. The module make possible to do this.
51.27 +
51.28 +/// \ingroup item_io
51.29 +/// \file
51.30 +/// \brief Item reader bits for lemon input.
51.31 +
51.32 +#ifndef LEMON_BITS_ITEM_READER_H
51.33 +#define LEMON_BITS_ITEM_READER_H
51.34 +
51.35 +#include <iostream>
51.36 +#include <string>
51.37 +
51.38 +#include <vector>
51.39 +#include <deque>
51.40 +#include <list>
51.41 +#include <set>
51.42 +
51.43 +namespace lemon {
51.44 +
51.45 + template <typename Value>
51.46 + class DefaultReader;
51.47 +
51.48 + /// \ingroup item_io
51.49 + ///
51.50 + /// \brief Reader class for quoted strings.
51.51 + ///
51.52 + /// Reader class for quoted strings. It can process the escape
51.53 + /// sequences in the string.
51.54 + ///
51.55 + /// \author Balazs Dezso
51.56 + class QuotedStringReader {
51.57 + public:
51.58 + /// \brief The value type of reader.
51.59 + ///
51.60 + /// The value type of reader.
51.61 + typedef std::string Value;
51.62 +
51.63 + /// \brief Constructor for the reader.
51.64 + ///
51.65 + /// Constructor for the reader. If the given parameter is true
51.66 + /// the reader processes the escape sequences.
51.67 + QuotedStringReader(bool _escaped = true)
51.68 + : escaped(_escaped) {}
51.69 +
51.70 + /// \brief Reads a quoted string from the given stream.
51.71 + ///
51.72 + /// Reads a quoted string from the given stream.
51.73 + void read(std::istream& is, std::string& value) const {
51.74 + char c;
51.75 + value.clear();
51.76 + is >> std::ws;
51.77 + if (!is.get(c) || c != '\"')
51.78 + throw DataFormatError("Quoted string format error");
51.79 + while (is.get(c) && c != '\"') {
51.80 + if (escaped && c == '\\') {
51.81 + value += readEscape(is);
51.82 + } else {
51.83 + value += c;
51.84 + }
51.85 + }
51.86 + if (!is) throw DataFormatError("Quoted string format error");
51.87 + }
51.88 +
51.89 + private:
51.90 +
51.91 + static char readEscape(std::istream& is) {
51.92 + char c;
51.93 + switch (is.get(c), c) {
51.94 + case '\\':
51.95 + return '\\';
51.96 + case '\"':
51.97 + return '\"';
51.98 + case '\'':
51.99 + return '\'';
51.100 + case '\?':
51.101 + return '\?';
51.102 + case 'a':
51.103 + return '\a';
51.104 + case 'b':
51.105 + return '\b';
51.106 + case 'f':
51.107 + return '\f';
51.108 + case 'n':
51.109 + return '\n';
51.110 + case 'r':
51.111 + return '\r';
51.112 + case 't':
51.113 + return '\t';
51.114 + case 'v':
51.115 + return '\v';
51.116 + case 'x':
51.117 + {
51.118 + int code;
51.119 + if (!is.get(c) || !isHex(c))
51.120 + throw DataFormatError("Escape format error");
51.121 + else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
51.122 + else code = code * 16 + valueHex(c);
51.123 + return code;
51.124 + }
51.125 + default:
51.126 + {
51.127 + int code;
51.128 + if (!isOct(c))
51.129 + throw DataFormatError("Escape format error");
51.130 + else if (code = valueOct(c), !is.get(c) || !isOct(c))
51.131 + is.putback(c);
51.132 + else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
51.133 + is.putback(c);
51.134 + else code = code * 8 + valueOct(c);
51.135 + return code;
51.136 + }
51.137 + }
51.138 + }
51.139 +
51.140 + static bool isOct(char c) {
51.141 + return '0' <= c && c <='7';
51.142 + }
51.143 +
51.144 + static int valueOct(char c) {
51.145 + return c - '0';
51.146 + }
51.147 +
51.148 + static bool isHex(char c) {
51.149 + return ('0' <= c && c <= '9') ||
51.150 + ('a' <= c && c <= 'z') ||
51.151 + ('A' <= c && c <= 'Z');
51.152 + }
51.153 +
51.154 + static int valueHex(char c) {
51.155 + if ('0' <= c && c <= '9') return c - '0';
51.156 + if ('a' <= c && c <= 'z') return c - 'a' + 10;
51.157 + return c - 'A' + 10;
51.158 + }
51.159 +
51.160 + bool escaped;
51.161 + };
51.162 +
51.163 + /// \ingroup item_io
51.164 + /// \brief Reader for standard containers.
51.165 + ///
51.166 + /// Reader for back insertable standard containers. The representation
51.167 + /// of the container is the values enumerated between an open and a
51.168 + /// close parse.
51.169 + ///
51.170 + /// \author Balazs Dezso
51.171 + template <
51.172 + typename _Container,
51.173 + typename _ItemReader = DefaultReader<typename _Container::value_type>
51.174 + >
51.175 + class PushBackReader {
51.176 + public:
51.177 + typedef _Container Value;
51.178 + typedef _ItemReader ItemReader;
51.179 +
51.180 + private:
51.181 +
51.182 + ItemReader item_reader;
51.183 +
51.184 + public:
51.185 +
51.186 + /// \brief Reads the values into the container from the given stream.
51.187 + ///
51.188 + /// Reads the values into the container from the given stream.
51.189 + void read(std::istream& is, Value& value) const {
51.190 + char c;
51.191 + if (!(is >> c) || c != '(')
51.192 + throw DataFormatError("PushBackReader format error");
51.193 + while (is >> c && c != ')') {
51.194 + is.putback(c);
51.195 + typename ItemReader::Value item;
51.196 + item_reader.read(is, item);
51.197 + value.push_back(item);
51.198 + }
51.199 + if (!is) throw DataFormatError("PushBackReader format error");
51.200 + is.putback(c);
51.201 + }
51.202 +
51.203 + };
51.204 +
51.205 + /// \ingroup item_io
51.206 + ///
51.207 + /// \brief Reader for standard containers.
51.208 + ///
51.209 + /// Reader for insertable standard containers. The representation
51.210 + /// of the container is the values enumerated between an open and a
51.211 + /// close parse.
51.212 + ///
51.213 + /// \author Balazs Dezso
51.214 + template <
51.215 + typename _Container,
51.216 + typename _ItemReader = DefaultReader<typename _Container::value_type>
51.217 + >
51.218 + class InsertReader {
51.219 + public:
51.220 + typedef _Container Value;
51.221 + typedef _ItemReader ItemReader;
51.222 +
51.223 + private:
51.224 +
51.225 + ItemReader item_reader;
51.226 +
51.227 + public:
51.228 +
51.229 + /// \brief Reads the values into the container from the given stream.
51.230 + ///
51.231 + /// Reads the values into the container from the given stream.
51.232 + void read(std::istream& is, Value& value) const {
51.233 + char c;
51.234 + if (!(is >> c) || c != '(')
51.235 + throw DataFormatError("InsertReader format error");
51.236 + while (is >> c && c != ')') {
51.237 + is.putback(c);
51.238 + typename ItemReader::Value item;
51.239 + item_reader.read(is, item);
51.240 + value.insert(item);
51.241 + }
51.242 + if (!is) throw DataFormatError("PushBackReader format error");
51.243 + is.putback(c);
51.244 + }
51.245 +
51.246 + };
51.247 +
51.248 + /// \ingroup item_io
51.249 + /// \brief Reader for parsed string.
51.250 + ///
51.251 + /// Reader for parsed strings. You can give the open and close
51.252 + /// parse characters.
51.253 + ///
51.254 + /// \author Balazs Dezso
51.255 + class ParsedStringReader {
51.256 + public:
51.257 + typedef std::string Value;
51.258 +
51.259 + /// \brief Constructor.
51.260 + ///
51.261 + /// Constructor for ParsedStringReader. You can give as parameter
51.262 + /// the open and close parse characters.
51.263 + ParsedStringReader(char _open = '(', char _close = ')')
51.264 + : open(_open), close(_close) {}
51.265 +
51.266 +
51.267 + /// \brief Reads the parsed string from the given stream.
51.268 + ///
51.269 + /// Reads the parsed string from the given stream.
51.270 + void read(std::istream& is, Value& value) const {
51.271 + char c;
51.272 + if (!(is >> c) || c != open) {
51.273 + throw DataFormatError("ParsedStringReader format error");
51.274 + }
51.275 + value += c;
51.276 + int counter = 1;
51.277 + while (counter > 0 && is >> c) {
51.278 + if (c == close) {
51.279 + --counter;
51.280 + } else if (c == open) {
51.281 + ++counter;
51.282 + }
51.283 + value += c;
51.284 + }
51.285 + if (!is) {
51.286 + throw DataFormatError("ParsedStrinReader format error");
51.287 + }
51.288 + }
51.289 +
51.290 + private:
51.291 + char open, close;
51.292 +
51.293 + };
51.294 +
51.295 + /// \ingroup item_io
51.296 + /// \brief Reader for read the whole line.
51.297 + ///
51.298 + /// Reader for read the whole line.
51.299 + ///
51.300 + /// \author Balazs Dezso
51.301 + class LineReader {
51.302 + public:
51.303 + typedef std::string Value;
51.304 +
51.305 + /// \brief Constructor.
51.306 + ///
51.307 + /// Constructor for the LineReader. If the given parameter is
51.308 + /// true then the spaces before the first not space character are
51.309 + /// skipped.
51.310 + LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
51.311 +
51.312 + /// \brief Reads the line from the given stream.
51.313 + ///
51.314 + /// Reads the line from the given stream.
51.315 + void read(std::istream& is, Value& value) {
51.316 + if (skipSpaces) is >> std::ws;
51.317 + if (!getline(is, value)) {
51.318 + throw DataFormatError("LineReader forma error");
51.319 + }
51.320 + }
51.321 + private:
51.322 + bool skipSpaces;
51.323 + };
51.324 +
51.325 + /// \ingroup item_io
51.326 + ///
51.327 + /// \brief The default item reader template class.
51.328 + ///
51.329 + /// The default item reader template class. If some section reader
51.330 + /// needs to read a value from a stream it will give the default way for it.
51.331 + ///
51.332 + /// \author Balazs Dezso
51.333 + template <typename _Value>
51.334 + class DefaultReader {
51.335 + public:
51.336 + /// The value type.
51.337 + typedef _Value Value;
51.338 + /// \brief Reads a value from the given stream.
51.339 + ///
51.340 + /// Reads a value from the given stream.
51.341 + void read(std::istream& is, Value& value) const {
51.342 + if (!(is >> value))
51.343 + throw DataFormatError("DefaultReader format error");
51.344 + }
51.345 + };
51.346 +
51.347 + template <>
51.348 + class DefaultReader<std::string> {
51.349 + public:
51.350 + typedef std::string Value;
51.351 +
51.352 + void read(std::istream& is, Value& value) const {
51.353 + char c;
51.354 + if (!(is >> std::ws >> c)) return;
51.355 + is.putback(c);
51.356 + switch (c) {
51.357 + case '\"':
51.358 + QuotedStringReader().read(is, value);
51.359 + break;
51.360 + case '(':
51.361 + ParsedStringReader().read(is, value);
51.362 + break;
51.363 + default:
51.364 + is >> value;
51.365 + break;
51.366 + }
51.367 + }
51.368 +
51.369 + };
51.370 +
51.371 + template <typename Item>
51.372 + class DefaultReader<std::vector<Item> >
51.373 + : public PushBackReader<std::vector<Item> > {};
51.374 +
51.375 + template <typename Item>
51.376 + class DefaultReader<std::deque<Item> >
51.377 + : public PushBackReader<std::deque<Item> > {};
51.378 +
51.379 + template <typename Item>
51.380 + class DefaultReader<std::list<Item> >
51.381 + : public PushBackReader<std::list<Item> > {};
51.382 +
51.383 + template <typename Item>
51.384 + class DefaultReader<std::set<Item> >
51.385 + : public InsertReader<std::set<Item> > {};
51.386 +
51.387 + template <typename Item>
51.388 + class DefaultReader<std::multiset<Item> >
51.389 + : public InsertReader<std::multiset<Item> > {};
51.390 +
51.391 + /// \ingroup item_io
51.392 + ///
51.393 + /// \brief The default item reader for skipping a value in the stream.
51.394 + ///
51.395 + /// The default item reader for skipping a value in the stream.
51.396 + ///
51.397 + /// \author Balazs Dezso
51.398 + class DefaultSkipper : public DefaultReader<std::string> {};
51.399 +
51.400 + /// \ingroup item_io
51.401 + /// \brief Standard ReaderTraits for the GraphReader class.
51.402 + ///
51.403 + /// Standard ReaderTraits for the GraphReader class.
51.404 + /// It defines standard reading method for all type of value.
51.405 + /// \author Balazs Dezso
51.406 + struct DefaultReaderTraits {
51.407 +
51.408 + template <typename _Value>
51.409 + struct Reader : DefaultReader<_Value> {};
51.410 +
51.411 + typedef DefaultSkipper Skipper;
51.412 +
51.413 + };
51.414 +
51.415 +}
51.416 +
51.417 +#endif
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/lemon/bits/item_writer.h Mon May 23 04:48:14 2005 +0000
52.3 @@ -0,0 +1,219 @@
52.4 +/* -*- C++ -*-
52.5 + * lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
52.6 + *
52.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
52.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
52.9 + *
52.10 + * Permission to use, modify and distribute this software is granted
52.11 + * provided that this copyright notice appears in all copies. For
52.12 + * precise terms see the accompanying LICENSE file.
52.13 + *
52.14 + * This software is provided "AS IS" with no warranty of any kind,
52.15 + * express or implied, and with no claim as to its suitability for any
52.16 + * purpose.
52.17 + *
52.18 + */
52.19 +
52.20 +/// \ingroup item_io
52.21 +/// \file
52.22 +/// \brief Item writer bits for lemon output.
52.23 +
52.24 +#ifndef LEMON_BITS_ITEM_WRITER_H
52.25 +#define LEMON_BITS_ITEM_WRITER_H
52.26 +
52.27 +#include <iostream>
52.28 +#include <string>
52.29 +
52.30 +#include <vector>
52.31 +#include <deque>
52.32 +#include <list>
52.33 +#include <set>
52.34 +
52.35 +namespace lemon {
52.36 +
52.37 + template <typename Value>
52.38 + class DefaultWriter;
52.39 +
52.40 + /// \ingroup item_io
52.41 + /// \brief Writer class for quoted strings.
52.42 + ///
52.43 + /// Writer class for quoted strings. It can process the escape
52.44 + /// sequences in the string.
52.45 + /// \author Balazs Dezso
52.46 + class QuotedStringWriter {
52.47 + public:
52.48 + typedef std::string Value;
52.49 +
52.50 + /// \brief Constructor for the writer.
52.51 + ///
52.52 + /// Constructor for the writer. If the given parameter is true
52.53 + /// the writer creates escape sequences from special characters.
52.54 + QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
52.55 +
52.56 + /// \brief Writes a quoted string to the given stream.
52.57 + ///
52.58 + /// Writes a quoted string to the given stream.
52.59 + void write(std::ostream& os, const std::string& value) {
52.60 + os << "\"";
52.61 + if (escaped) {
52.62 + std::ostringstream ls;
52.63 + for (int i = 0; i < (int)value.size(); ++i) {
52.64 + writeEscape(ls, value[i]);
52.65 + }
52.66 + os << ls.str();
52.67 + } else {
52.68 + os << value;
52.69 + }
52.70 + os << "\"";
52.71 + }
52.72 +
52.73 + private:
52.74 +
52.75 + static void writeEscape(std::ostream& os, char c) {
52.76 + switch (c) {
52.77 + case '\\':
52.78 + os << "\\\\";
52.79 + return;
52.80 + case '\"':
52.81 + os << "\\\"";
52.82 + return;
52.83 + case '\'':
52.84 + os << "\\\'";
52.85 + return;
52.86 + case '\?':
52.87 + os << "\\\?";
52.88 + return;
52.89 + case '\a':
52.90 + os << "\\a";
52.91 + return;
52.92 + case '\b':
52.93 + os << "\\b";
52.94 + return;
52.95 + case '\f':
52.96 + os << "\\f";
52.97 + return;
52.98 + case '\r':
52.99 + os << "\\r";
52.100 + return;
52.101 + case '\n':
52.102 + os << "\\n";
52.103 + return;
52.104 + case '\t':
52.105 + os << "\\t";
52.106 + return;
52.107 + case '\v':
52.108 + os << "\\v";
52.109 + return;
52.110 + default:
52.111 + if (c < 0x20) {
52.112 + os << '\\' << std::oct << (int)c;
52.113 + } else {
52.114 + os << c;
52.115 + }
52.116 + return;
52.117 + }
52.118 + }
52.119 + private:
52.120 + bool escaped;
52.121 + };
52.122 +
52.123 + /// \ingroup item_io
52.124 + ///
52.125 + /// \brief Writer for standard containers.
52.126 + ///
52.127 + /// Writer for each iterable standard containers. The representation
52.128 + /// of the container is the values enumerated between an open and a
52.129 + /// close parse.
52.130 + ///
52.131 + /// \author Balazs Dezso
52.132 + template <
52.133 + typename _Container,
52.134 + typename _ItemWriter = DefaultWriter<typename _Container::value_type>
52.135 + >
52.136 + class IterableWriter {
52.137 + public:
52.138 + typedef _Container Value;
52.139 + typedef _ItemWriter ItemWriter;
52.140 +
52.141 + private:
52.142 +
52.143 + ItemWriter item_writer;
52.144 +
52.145 + public:
52.146 +
52.147 + /// \brief Writes the values of the container to the given stream.
52.148 + ///
52.149 + /// Writes the values of the container to the given stream.
52.150 + void write(std::ostream& os, const Value& value) const {
52.151 + typename Value::const_iterator it;
52.152 + os << '(';
52.153 + for (it = value.begin(); it != value.end(); ++it) {
52.154 + item_writer.write(os, *it);
52.155 + os << ' ';
52.156 + }
52.157 + os << ')';
52.158 + }
52.159 +
52.160 + };
52.161 +
52.162 + /// \ingroup item_io
52.163 + ///
52.164 + /// \brief The default item writer template class.
52.165 + ///
52.166 + /// The default item writer template class. If some section writer
52.167 + /// needs to write a value to the stream it will give the default way for it.
52.168 + ///
52.169 + /// \author Balazs Dezso
52.170 + template <typename _Value>
52.171 + class DefaultWriter {
52.172 + public:
52.173 + /// The value type.
52.174 + typedef _Value Value;
52.175 + /// \brief Writes the value to the given stream.
52.176 + ///
52.177 + /// Writes the value to the given stream.
52.178 + void write(std::ostream& os, const Value& value) const {
52.179 + os << value;
52.180 + }
52.181 + };
52.182 +
52.183 + template <>
52.184 + class DefaultWriter<std::string>
52.185 + : public QuotedStringWriter {};
52.186 +
52.187 + template <typename Item>
52.188 + class DefaultWriter<std::vector<Item> >
52.189 + : public IterableWriter<std::vector<Item> > {};
52.190 +
52.191 + template <typename Item>
52.192 + class DefaultWriter<std::deque<Item> >
52.193 + : public IterableWriter<std::deque<Item> > {};
52.194 +
52.195 + template <typename Item>
52.196 + class DefaultWriter<std::list<Item> >
52.197 + : public IterableWriter<std::list<Item> > {};
52.198 +
52.199 + template <typename Item>
52.200 + class DefaultWriter<std::set<Item> >
52.201 + : public IterableWriter<std::set<Item> > {};
52.202 +
52.203 + template <typename Item>
52.204 + class DefaultWriter<std::multiset<Item> >
52.205 + : public IterableWriter<std::multiset<Item> > {};
52.206 +
52.207 + /// \ingroup item_io
52.208 + /// \brief Standard WriterTraits for the section writers.
52.209 + ///
52.210 + /// Standard WriterTraits for the section writers.
52.211 + /// It defines standard writing method for all type of value.
52.212 + /// \author Balazs Dezso
52.213 + struct DefaultWriterTraits {
52.214 +
52.215 + template <typename _Value>
52.216 + struct Writer : DefaultWriter<_Value> {};
52.217 +
52.218 + };
52.219 +
52.220 +}
52.221 +
52.222 +#endif
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/lemon/bits/iterable_graph_extender.h Mon May 23 04:48:14 2005 +0000
53.3 @@ -0,0 +1,250 @@
53.4 +// -*- c++ -*-
53.5 +#ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
53.6 +#define LEMON_ITERABLE_GRAPH_EXTENDER_H
53.7 +
53.8 +#include <lemon/invalid.h>
53.9 +
53.10 +namespace lemon {
53.11 +
53.12 + template <typename _Base>
53.13 + class IterableGraphExtender : public _Base {
53.14 + public:
53.15 +
53.16 + typedef _Base Parent;
53.17 + typedef IterableGraphExtender<_Base> Graph;
53.18 +
53.19 + typedef typename Parent::Node Node;
53.20 + typedef typename Parent::Edge Edge;
53.21 +
53.22 +
53.23 + class NodeIt : public Node {
53.24 + const Graph* graph;
53.25 + public:
53.26 +
53.27 + NodeIt() {}
53.28 +
53.29 + NodeIt(Invalid i) : Node(i) { }
53.30 +
53.31 + explicit NodeIt(const Graph& _graph) : graph(&_graph) {
53.32 + _graph.first(*static_cast<Node*>(this));
53.33 + }
53.34 +
53.35 + NodeIt(const Graph& _graph, const Node& node)
53.36 + : Node(node), graph(&_graph) {}
53.37 +
53.38 + NodeIt& operator++() {
53.39 + graph->next(*this);
53.40 + return *this;
53.41 + }
53.42 +
53.43 + };
53.44 +
53.45 +
53.46 + class EdgeIt : public Edge {
53.47 + const Graph* graph;
53.48 + public:
53.49 +
53.50 + EdgeIt() { }
53.51 +
53.52 + EdgeIt(Invalid i) : Edge(i) { }
53.53 +
53.54 + explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
53.55 + _graph.first(*static_cast<Edge*>(this));
53.56 + }
53.57 +
53.58 + EdgeIt(const Graph& _graph, const Edge& e) :
53.59 + Edge(e), graph(&_graph) { }
53.60 +
53.61 + EdgeIt& operator++() {
53.62 + graph->next(*this);
53.63 + return *this;
53.64 + }
53.65 +
53.66 + };
53.67 +
53.68 +
53.69 + class OutEdgeIt : public Edge {
53.70 + const Graph* graph;
53.71 + public:
53.72 +
53.73 + OutEdgeIt() { }
53.74 +
53.75 + OutEdgeIt(Invalid i) : Edge(i) { }
53.76 +
53.77 + OutEdgeIt(const Graph& _graph, const Node& node)
53.78 + : graph(&_graph) {
53.79 + _graph.firstOut(*this, node);
53.80 + }
53.81 +
53.82 + OutEdgeIt(const Graph& _graph, const Edge& edge)
53.83 + : Edge(edge), graph(&_graph) {}
53.84 +
53.85 + OutEdgeIt& operator++() {
53.86 + graph->nextOut(*this);
53.87 + return *this;
53.88 + }
53.89 +
53.90 + };
53.91 +
53.92 +
53.93 + class InEdgeIt : public Edge {
53.94 + const Graph* graph;
53.95 + public:
53.96 +
53.97 + InEdgeIt() { }
53.98 +
53.99 + InEdgeIt(Invalid i) : Edge(i) { }
53.100 +
53.101 + InEdgeIt(const Graph& _graph, const Node& node)
53.102 + : graph(&_graph) {
53.103 + _graph.firstIn(*this, node);
53.104 + }
53.105 +
53.106 + InEdgeIt(const Graph& _graph, const Edge& edge) :
53.107 + Edge(edge), graph(&_graph) {}
53.108 +
53.109 + InEdgeIt& operator++() {
53.110 + graph->nextIn(*this);
53.111 + return *this;
53.112 + }
53.113 +
53.114 + };
53.115 +
53.116 + /// Base node of the iterator
53.117 + ///
53.118 + /// Returns the base node (ie. the source in this case) of the iterator
53.119 + ///
53.120 + /// \todo Document in the concept!
53.121 + Node baseNode(const OutEdgeIt &e) const {
53.122 + return source(e);
53.123 + }
53.124 + /// Running node of the iterator
53.125 + ///
53.126 + /// Returns the running node (ie. the target in this case) of the
53.127 + /// iterator
53.128 + ///
53.129 + /// \todo Document in the concept!
53.130 + Node runningNode(const OutEdgeIt &e) const {
53.131 + return target(e);
53.132 + }
53.133 +
53.134 + /// Base node of the iterator
53.135 + ///
53.136 + /// Returns the base node (ie. the target in this case) of the iterator
53.137 + ///
53.138 + /// \todo Document in the concept!
53.139 + Node baseNode(const InEdgeIt &e) const {
53.140 + return target(e);
53.141 + }
53.142 + /// Running node of the iterator
53.143 + ///
53.144 + /// Returns the running node (ie. the source in this case) of the
53.145 + /// iterator
53.146 + ///
53.147 + /// \todo Document in the concept!
53.148 + Node runningNode(const InEdgeIt &e) const {
53.149 + return source(e);
53.150 + }
53.151 +
53.152 + using Parent::first;
53.153 +
53.154 + private:
53.155 +
53.156 + // /// \todo When (and if) we change the iterators concept to use operator*,
53.157 + // /// then the following shadowed methods will become superfluous.
53.158 + // /// But for now these are important safety measures.
53.159 +
53.160 + // void first(NodeIt &) const;
53.161 + // void first(EdgeIt &) const;
53.162 + // void first(OutEdgeIt &) const;
53.163 + // void first(InEdgeIt &) const;
53.164 +
53.165 + };
53.166 +
53.167 +
53.168 +
53.169 +
53.170 +
53.171 +
53.172 + template <typename _Base>
53.173 + class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
53.174 + public:
53.175 +
53.176 + typedef IterableGraphExtender<_Base> Parent;
53.177 + typedef IterableUndirGraphExtender<_Base> Graph;
53.178 + typedef typename Parent::Node Node;
53.179 +
53.180 + typedef typename Parent::UndirEdge UndirEdge;
53.181 +
53.182 + class UndirEdgeIt : public Parent::UndirEdge {
53.183 + const Graph* graph;
53.184 + public:
53.185 +
53.186 + UndirEdgeIt() { }
53.187 +
53.188 + UndirEdgeIt(Invalid i) : UndirEdge(i) { }
53.189 +
53.190 + explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
53.191 + _graph.first(*static_cast<UndirEdge*>(this));
53.192 + }
53.193 +
53.194 + UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
53.195 + UndirEdge(e), graph(&_graph) { }
53.196 +
53.197 + UndirEdgeIt& operator++() {
53.198 + graph->next(*this);
53.199 + return *this;
53.200 + }
53.201 +
53.202 + };
53.203 +
53.204 + class IncEdgeIt : public Parent::UndirEdge {
53.205 + const Graph* graph;
53.206 + bool forward;
53.207 + friend class IterableUndirGraphExtender;
53.208 + template <typename G>
53.209 + friend class UndirGraphExtender;
53.210 + public:
53.211 +
53.212 + IncEdgeIt() { }
53.213 +
53.214 + IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
53.215 +
53.216 + IncEdgeIt(const Graph& _graph, const Node &n)
53.217 + : graph(&_graph)
53.218 + {
53.219 + _graph._dirFirstOut(*this, n);
53.220 + }
53.221 +
53.222 + IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
53.223 + : graph(&_graph), UndirEdge(ue)
53.224 + {
53.225 + forward = (_graph.source(ue) == n);
53.226 + }
53.227 +
53.228 + IncEdgeIt& operator++() {
53.229 + graph->_dirNextOut(*this);
53.230 + return *this;
53.231 + }
53.232 + };
53.233 +
53.234 + using Parent::baseNode;
53.235 + using Parent::runningNode;
53.236 +
53.237 + /// Base node of the iterator
53.238 + ///
53.239 + /// Returns the base node of the iterator
53.240 + Node baseNode(const IncEdgeIt &e) const {
53.241 + return _dirSource(e);
53.242 + }
53.243 + /// Running node of the iterator
53.244 + ///
53.245 + /// Returns the running node of the iterator
53.246 + Node runningNode(const IncEdgeIt &e) const {
53.247 + return _dirTarget(e);
53.248 + }
53.249 +
53.250 + };
53.251 +}
53.252 +
53.253 +#endif // LEMON_GRAPH_EXTENDER_H
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/lemon/bits/map_iterator.h Mon May 23 04:48:14 2005 +0000
54.3 @@ -0,0 +1,855 @@
54.4 +/* -*- C++ -*-
54.5 + * lemon/map_iterator.h - Part of LEMON, a generic C++ optimization library
54.6 + *
54.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
54.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
54.9 + *
54.10 + * Permission to use, modify and distribute this software is granted
54.11 + * provided that this copyright notice appears in all copies. For
54.12 + * precise terms see the accompanying LICENSE file.
54.13 + *
54.14 + * This software is provided "AS IS" with no warranty of any kind,
54.15 + * express or implied, and with no claim as to its suitability for any
54.16 + * purpose.
54.17 + *
54.18 + */
54.19 +
54.20 +#ifndef LEMON_MAP_ITERATOR_H
54.21 +#define LEMON_MAP_ITERATOR_H
54.22 +
54.23 +#include <iterator>
54.24 +
54.25 +#include <lemon/bits/extended_pair.h>
54.26 +#include <lemon/graph_utils.h>
54.27 +
54.28 +///\ingroup graphmaps
54.29 +///\file
54.30 +///\brief Iterators on the maps.
54.31 +
54.32 +namespace lemon {
54.33 +
54.34 + /// \addtogroup graphmaps
54.35 + /// @{
54.36 +
54.37 + /** The base class all of the map iterators.
54.38 + * The class defines the typedefs of the iterators,
54.39 + * simple step functions and equality operators.
54.40 + */
54.41 +
54.42 + template <
54.43 + typename _Graph,
54.44 + typename _Item>
54.45 + class MapIteratorBase {
54.46 +
54.47 + protected:
54.48 +
54.49 + /// The key type of the iterator.
54.50 + typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
54.51 +
54.52 + ItemIt it;
54.53 +
54.54 + /// Default constructor.
54.55 + MapIteratorBase() {}
54.56 +
54.57 + /// ItemIt initialized MapIteratorBase constructor.
54.58 + MapIteratorBase(const ItemIt _it) : it(_it) {}
54.59 +
54.60 + public:
54.61 +
54.62 + /// Stepping forward in the map.
54.63 + void increment() {
54.64 + ++it;
54.65 + }
54.66 +
54.67 + /// The equality operator of the map.
54.68 + bool operator==(const MapIteratorBase& _it) const {
54.69 + return _it.it == it;
54.70 + }
54.71 +
54.72 + /// The not-equality operator of the map.
54.73 + bool operator!=(const MapIteratorBase& _it) const {
54.74 + return !(*this == _it);
54.75 + }
54.76 + };
54.77 +
54.78 +
54.79 + template <
54.80 + typename _Graph,
54.81 + typename _Item,
54.82 + typename _Map>
54.83 + class MapConstIterator;
54.84 +
54.85 + /** Compatible iterator with the stl maps' iterators.
54.86 + * It iterates on pairs of a key and a value.
54.87 + */
54.88 + template <
54.89 + typename _Graph,
54.90 + typename _Item,
54.91 + typename _Map>
54.92 + class MapIterator : public MapIteratorBase<_Graph, _Item> {
54.93 +
54.94 + friend class MapConstIterator<_Graph, _Item, _Map>;
54.95 +
54.96 +
54.97 + public:
54.98 +
54.99 + /// The iterator base class.
54.100 + typedef MapIteratorBase<_Graph, _Item> Parent;
54.101 +
54.102 + typedef _Item Item;
54.103 + typedef _Map Map;
54.104 + typedef _Graph Graph;
54.105 +
54.106 + protected:
54.107 +
54.108 + typedef typename Parent::ItemIt ItemIt;
54.109 +
54.110 + typedef typename ReferenceMapTraits<_Map>::Value MapValue;
54.111 + typedef typename ReferenceMapTraits<_Map>::Reference MapReference;
54.112 +
54.113 + public:
54.114 +
54.115 + /// The value type of the iterator.
54.116 + typedef extended_pair<Item, const Item&,
54.117 + MapValue, const MapValue&> Value;
54.118 +
54.119 + /// The reference type of the iterator.
54.120 + typedef extended_pair<const Item&, const Item&,
54.121 + MapReference, MapReference> Reference;
54.122 +
54.123 + /// Default constructor.
54.124 + MapIterator() {}
54.125 +
54.126 + /// Constructor to initalize the iterators returned
54.127 + /// by the begin() and end().
54.128 + MapIterator(Map& _map, const ItemIt& _it)
54.129 + : Parent(_it), map(&_map) {}
54.130 +
54.131 + /// Dereference operator for the iterator.
54.132 + Reference operator*() {
54.133 + return Reference(Parent::it, (*map)[Parent::it]);
54.134 + }
54.135 +
54.136 + /// The pointer type of the iterator.
54.137 + class Pointer {
54.138 + friend class MapIterator;
54.139 + protected:
54.140 + Reference data;
54.141 + Pointer(const Item& item, MapReference val)
54.142 + : data(item, val) {}
54.143 + public:
54.144 + Reference* operator->() {return &data;}
54.145 + };
54.146 +
54.147 + /// Arrow operator for the iterator.
54.148 + Pointer operator->() {
54.149 + return Pointer(Parent::it, (*map)[Parent::it]);
54.150 + }
54.151 +
54.152 + /// The pre increment operator of the iterator.
54.153 + MapIterator& operator++() {
54.154 + Parent::increment();
54.155 + return *this;
54.156 + }
54.157 +
54.158 + /// The post increment operator of the iterator.
54.159 + MapIterator operator++(int) {
54.160 + MapIterator tmp(*this);
54.161 + Parent::increment();
54.162 + return tmp;
54.163 + }
54.164 +
54.165 + protected:
54.166 +
54.167 + Map* map;
54.168 +
54.169 + public:
54.170 + // STL compatibility typedefs.
54.171 + typedef std::forward_iterator_tag iterator_category;
54.172 + typedef int difference_type;
54.173 + typedef Value value_type;
54.174 + typedef Reference reference;
54.175 + typedef Pointer pointer;
54.176 + };
54.177 +
54.178 + /** Compatible iterator with the stl maps' iterators.
54.179 + * It iterates on pairs of a key and a value.
54.180 + */
54.181 + template <
54.182 + typename _Graph,
54.183 + typename _Item,
54.184 + typename _Map>
54.185 + class MapConstIterator : public MapIteratorBase<_Graph, _Item> {
54.186 +
54.187 + public:
54.188 +
54.189 + /// The iterator base class.
54.190 + typedef MapIteratorBase<_Graph, _Item> Parent;
54.191 +
54.192 + typedef _Graph Graph;
54.193 + typedef _Item Item;
54.194 + typedef _Map Map;
54.195 +
54.196 + protected:
54.197 +
54.198 + typedef typename Parent::ItemIt ItemIt;
54.199 +
54.200 + typedef typename ReferenceMapTraits<_Map>::Value MapValue;
54.201 + typedef typename ReferenceMapTraits<_Map>::ConstReference
54.202 + MapReference;
54.203 +
54.204 + public:
54.205 +
54.206 + /// The value type of the iterator.
54.207 + typedef extended_pair<Item, const Item&,
54.208 + MapValue, const MapValue&> Value;
54.209 +
54.210 + /// The reference type of the iterator.
54.211 + typedef extended_pair<const Item&, const Item&,
54.212 + MapReference, MapReference> Reference;
54.213 +
54.214 + /// Default constructor.
54.215 + MapConstIterator() {}
54.216 +
54.217 + /// Constructor to initalize the iterators returned
54.218 + /// by the begin() and end().
54.219 + MapConstIterator(const Map& _map, const ItemIt& _it)
54.220 + : Parent(_it), map(&_map) {}
54.221 +
54.222 + /// Dereference operator for the iterator.
54.223 + Reference operator*() {
54.224 + return Reference(Parent::it, (*map)[Parent::it]);
54.225 + }
54.226 +
54.227 + /// The pointer type of the iterator.
54.228 + class Pointer {
54.229 + friend class MapConstIterator;
54.230 + protected:
54.231 + Reference data;
54.232 + Pointer(const Item& item, MapReference val)
54.233 + : data(item, val) {}
54.234 + public:
54.235 + Reference* operator->() {return &data;}
54.236 + };
54.237 +
54.238 + /// Arrow operator for the iterator.
54.239 + Pointer operator->() {
54.240 + return Pointer(Parent::it, ((*map)[Parent::it]));
54.241 + }
54.242 +
54.243 + /// The pre increment operator of the iterator.
54.244 + MapConstIterator& operator++() {
54.245 + Parent::increment();
54.246 + return *this;
54.247 + }
54.248 +
54.249 + /// The post increment operator of the iterator.
54.250 + MapConstIterator operator++(int) {
54.251 + MapConstIterator tmp(*this);
54.252 + Parent::increment();
54.253 + return tmp;
54.254 + }
54.255 +
54.256 + protected:
54.257 + const Map* map;
54.258 +
54.259 + public:
54.260 + // STL compatibility typedefs.
54.261 + typedef std::forward_iterator_tag iterator_category;
54.262 + typedef int difference_type;
54.263 + typedef Value value_type;
54.264 + typedef Reference reference;
54.265 + typedef Pointer pointer;
54.266 + };
54.267 +
54.268 + /** The class makes the ItemIt to an stl compatible iterator
54.269 + * with dereferencing operator.
54.270 + */
54.271 + template <
54.272 + typename _Graph,
54.273 + typename _Item>
54.274 + class MapConstKeyIterator : public MapIteratorBase<_Graph, _Item> {
54.275 +
54.276 + public:
54.277 +
54.278 + /// The iterator base class.
54.279 + typedef MapIteratorBase<_Graph, _Item> Parent;
54.280 +
54.281 + typedef _Graph Graph;
54.282 + typedef _Item Item;
54.283 +
54.284 + protected:
54.285 + /// The iterator to iterate on the keys.
54.286 + typedef typename Parent::ItemIt ItemIt;
54.287 +
54.288 + public:
54.289 +
54.290 + typedef Item Value;
54.291 + typedef const Item& Reference;
54.292 + typedef const Item* Pointer;
54.293 +
54.294 + /// Default constructor.
54.295 + MapConstKeyIterator() {}
54.296 +
54.297 + /// ItemIt initialized iterator.
54.298 + MapConstKeyIterator(const ItemIt& pit) : Parent(pit) {}
54.299 +
54.300 + /// The pre increment operator of the iterator.
54.301 + MapConstKeyIterator& operator++() {
54.302 + Parent::increment();
54.303 + return *this;
54.304 + }
54.305 +
54.306 + /// The post increment operator of the iterator.
54.307 + MapConstKeyIterator operator++(int) {
54.308 + MapConstKeyIterator tmp(*this);
54.309 + Parent::increment();
54.310 + return tmp;
54.311 + }
54.312 +
54.313 + /// The dereferencing operator of the iterator.
54.314 + Item operator*() const {
54.315 + return static_cast<Item>(Parent::it);
54.316 + }
54.317 +
54.318 + public:
54.319 + // STL compatibility typedefs.
54.320 + typedef std::input_iterator_tag iterator_category;
54.321 + typedef int difference_type;
54.322 + typedef Value value_type;
54.323 + typedef Reference reference;
54.324 + typedef Pointer pointer;
54.325 + };
54.326 +
54.327 + template <
54.328 + typename _Graph,
54.329 + typename _Item,
54.330 + typename _Map>
54.331 + class MapConstValueIterator;
54.332 +
54.333 + /** MapValueIterator creates an stl compatible iterator
54.334 + * for the values.
54.335 + */
54.336 + template <
54.337 + typename _Graph,
54.338 + typename _Item,
54.339 + typename _Map>
54.340 + class MapValueIterator : public MapIteratorBase<_Graph, _Item> {
54.341 +
54.342 + friend class MapConstValueIterator<_Graph, _Item, _Map>;
54.343 +
54.344 + public:
54.345 +
54.346 + /// The iterator base class.
54.347 + typedef MapIteratorBase<_Graph, _Item> Parent;
54.348 +
54.349 + typedef _Graph Graph;
54.350 + typedef _Item Item;
54.351 + typedef _Map Map;
54.352 +
54.353 + protected:
54.354 +
54.355 + /// The iterator to iterate on the keys.
54.356 + typedef typename Parent::ItemIt ItemIt;
54.357 +
54.358 + /// The value type of the iterator.
54.359 + typedef typename ReferenceMapTraits<Map>::Value MapValue;
54.360 + /// The reference type of the iterator.
54.361 + typedef typename ReferenceMapTraits<Map>::Reference MapReference;
54.362 + /// The pointer type of the iterator.
54.363 + typedef typename ReferenceMapTraits<Map>::Pointer MapPointer;
54.364 +
54.365 + public:
54.366 +
54.367 + typedef MapValue Value;
54.368 + typedef MapReference Reference;
54.369 + typedef MapPointer Pointer;
54.370 +
54.371 + /// Default constructor.
54.372 + MapValueIterator() {}
54.373 +
54.374 + /// Map and ItemIt initialized iterator.
54.375 + MapValueIterator(Map& _map, const ItemIt& _it)
54.376 + : Parent(_it), map(&_map) {}
54.377 +
54.378 +
54.379 + /// The pre increment operator of the iterator.
54.380 + MapValueIterator& operator++() {
54.381 + Parent::increment();
54.382 + return *this;
54.383 + }
54.384 +
54.385 + /// The post increment operator of the iterator.
54.386 + MapValueIterator operator++(int) {
54.387 + MapValueIterator tmp(*this);
54.388 + Parent::increment();
54.389 + return tmp;
54.390 + }
54.391 +
54.392 + /// The dereferencing operator of the iterator.
54.393 + Reference operator*() const {
54.394 + return (*map)[Parent::it];
54.395 + }
54.396 +
54.397 + /// The arrow operator of the iterator.
54.398 + Pointer operator->() const {
54.399 + return &(operator*());
54.400 + }
54.401 +
54.402 + protected:
54.403 +
54.404 + Map* map;
54.405 +
54.406 + public:
54.407 + // STL compatibility typedefs.
54.408 + typedef std::forward_iterator_tag iterator_category;
54.409 + typedef int difference_type;
54.410 + typedef Value value_type;
54.411 + typedef Reference reference;
54.412 + typedef Pointer pointer;
54.413 + };
54.414 +
54.415 + /** MapValueIterator creates an stl compatible iterator
54.416 + * for the values.
54.417 + */
54.418 + template <
54.419 + typename _Graph,
54.420 + typename _Item,
54.421 + typename _Map>
54.422 + class MapConstValueIterator : public MapIteratorBase<_Graph, _Item> {
54.423 +
54.424 + public:
54.425 +
54.426 + /// The iterator base class.
54.427 + typedef MapIteratorBase<_Graph, _Item> Parent;
54.428 +
54.429 + typedef _Graph Graph;
54.430 + typedef _Item Item;
54.431 + typedef _Map Map;
54.432 +
54.433 + protected:
54.434 +
54.435 + /// The iterator to iterate on the keys.
54.436 + typedef typename Parent::ItemIt ItemIt;
54.437 +
54.438 + /// The value type of the iterator.
54.439 + typedef typename ReferenceMapTraits<Map>::Value MapValue;
54.440 + /// The reference type of the iterator.
54.441 + typedef typename ReferenceMapTraits<Map>::ConstReference MapReference;
54.442 + /// The pointer type of the iterator.
54.443 + typedef typename ReferenceMapTraits<Map>::ConstPointer MapPointer;
54.444 +
54.445 + public:
54.446 +
54.447 + typedef MapValue Value;
54.448 + typedef MapReference Reference;
54.449 + typedef MapPointer Pointer;
54.450 +
54.451 + /// Default constructor.
54.452 + MapConstValueIterator() {}
54.453 +
54.454 + /// Map and ItemIt initialized iterator.
54.455 + MapConstValueIterator(const Map& _map, const ItemIt& _it)
54.456 + : Parent(_it), map(&_map) {}
54.457 +
54.458 +
54.459 + /// The pre increment operator of the iterator.
54.460 + MapConstValueIterator& operator++() {
54.461 + Parent::increment();
54.462 + return *this;
54.463 + }
54.464 +
54.465 + /// The post increment operator of the iterator.
54.466 + MapConstValueIterator operator++(int) {
54.467 + MapConstValueIterator tmp(*this);
54.468 + Parent::increment();
54.469 + return tmp;
54.470 + }
54.471 +
54.472 + /// The dereferencing operator of the iterator.
54.473 + Reference operator*() const {
54.474 + return (*map)[Parent::it];
54.475 + }
54.476 +
54.477 + /// The arrow operator of the iterator.
54.478 + Pointer operator->() const {
54.479 + return &(operator*());
54.480 + }
54.481 +
54.482 + protected:
54.483 +
54.484 + const Map* map;
54.485 +
54.486 + public:
54.487 + // STL compatibility typedefs.
54.488 + typedef std::forward_iterator_tag iterator_category;
54.489 + typedef int difference_type;
54.490 + typedef Value value_type;
54.491 + typedef Reference reference;
54.492 + typedef Pointer pointer;
54.493 + };
54.494 +
54.495 +
54.496 + /** This class makes from a map an iteratable set
54.497 + * which contains all the keys of the map.
54.498 + */
54.499 + template <typename _Graph, typename _Item>
54.500 + class MapConstKeySet {
54.501 +
54.502 + public:
54.503 +
54.504 + typedef _Graph Graph;
54.505 + /// The key type of the iterator.
54.506 + typedef _Item Item;
54.507 + /// The iterator to iterate on the keys.
54.508 +
54.509 + protected:
54.510 +
54.511 + typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
54.512 +
54.513 + public:
54.514 +
54.515 + /// The map initialized const key set.
54.516 + MapConstKeySet(const Graph& _graph) : graph(&_graph) {}
54.517 +
54.518 + /// The const iterator of the set.
54.519 + typedef MapConstKeyIterator<_Graph, _Item> ConstIterator;
54.520 +
54.521 + typedef typename ConstIterator::Value Value;
54.522 + /// The reference type of the iterator.
54.523 + typedef typename ConstIterator::Reference ConstReference;
54.524 + /// The pointer type of the iterator.
54.525 + typedef typename ConstIterator::Pointer ConstPointer;
54.526 +
54.527 + /// It gives back the const iterator pointed to the first element.
54.528 + ConstIterator begin() const {
54.529 + return ConstIterator(ItemIt(*graph));
54.530 + }
54.531 +
54.532 + /// It gives back the const iterator pointed to the first ivalid element.
54.533 + ConstIterator end() const {
54.534 + return ConstIterator(ItemIt(INVALID));
54.535 + }
54.536 +
54.537 + protected:
54.538 +
54.539 + const Graph* graph;
54.540 +
54.541 + public:
54.542 + // STL compatibility typedefs.
54.543 + typedef Value value_type;
54.544 + typedef ConstIterator const_iterator;
54.545 + typedef ConstReference const_reference;
54.546 + typedef ConstPointer const_pointer;
54.547 + typedef int difference_type;
54.548 + };
54.549 +
54.550 + /** This class makes from a map an iteratable set
54.551 + * which contains all the values of the map.
54.552 + * The values cannot be modified.
54.553 + */
54.554 + template <typename _Graph, typename _Item, typename _Map>
54.555 + class MapConstValueSet {
54.556 +
54.557 + public:
54.558 +
54.559 + typedef _Graph Graph;
54.560 + typedef _Item Item;
54.561 + typedef _Map Map;
54.562 +
54.563 + protected:
54.564 +
54.565 + /// The iterator to iterate on the keys.
54.566 + typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
54.567 +
54.568 + public:
54.569 +
54.570 + /// The map initialized const value set.
54.571 + MapConstValueSet(const Graph& _graph, const Map& _map)
54.572 + : graph(&_graph), map(&_map) {}
54.573 +
54.574 + /// The const iterator of the set.
54.575 + typedef MapConstValueIterator<_Graph, _Item, _Map> ConstIterator;
54.576 +
54.577 + typedef typename ConstIterator::Value Value;
54.578 + typedef typename ConstIterator::Reference ConstReference;
54.579 + typedef typename ConstIterator::Pointer ConstPointer;
54.580 +
54.581 + /// It gives back the const iterator pointed to the first element.
54.582 + ConstIterator begin() const {
54.583 + return ConstIterator(*map, ItemIt(*graph));
54.584 + }
54.585 +
54.586 + /// It gives back the const iterator pointed to the first invalid element.
54.587 + ConstIterator end() const {
54.588 + return ConstIterator(*map, ItemIt(INVALID));
54.589 + }
54.590 +
54.591 + protected:
54.592 +
54.593 + const Map* map;
54.594 + const Graph * graph;
54.595 +
54.596 + public:
54.597 + // STL compatibility typedefs.
54.598 + typedef Value value_type;
54.599 + typedef ConstIterator const_iterator;
54.600 + typedef ConstReference const_reference;
54.601 + typedef ConstPointer const_pointer;
54.602 + typedef int difference_type;
54.603 + };
54.604 +
54.605 +
54.606 + /** This class makes from a map an iteratable set
54.607 + * which contains all the values of the map.
54.608 + * The values can be modified.
54.609 + */
54.610 + template <typename _Graph, typename _Item, typename _Map>
54.611 + class MapValueSet {
54.612 +
54.613 + public:
54.614 +
54.615 + typedef _Graph Graph;
54.616 + typedef _Item Item;
54.617 + typedef _Map Map;
54.618 +
54.619 + protected:
54.620 +
54.621 + /// The iterator to iterate on the keys.
54.622 + typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
54.623 +
54.624 + public:
54.625 +
54.626 + /// The map initialized const value set.
54.627 + MapValueSet(const Graph& _graph, Map& _map)
54.628 + : map(&_map), graph(&_graph) {}
54.629 +
54.630 + /// The const iterator of the set.
54.631 + typedef MapValueIterator<_Graph, _Item, _Map> Iterator;
54.632 + /// The const iterator of the set.
54.633 + typedef MapConstValueIterator<_Graph, _Item, _Map> ConstIterator;
54.634 +
54.635 + typedef typename ConstIterator::Value Value;
54.636 + typedef typename Iterator::Reference Reference;
54.637 + typedef typename Iterator::Pointer Pointer;
54.638 + typedef typename ConstIterator::Reference ConstReference;
54.639 + typedef typename ConstIterator::Pointer ConstPointer;
54.640 +
54.641 + /// It gives back the const iterator pointed to the first element.
54.642 + ConstIterator begin() const {
54.643 + return ConstIterator(*map, ItemIt(*graph));
54.644 + }
54.645 +
54.646 + /// It gives back the const iterator pointed to the first invalid element.
54.647 + ConstIterator end() const {
54.648 + return ConstIterator(*map, ItemIt(INVALID));
54.649 + }
54.650 +
54.651 + /// It gives back the iterator pointed to the first element.
54.652 + Iterator begin() {
54.653 + return Iterator(*map, ItemIt(*graph));
54.654 + }
54.655 +
54.656 + /// It gives back the iterator pointed to the first invalid element.
54.657 + Iterator end() {
54.658 + return Iterator(*map, ItemIt(INVALID));
54.659 + }
54.660 +
54.661 + protected:
54.662 +
54.663 + Map* map;
54.664 + const Graph * graph;
54.665 +
54.666 + public:
54.667 + // STL compatibility typedefs.
54.668 + typedef Value value_type;
54.669 + typedef Iterator iterator;
54.670 + typedef ConstIterator const_iterator;
54.671 + typedef Reference reference;
54.672 + typedef ConstReference const_reference;
54.673 + typedef Pointer pointer;
54.674 + typedef ConstPointer const_pointer;
54.675 + typedef int difference_type;
54.676 +
54.677 + };
54.678 +
54.679 + /** This class makes from a map an iteratable set
54.680 + * which contains all the values of the map.
54.681 + * The values can be modified.
54.682 + */
54.683 + template <
54.684 + typename _Graph,
54.685 + typename _Item,
54.686 + typename _Map
54.687 + >
54.688 + class MapSet {
54.689 + public:
54.690 +
54.691 + typedef _Graph Graph;
54.692 + typedef _Item Item;
54.693 + typedef _Map Map;
54.694 +
54.695 + protected:
54.696 +
54.697 + typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
54.698 +
54.699 + public:
54.700 +
54.701 + /// The map initialized value set.
54.702 + MapSet(const Graph& _graph, Map& _map) : graph(&_graph), map(&_map) {}
54.703 +
54.704 + /// The const iterator of the set.
54.705 + typedef MapIterator<_Graph, _Item, _Map> Iterator;
54.706 + typedef MapConstIterator<_Graph, _Item, _Map> ConstIterator;
54.707 +
54.708 + typedef typename ConstIterator::Value Value;
54.709 + typedef typename Iterator::Reference Reference;
54.710 + typedef typename Iterator::Pointer Pointer;
54.711 + typedef typename ConstIterator::Reference ConstReference;
54.712 + typedef typename ConstIterator::Pointer ConstPointer;
54.713 +
54.714 +
54.715 + /// It gives back the const iterator pointed to the first element.
54.716 + ConstIterator begin() const {
54.717 + return ConstIterator(*map, ItemIt(*graph));
54.718 + }
54.719 +
54.720 + /// It gives back the const iterator pointed to the first invalid element.
54.721 + ConstIterator end() const {
54.722 + return ConstIterator(*map, ItemIt(INVALID));
54.723 + }
54.724 +
54.725 + /// The iterator of the set.
54.726 +
54.727 + /// It gives back the iterator pointed to the first element.
54.728 + Iterator begin() {
54.729 + return Iterator(*map, ItemIt(*graph));
54.730 + }
54.731 +
54.732 + /// It gives back the iterator pointed to the first invalid element.
54.733 + Iterator end() {
54.734 + return Iterator(*map, ItemIt(INVALID));
54.735 + }
54.736 +
54.737 + protected:
54.738 +
54.739 + const Graph* graph;
54.740 + Map* map;
54.741 +
54.742 + public:
54.743 + // STL compatibility typedefs.
54.744 + typedef Value value_type;
54.745 + typedef Iterator iterator;
54.746 + typedef ConstIterator const_iterator;
54.747 + typedef Reference reference;
54.748 + typedef ConstReference const_reference;
54.749 + typedef Pointer pointer;
54.750 + typedef ConstPointer const_pointer;
54.751 + typedef int difference_type;
54.752 +
54.753 + };
54.754 +
54.755 + template <
54.756 + typename _Graph,
54.757 + typename _Item,
54.758 + typename _Map
54.759 + >
54.760 + class ConstMapSet {
54.761 +
54.762 + typedef _Graph Graph;
54.763 + typedef _Map Map;
54.764 +
54.765 + const Graph* graph;
54.766 + const Map* map;
54.767 +
54.768 + public:
54.769 +
54.770 + typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
54.771 +
54.772 +
54.773 + /// The map initialized value set.
54.774 + ConstMapSet(const Graph& _graph, const Map& _map)
54.775 + : graph(&_graph), map(&_map) {}
54.776 +
54.777 + /// The const iterator of the set.
54.778 + typedef MapConstIterator<_Graph, _Item, _Map> ConstIterator;
54.779 +
54.780 + typedef typename ConstIterator::Value Value;
54.781 + typedef typename ConstIterator::Reference ConstReference;
54.782 + typedef typename ConstIterator::Pointer ConstPointer;
54.783 +
54.784 +
54.785 + /// It gives back the const iterator pointed to the first element.
54.786 + ConstIterator begin() const {
54.787 + return ConstIterator(*map, ItemIt(*graph));
54.788 + }
54.789 +
54.790 + /// It gives back the const iterator pointed to the first invalid element.
54.791 + ConstIterator end() const {
54.792 + return ConstIterator(*map, ItemIt(INVALID));
54.793 + }
54.794 +
54.795 + public:
54.796 + // STL compatibility typedefs.
54.797 + typedef Value value_type;
54.798 + typedef ConstIterator const_iterator;
54.799 + typedef ConstReference const_reference;
54.800 + typedef ConstPointer const_pointer;
54.801 + typedef int difference_type;
54.802 +
54.803 + };
54.804 +
54.805 + template <typename _Map>
54.806 + class IterableMapExtender : public _Map {
54.807 + public:
54.808 +
54.809 + typedef _Map Parent;
54.810 + typedef Parent Map;
54.811 + typedef typename Map::Graph Graph;
54.812 + typedef typename Map::Key Item;
54.813 + typedef typename Map::Value Value;
54.814 +
54.815 + typedef MapSet<Graph, Item, Map> MapSet;
54.816 +
54.817 + IterableMapExtender() : Parent() {}
54.818 +
54.819 + IterableMapExtender(const Graph& graph) : Parent(graph) {}
54.820 +
54.821 + IterableMapExtender(const Graph& graph, const Value& value)
54.822 + : Parent(graph, value) {}
54.823 +
54.824 + MapSet mapSet() {
54.825 + return MapSet(*Parent::getGraph(), *this);
54.826 + }
54.827 +
54.828 + typedef ConstMapSet<Graph, Item, Map> ConstMapSet;
54.829 +
54.830 + ConstMapSet mapSet() const {
54.831 + return ConstMapSet(*Parent::getGraph(), *this);
54.832 + }
54.833 +
54.834 + typedef MapConstKeySet<Graph, Item> ConstKeySet;
54.835 +
54.836 + ConstKeySet keySet() const {
54.837 + return ConstKeySet(*Parent::getGraph());
54.838 + }
54.839 +
54.840 + typedef MapValueSet<Graph, Item, Map> ValueSet;
54.841 +
54.842 + ValueSet valueSet() {
54.843 + return ValueSet(*Parent::getGraph(), *this);
54.844 + }
54.845 +
54.846 + typedef MapConstValueSet<Graph, Item, Map> ConstValueSet;
54.847 +
54.848 + ConstValueSet valueSet() const {
54.849 + return ConstValueSet(*Parent::getGraph(), *this);
54.850 + }
54.851 +
54.852 + };
54.853 +
54.854 + /// @}
54.855 +
54.856 +}
54.857 +
54.858 +#endif
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/lemon/bits/undir_graph_extender.h Mon May 23 04:48:14 2005 +0000
55.3 @@ -0,0 +1,278 @@
55.4 +/* -*- C++ -*-
55.5 + *
55.6 + * lemon/undir_graph_extender.h - Part of LEMON, a generic C++
55.7 + * optimization library
55.8 + *
55.9 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
55.10 + * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
55.11 + * EGRES).
55.12 + *
55.13 + * Permission to use, modify and distribute this software is granted
55.14 + * provided that this copyright notice appears in all copies. For
55.15 + * precise terms see the accompanying LICENSE file.
55.16 + *
55.17 + * This software is provided "AS IS" with no warranty of any kind,
55.18 + * express or implied, and with no claim as to its suitability for any
55.19 + * purpose.
55.20 + *
55.21 + */
55.22 +
55.23 +#ifndef LEMON_UNDIR_GRAPH_EXTENDER_H
55.24 +#define LEMON_UNDIR_GRAPH_EXTENDER_H
55.25 +
55.26 +#include <lemon/invalid.h>
55.27 +
55.28 +namespace lemon {
55.29 +
55.30 + template <typename _Base>
55.31 + class UndirGraphExtender : public _Base {
55.32 + typedef _Base Parent;
55.33 + typedef UndirGraphExtender Graph;
55.34 +
55.35 + public:
55.36 +
55.37 + typedef typename Parent::Edge UndirEdge;
55.38 + typedef typename Parent::Node Node;
55.39 +
55.40 + class Edge : public UndirEdge {
55.41 + friend class UndirGraphExtender;
55.42 +
55.43 + protected:
55.44 + // FIXME: Marci use opposite logic in his graph adaptors. It would
55.45 + // be reasonable to syncronize...
55.46 + bool forward;
55.47 +
55.48 + public:
55.49 + Edge() {}
55.50 +
55.51 + /// \brief Directed edge from undirected edge and a direction.
55.52 + ///
55.53 + /// This constructor is not a part of the concept interface of
55.54 + /// undirected graph, so please avoid using it if possible!
55.55 + Edge(const UndirEdge &ue, bool _forward) :
55.56 + UndirEdge(ue), forward(_forward) {}
55.57 +
55.58 + /// \brief Directed edge from undirected edge and a source node.
55.59 + ///
55.60 + /// Constructs a directed edge from undirected edge and a source node.
55.61 + ///
55.62 + /// \note You have to specify the graph for this constructor.
55.63 + Edge(const Graph &g, const UndirEdge &ue, const Node &n) :
55.64 + UndirEdge(ue) { forward = (g.source(ue) == n); }
55.65 +
55.66 + /// Invalid edge constructor
55.67 + Edge(Invalid i) : UndirEdge(i), forward(true) {}
55.68 +
55.69 + bool operator==(const Edge &that) const {
55.70 + return forward==that.forward && UndirEdge(*this)==UndirEdge(that);
55.71 + }
55.72 + bool operator!=(const Edge &that) const {
55.73 + return forward!=that.forward || UndirEdge(*this)!=UndirEdge(that);
55.74 + }
55.75 + bool operator<(const Edge &that) const {
55.76 + return forward<that.forward ||
55.77 + (!(that.forward<forward) && UndirEdge(*this)<UndirEdge(that));
55.78 + }
55.79 + };
55.80 +
55.81 +
55.82 + /// \brief Edge of opposite direction.
55.83 + ///
55.84 + /// Returns the Edge of opposite direction.
55.85 + Edge opposite(const Edge &e) const {
55.86 + return Edge(e,!e.forward);
55.87 + }
55.88 +
55.89 + protected:
55.90 +
55.91 + template <typename E>
55.92 + Node _dirSource(const E &e) const {
55.93 + return e.forward ? Parent::source(e) : Parent::target(e);
55.94 + }
55.95 +
55.96 + template <typename E>
55.97 + Node _dirTarget(const E &e) const {
55.98 + return e.forward ? Parent::target(e) : Parent::source(e);
55.99 + }
55.100 +
55.101 + public:
55.102 + /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
55.103 + /// or something???
55.104 + using Parent::source;
55.105 +
55.106 + /// Source of the given Edge.
55.107 + Node source(const Edge &e) const {
55.108 + return _dirSource(e);
55.109 + }
55.110 +
55.111 + /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
55.112 + /// or something???
55.113 + using Parent::target;
55.114 +
55.115 + /// Target of the given Edge.
55.116 + Node target(const Edge &e) const {
55.117 + return _dirTarget(e);
55.118 + }
55.119 +
55.120 + /// Returns whether the given directed edge is same orientation as the
55.121 + /// corresponding undirected edge.
55.122 + ///
55.123 + /// \todo reference to the corresponding point of the undirected graph
55.124 + /// concept. "What does the direction of an undirected edge mean?"
55.125 + bool forward(const Edge &e) const { return e.forward; }
55.126 +
55.127 + Node oppositeNode(const Node &n, const UndirEdge &e) const {
55.128 + if( n == Parent::source(e))
55.129 + return Parent::target(e);
55.130 + else if( n == Parent::target(e))
55.131 + return Parent::source(e);
55.132 + else
55.133 + return INVALID;
55.134 + }
55.135 +
55.136 + /// Directed edge from an undirected edge and a source node.
55.137 + ///
55.138 + /// Returns a (directed) Edge corresponding to the specified UndirEdge
55.139 + /// and source Node.
55.140 + ///
55.141 + ///\todo Do we need this?
55.142 + ///
55.143 + ///\todo Better name...
55.144 + Edge edgeWithSource(const UndirEdge &ue, const Node &s) const {
55.145 + return Edge(*this, ue, s);
55.146 + }
55.147 +
55.148 + using Parent::first;
55.149 + void first(Edge &e) const {
55.150 + Parent::first(e);
55.151 + e.forward=true;
55.152 + }
55.153 +
55.154 + using Parent::next;
55.155 + void next(Edge &e) const {
55.156 + if( e.forward ) {
55.157 + e.forward = false;
55.158 + }
55.159 + else {
55.160 + Parent::next(e);
55.161 + e.forward = true;
55.162 + }
55.163 + }
55.164 +
55.165 +
55.166 + protected:
55.167 +
55.168 + template <typename E>
55.169 + void _dirFirstOut(E &e, const Node &n) const {
55.170 + Parent::firstIn(e,n);
55.171 + if( UndirEdge(e) != INVALID ) {
55.172 + e.forward = false;
55.173 + }
55.174 + else {
55.175 + Parent::firstOut(e,n);
55.176 + e.forward = true;
55.177 + }
55.178 + }
55.179 + template <typename E>
55.180 + void _dirFirstIn(E &e, const Node &n) const {
55.181 + Parent::firstOut(e,n);
55.182 + if( UndirEdge(e) != INVALID ) {
55.183 + e.forward = false;
55.184 + }
55.185 + else {
55.186 + Parent::firstIn(e,n);
55.187 + e.forward = true;
55.188 + }
55.189 + }
55.190 +
55.191 + template <typename E>
55.192 + void _dirNextOut(E &e) const {
55.193 + if( ! e.forward ) {
55.194 + Node n = Parent::target(e);
55.195 + Parent::nextIn(e);
55.196 + if( UndirEdge(e) == INVALID ) {
55.197 + Parent::firstOut(e, n);
55.198 + e.forward = true;
55.199 + }
55.200 + }
55.201 + else {
55.202 + Parent::nextOut(e);
55.203 + }
55.204 + }
55.205 + template <typename E>
55.206 + void _dirNextIn(E &e) const {
55.207 + if( ! e.forward ) {
55.208 + Node n = Parent::source(e);
55.209 + Parent::nextOut(e);
55.210 + if( UndirEdge(e) == INVALID ) {
55.211 + Parent::firstIn(e, n);
55.212 + e.forward = true;
55.213 + }
55.214 + }
55.215 + else {
55.216 + Parent::nextIn(e);
55.217 + }
55.218 + }
55.219 +
55.220 + public:
55.221 +
55.222 + void firstOut(Edge &e, const Node &n) const {
55.223 + _dirFirstOut(e, n);
55.224 + }
55.225 + void firstIn(Edge &e, const Node &n) const {
55.226 + _dirFirstIn(e, n);
55.227 + }
55.228 +
55.229 + void nextOut(Edge &e) const {
55.230 + _dirNextOut(e);
55.231 + }
55.232 + void nextIn(Edge &e) const {
55.233 + _dirNextIn(e);
55.234 + }
55.235 +
55.236 + // Miscellaneous stuff:
55.237 +
55.238 + /// \todo these methods (id, maxEdgeId) should be moved into separate
55.239 + /// Extender
55.240 +
55.241 + // using Parent::id;
55.242 + // Using "using" is not a good idea, cause it could be that there is
55.243 + // no "id" in Parent...
55.244 +
55.245 + int id(const Node &n) const {
55.246 + return Parent::id(n);
55.247 + }
55.248 +
55.249 + int id(const UndirEdge &e) const {
55.250 + return Parent::id(e);
55.251 + }
55.252 +
55.253 + int id(const Edge &e) const {
55.254 + return 2 * Parent::id(e) + int(e.forward);
55.255 + }
55.256 +
55.257 +
55.258 + int maxId(Node) const {
55.259 + return Parent::maxId(Node());
55.260 + }
55.261 +
55.262 + int maxId(Edge) const {
55.263 + return 2 * Parent::maxId(typename Parent::Edge()) + 1;
55.264 + }
55.265 + int maxId(UndirEdge) const {
55.266 + return Parent::maxId(typename Parent::Edge());
55.267 + }
55.268 +
55.269 +
55.270 + int edgeNum() const {
55.271 + return 2 * Parent::edgeNum();
55.272 + }
55.273 + int undirEdgeNum() const {
55.274 + return Parent::edgeNum();
55.275 + }
55.276 +
55.277 + };
55.278 +
55.279 +}
55.280 +
55.281 +#endif // LEMON_UNDIR_GRAPH_EXTENDER_H
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/lemon/bits/vector_map.h Mon May 23 04:48:14 2005 +0000
56.3 @@ -0,0 +1,288 @@
56.4 +/* -*- C++ -*-
56.5 + * lemon/vector_map.h - Part of LEMON, a generic C++ optimization library
56.6 + *
56.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
56.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
56.9 + *
56.10 + * Permission to use, modify and distribute this software is granted
56.11 + * provided that this copyright notice appears in all copies. For
56.12 + * precise terms see the accompanying LICENSE file.
56.13 + *
56.14 + * This software is provided "AS IS" with no warranty of any kind,
56.15 + * express or implied, and with no claim as to its suitability for any
56.16 + * purpose.
56.17 + *
56.18 + */
56.19 +
56.20 +#ifndef LEMON_VECTOR_MAP_H
56.21 +#define LEMON_VECTOR_MAP_H
56.22 +
56.23 +#include <vector>
56.24 +#include <algorithm>
56.25 +
56.26 +#include <lemon/utility.h>
56.27 +#include <lemon/bits/map_iterator.h>
56.28 +#include <lemon/bits/alteration_notifier.h>
56.29 +
56.30 +///\ingroup graphmaps
56.31 +///\file
56.32 +///\brief Vector based graph maps.
56.33 +
56.34 +namespace lemon {
56.35 +
56.36 + /// \addtogroup graphmaps
56.37 + /// @{
56.38 +
56.39 + /// The VectorMap template class is graph map structure what
56.40 + /// automatically updates the map when a key is added to or erased from
56.41 + /// the map. This map factory uses the allocators to implement
56.42 + /// the container functionality. This map factory
56.43 + /// uses the std::vector to implement the container function.
56.44 + ///
56.45 + /// \param Registry The AlterationNotifier that will notify this map.
56.46 + /// \param IdMap The IdMap type of the graph items.
56.47 + /// \param Value The value type of the map.
56.48 + ///
56.49 + /// \author Balazs Dezso
56.50 +
56.51 +
56.52 + template <
56.53 + typename _Graph,
56.54 + typename _Item,
56.55 + typename _Value
56.56 + >
56.57 + class VectorMap : public AlterationNotifier<_Item>::ObserverBase {
56.58 + public:
56.59 +
56.60 + /// The graph type of the map.
56.61 + typedef _Graph Graph;
56.62 + /// The key type of the map.
56.63 + typedef _Item Key;
56.64 + /// The id map type of the map.
56.65 + typedef AlterationNotifier<_Item> Registry;
56.66 + /// The value type of the map.
56.67 + typedef _Value Value;
56.68 +
56.69 + /// The map type.
56.70 + typedef VectorMap Map;
56.71 + /// The base class of the map.
56.72 + typedef typename Registry::ObserverBase Parent;
56.73 +
56.74 + private:
56.75 +
56.76 + /// The container type of the map.
56.77 + typedef std::vector<Value> Container;
56.78 +
56.79 + public:
56.80 +
56.81 + /// The reference type of the map;
56.82 + typedef typename Container::reference Reference;
56.83 + /// The pointer type of the map;
56.84 + typedef typename Container::pointer Pointer;
56.85 +
56.86 + /// The const value type of the map.
56.87 + typedef const Value ConstValue;
56.88 + /// The const reference type of the map;
56.89 + typedef typename Container::const_reference ConstReference;
56.90 + /// The pointer type of the map;
56.91 + typedef typename Container::const_pointer ConstPointer;
56.92 +
56.93 + typedef True FullTypeTag;
56.94 +
56.95 + /// Constructor to attach the new map into the registry.
56.96 +
56.97 + /// It construates a map and attachs it into the registry.
56.98 + /// It adds all the items of the graph to the map.
56.99 +
56.100 + VectorMap(const Graph& _g) : graph(&_g) {
56.101 + attach(_g.getNotifier(_Item()));
56.102 + build();
56.103 + }
56.104 +
56.105 + /// Constructor uses given value to initialize the map.
56.106 +
56.107 + /// It construates a map uses a given value to initialize the map.
56.108 + /// It adds all the items of the graph to the map.
56.109 +
56.110 + VectorMap(const Graph& _g, const Value& _v) : graph(&_g) {
56.111 + attach(_g.getNotifier(_Item()));
56.112 + container.resize(graph->maxId(_Item()) + 1, _v);
56.113 + }
56.114 +
56.115 + VectorMap(const VectorMap& _copy)
56.116 + : Parent(), graph(_copy.getGraph()) {
56.117 + if (_copy.attached()) {
56.118 + attach(*_copy.getRegistry());
56.119 + container = _copy.container;
56.120 + }
56.121 + }
56.122 +
56.123 + using Parent::attach;
56.124 + using Parent::detach;
56.125 + using Parent::attached;
56.126 +
56.127 + /** Assign operator to copy a map of the same map type.
56.128 + */
56.129 + VectorMap& operator=(const VectorMap& copy) {
56.130 + if (© == this) return *this;
56.131 +
56.132 + if (graph != copy.graph) {
56.133 + if (attached()) {
56.134 + detach();
56.135 + }
56.136 + if (copy.attached()) {
56.137 + attach(*copy.getRegistry());
56.138 + }
56.139 + }
56.140 + container = copy.container;
56.141 +
56.142 + return *this;
56.143 + }
56.144 +
56.145 +
56.146 + virtual ~VectorMap() {
56.147 + if (attached()) {
56.148 + detach();
56.149 + }
56.150 + }
56.151 +
56.152 + const Graph* getGraph() const {
56.153 + return graph;
56.154 + }
56.155 +
56.156 + /// The subcript operator.
56.157 +
56.158 + /// The subscript operator. The map can be subscripted by the
56.159 + /// actual items of the graph.
56.160 +
56.161 + Reference operator[](const Key& key) {
56.162 + return container[graph->id(key)];
56.163 + }
56.164 +
56.165 + /// The const subcript operator.
56.166 +
56.167 + /// The const subscript operator. The map can be subscripted by the
56.168 + /// actual items of the graph.
56.169 +
56.170 + ConstReference operator[](const Key& key) const {
56.171 + return container[graph->id(key)];
56.172 + }
56.173 +
56.174 +
56.175 + /// The setter function of the map.
56.176 +
56.177 + /// It the same as operator[](key) = value expression.
56.178 + ///
56.179 +
56.180 + void set(const Key& key, const Value& value) {
56.181 + (*this)[key] = value;
56.182 + }
56.183 +
56.184 + /// Adds a new key to the map.
56.185 +
56.186 + /// It adds a new key to the map. It called by the observer registry
56.187 + /// and it overrides the add() member function of the observer base.
56.188 +
56.189 + void add(const Key& key) {
56.190 + int id = graph->id(key);
56.191 + if (id >= (int)container.size()) {
56.192 + container.resize(id + 1);
56.193 + }
56.194 + }
56.195 +
56.196 + /// Erases a key from the map.
56.197 +
56.198 + /// Erase a key from the map. It called by the observer registry
56.199 + /// and it overrides the erase() member function of the observer base.
56.200 + void erase(const Key&) {}
56.201 +
56.202 + /// Buildes the map.
56.203 +
56.204 + /// It buildes the map. It called by the observer registry
56.205 + /// and it overrides the build() member function of the observer base.
56.206 +
56.207 + void build() {
56.208 + container.resize(graph->maxId(_Item()) + 1);
56.209 + }
56.210 +
56.211 + /// Clear the map.
56.212 +
56.213 + /// It erase all items from the map. It called by the observer registry
56.214 + /// and it overrides the clear() member function of the observer base.
56.215 + void clear() {
56.216 + container.clear();
56.217 + }
56.218 +
56.219 + private:
56.220 +
56.221 + Container container;
56.222 + const Graph *graph;
56.223 +
56.224 + };
56.225 +
56.226 +
56.227 + template <typename _Base>
56.228 + class VectorMappableGraphExtender : public _Base {
56.229 + public:
56.230 +
56.231 + typedef VectorMappableGraphExtender<_Base> Graph;
56.232 + typedef _Base Parent;
56.233 +
56.234 + typedef typename Parent::Node Node;
56.235 + typedef typename Parent::NodeIt NodeIt;
56.236 + typedef typename Parent::NodeIdMap NodeIdMap;
56.237 + typedef typename Parent::NodeNotifier NodeObserverRegistry;
56.238 +
56.239 + typedef typename Parent::Edge Edge;
56.240 + typedef typename Parent::EdgeIt EdgeIt;
56.241 + typedef typename Parent::EdgeIdMap EdgeIdMap;
56.242 + typedef typename Parent::EdgeNotifier EdgeObserverRegistry;
56.243 +
56.244 +
56.245 + template <typename _Value>
56.246 + class NodeMap :
56.247 + public IterableMapExtender<VectorMap<Graph, Node, _Value> > {
56.248 + public:
56.249 + typedef VectorMappableGraphExtender<_Base> Graph;
56.250 +
56.251 + typedef typename Graph::Node Node;
56.252 +
56.253 + typedef IterableMapExtender<VectorMap<Graph, Node, _Value> > Parent;
56.254 +
56.255 + //typedef typename Parent::Graph Graph;
56.256 + typedef typename Parent::Value Value;
56.257 +
56.258 + NodeMap(const Graph& g)
56.259 + : Parent(g) {}
56.260 + NodeMap(const Graph& g, const Value& v)
56.261 + : Parent(g, v) {}
56.262 +
56.263 + };
56.264 +
56.265 + template <typename _Value>
56.266 + class EdgeMap
56.267 + : public IterableMapExtender<VectorMap<Graph, Edge, _Value> > {
56.268 + public:
56.269 + typedef VectorMappableGraphExtender<_Base> Graph;
56.270 +
56.271 + typedef typename Graph::Edge Edge;
56.272 +
56.273 + typedef IterableMapExtender<VectorMap<Graph, Edge, _Value> > Parent;
56.274 +
56.275 + //typedef typename Parent::Graph Graph;
56.276 + typedef typename Parent::Value Value;
56.277 +
56.278 + EdgeMap(const Graph& g)
56.279 + : Parent(g) {}
56.280 + EdgeMap(const Graph& g, const Value& v)
56.281 + : Parent(g, v) {}
56.282 +
56.283 + };
56.284 +
56.285 + };
56.286 +
56.287 + /// @}
56.288 +
56.289 +}
56.290 +
56.291 +#endif
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/lemon/concept/graph.h Mon May 23 04:48:14 2005 +0000
57.3 @@ -0,0 +1,578 @@
57.4 +/* -*- C++ -*-
57.5 + * lemon/concept/graph.h - Part of LEMON, a generic C++ optimization library
57.6 + *
57.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
57.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
57.9 + *
57.10 + * Permission to use, modify and distribute this software is granted
57.11 + * provided that this copyright notice appears in all copies. For
57.12 + * precise terms see the accompanying LICENSE file.
57.13 + *
57.14 + * This software is provided "AS IS" with no warranty of any kind,
57.15 + * express or implied, and with no claim as to its suitability for any
57.16 + * purpose.
57.17 + *
57.18 + */
57.19 +
57.20 +#ifndef LEMON_CONCEPT_GRAPH_H
57.21 +#define LEMON_CONCEPT_GRAPH_H
57.22 +
57.23 +///\ingroup graph_concepts
57.24 +///\file
57.25 +///\brief Declaration of Graph.
57.26 +
57.27 +#include <lemon/invalid.h>
57.28 +#include <lemon/concept/maps.h>
57.29 +#include <lemon/concept_check.h>
57.30 +#include <lemon/concept/graph_component.h>
57.31 +
57.32 +namespace lemon {
57.33 + namespace concept {
57.34 +
57.35 +
57.36 + /// \addtogroup graph_concepts
57.37 + /// @{
57.38 +
57.39 + /**************** The full-featured graph concepts ****************/
57.40 +
57.41 +
57.42 + /// \brief Modular static graph class.
57.43 + ///
57.44 + /// It should be the same as the \c StaticGraph class.
57.45 + class _StaticGraph
57.46 + : virtual public BaseGraphComponent,
57.47 + public IterableGraphComponent, public MappableGraphComponent {
57.48 + public:
57.49 + typedef BaseGraphComponent::Node Node;
57.50 + typedef BaseGraphComponent::Edge Edge;
57.51 +
57.52 + template <typename _Graph>
57.53 + struct Constraints {
57.54 + void constraints() {
57.55 + checkConcept<IterableGraphComponent, _Graph>();
57.56 + checkConcept<MappableGraphComponent, _Graph>();
57.57 + }
57.58 + };
57.59 + };
57.60 +
57.61 + /// \brief Modular extendable graph class.
57.62 + ///
57.63 + /// It should be the same as the \c ExtendableGraph class.
57.64 + class _ExtendableGraph
57.65 + : virtual public BaseGraphComponent, public _StaticGraph,
57.66 + public ExtendableGraphComponent, public ClearableGraphComponent {
57.67 + public:
57.68 + typedef BaseGraphComponent::Node Node;
57.69 + typedef BaseGraphComponent::Edge Edge;
57.70 +
57.71 + template <typename _Graph>
57.72 + struct Constraints {
57.73 + void constraints() {
57.74 + checkConcept<_StaticGraph, _Graph >();
57.75 + checkConcept<ExtendableGraphComponent, _Graph >();
57.76 + checkConcept<ClearableGraphComponent, _Graph >();
57.77 + }
57.78 + };
57.79 + };
57.80 +
57.81 + /// \brief Modular erasable graph class.
57.82 + ///
57.83 + /// It should be the same as the \c ErasableGraph class.
57.84 + class _ErasableGraph
57.85 + : virtual public BaseGraphComponent, public _ExtendableGraph,
57.86 + public ErasableGraphComponent {
57.87 + public:
57.88 + typedef BaseGraphComponent::Node Node;
57.89 + typedef BaseGraphComponent::Edge Edge;
57.90 +
57.91 + template <typename _Graph>
57.92 + struct Constraints {
57.93 + void constraints() {
57.94 + checkConcept<_ExtendableGraph, _Graph >();
57.95 + checkConcept<ErasableGraphComponent, _Graph >();
57.96 + }
57.97 + };
57.98 + };
57.99 +
57.100 + /// An empty static graph class.
57.101 +
57.102 + /// This class provides all the common features of a graph structure,
57.103 + /// however completely without implementations and real data structures
57.104 + /// behind the interface.
57.105 + /// All graph algorithms should compile with this class, but it will not
57.106 + /// run properly, of course.
57.107 + ///
57.108 + /// It can be used for checking the interface compatibility,
57.109 + /// or it can serve as a skeleton of a new graph structure.
57.110 + ///
57.111 + /// Also, you will find here the full documentation of a certain graph
57.112 + /// feature, the documentation of a real graph imlementation
57.113 + /// like @ref ListGraph or
57.114 + /// @ref SmartGraph will just refer to this structure.
57.115 + ///
57.116 + /// \todo A pages describing the concept of concept description would
57.117 + /// be nice.
57.118 + class StaticGraph
57.119 + {
57.120 + public:
57.121 + /// Defalult constructor.
57.122 +
57.123 + /// Defalult constructor.
57.124 + ///
57.125 + StaticGraph() { }
57.126 + ///Copy consructor.
57.127 +
57.128 +// ///\todo It is not clear, what we expect from a copy constructor.
57.129 +// ///E.g. How to assign the nodes/edges to each other? What about maps?
57.130 +// StaticGraph(const StaticGraph& g) { }
57.131 +
57.132 + /// The base type of node iterators,
57.133 + /// or in other words, the trivial node iterator.
57.134 +
57.135 + /// This is the base type of each node iterator,
57.136 + /// thus each kind of node iterator converts to this.
57.137 + /// More precisely each kind of node iterator should be inherited
57.138 + /// from the trivial node iterator.
57.139 + class Node {
57.140 + public:
57.141 + /// Default constructor
57.142 +
57.143 + /// @warning The default constructor sets the iterator
57.144 + /// to an undefined value.
57.145 + Node() { }
57.146 + /// Copy constructor.
57.147 +
57.148 + /// Copy constructor.
57.149 + ///
57.150 + Node(const Node&) { }
57.151 +
57.152 + /// Invalid constructor \& conversion.
57.153 +
57.154 + /// This constructor initializes the iterator to be invalid.
57.155 + /// \sa Invalid for more details.
57.156 + Node(Invalid) { }
57.157 + /// Equality operator
57.158 +
57.159 + /// Two iterators are equal if and only if they point to the
57.160 + /// same object or both are invalid.
57.161 + bool operator==(Node) const { return true; }
57.162 +
57.163 + /// Inequality operator
57.164 +
57.165 + /// \sa operator==(Node n)
57.166 + ///
57.167 + bool operator!=(Node) const { return true; }
57.168 +
57.169 + };
57.170 +
57.171 + /// This iterator goes through each node.
57.172 +
57.173 + /// This iterator goes through each node.
57.174 + /// Its usage is quite simple, for example you can count the number
57.175 + /// of nodes in graph \c g of type \c Graph like this:
57.176 + /// \code
57.177 + /// int count=0;
57.178 + /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
57.179 + /// \endcode
57.180 + class NodeIt : public Node {
57.181 + public:
57.182 + /// Default constructor
57.183 +
57.184 + /// @warning The default constructor sets the iterator
57.185 + /// to an undefined value.
57.186 + NodeIt() { }
57.187 + /// Copy constructor.
57.188 +
57.189 + /// Copy constructor.
57.190 + ///
57.191 + NodeIt(const NodeIt& n) : Node(n) { }
57.192 + /// Invalid constructor \& conversion.
57.193 +
57.194 + /// Initialize the iterator to be invalid.
57.195 + /// \sa Invalid for more details.
57.196 + NodeIt(Invalid) { }
57.197 + /// Sets the iterator to the first node.
57.198 +
57.199 + /// Sets the iterator to the first node of \c g.
57.200 + ///
57.201 + NodeIt(const StaticGraph&) { }
57.202 + /// Node -> NodeIt conversion.
57.203 +
57.204 + /// Sets the iterator to the node of \c g pointed by the trivial
57.205 + /// iterator n.
57.206 + /// This feature necessitates that each time we
57.207 + /// iterate the edge-set, the iteration order is the same.
57.208 + NodeIt(const StaticGraph& g, const Node& n) { }
57.209 + /// Next node.
57.210 +
57.211 + /// Assign the iterator to the next node.
57.212 + ///
57.213 + NodeIt& operator++() { return *this; }
57.214 + };
57.215 +
57.216 +
57.217 + /// The base type of the edge iterators.
57.218 +
57.219 + /// The base type of the edge iterators.
57.220 + ///
57.221 + class Edge {
57.222 + public:
57.223 + /// Default constructor
57.224 +
57.225 + /// @warning The default constructor sets the iterator
57.226 + /// to an undefined value.
57.227 + Edge() { }
57.228 + /// Copy constructor.
57.229 +
57.230 + /// Copy constructor.
57.231 + ///
57.232 + Edge(const Edge&) { }
57.233 + /// Initialize the iterator to be invalid.
57.234 +
57.235 + /// Initialize the iterator to be invalid.
57.236 + ///
57.237 + Edge(Invalid) { }
57.238 + /// Equality operator
57.239 +
57.240 + /// Two iterators are equal if and only if they point to the
57.241 + /// same object or both are invalid.
57.242 + bool operator==(Edge) const { return true; }
57.243 + /// Inequality operator
57.244 +
57.245 + /// \sa operator==(Node n)
57.246 + ///
57.247 + bool operator!=(Edge) const { return true; }
57.248 + };
57.249 +
57.250 + /// This iterator goes trough the outgoing edges of a node.
57.251 +
57.252 + /// This iterator goes trough the \e outgoing edges of a certain node
57.253 + /// of a graph.
57.254 + /// Its usage is quite simple, for example you can count the number
57.255 + /// of outgoing edges of a node \c n
57.256 + /// in graph \c g of type \c Graph as follows.
57.257 + /// \code
57.258 + /// int count=0;
57.259 + /// for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) ++count;
57.260 + /// \endcode
57.261 +
57.262 + class OutEdgeIt : public Edge {
57.263 + public:
57.264 + /// Default constructor
57.265 +
57.266 + /// @warning The default constructor sets the iterator
57.267 + /// to an undefined value.
57.268 + OutEdgeIt() { }
57.269 + /// Copy constructor.
57.270 +
57.271 + /// Copy constructor.
57.272 + ///
57.273 + OutEdgeIt(const OutEdgeIt& e) : Edge(e) { }
57.274 + /// Initialize the iterator to be invalid.
57.275 +
57.276 + /// Initialize the iterator to be invalid.
57.277 + ///
57.278 + OutEdgeIt(Invalid) { }
57.279 + /// This constructor sets the iterator to the first outgoing edge.
57.280 +
57.281 + /// This constructor sets the iterator to the first outgoing edge of
57.282 + /// the node.
57.283 + ///@param n the node
57.284 + ///@param g the graph
57.285 + OutEdgeIt(const StaticGraph&, const Node&) { }
57.286 + /// Edge -> OutEdgeIt conversion
57.287 +
57.288 + /// Sets the iterator to the value of the trivial iterator \c e.
57.289 + /// This feature necessitates that each time we
57.290 + /// iterate the edge-set, the iteration order is the same.
57.291 + OutEdgeIt(const StaticGraph& g, const Edge& e) { }
57.292 + ///Next outgoing edge
57.293 +
57.294 + /// Assign the iterator to the next
57.295 + /// outgoing edge of the corresponding node.
57.296 + OutEdgeIt& operator++() { return *this; }
57.297 + };
57.298 +
57.299 + /// This iterator goes trough the incoming edges of a node.
57.300 +
57.301 + /// This iterator goes trough the \e incoming edges of a certain node
57.302 + /// of a graph.
57.303 + /// Its usage is quite simple, for example you can count the number
57.304 + /// of outgoing edges of a node \c n
57.305 + /// in graph \c g of type \c Graph as follows.
57.306 + /// \code
57.307 + /// int count=0;
57.308 + /// for(Graph::InEdgeIt e(g, n); e!=INVALID; ++e) ++count;
57.309 + /// \endcode
57.310 +
57.311 + class InEdgeIt : public Edge {
57.312 + public:
57.313 + /// Default constructor
57.314 +
57.315 + /// @warning The default constructor sets the iterator
57.316 + /// to an undefined value.
57.317 + InEdgeIt() { }
57.318 + /// Copy constructor.
57.319 +
57.320 + /// Copy constructor.
57.321 + ///
57.322 + InEdgeIt(const InEdgeIt& e) : Edge(e) { }
57.323 + /// Initialize the iterator to be invalid.
57.324 +
57.325 + /// Initialize the iterator to be invalid.
57.326 + ///
57.327 + InEdgeIt(Invalid) { }
57.328 + /// This constructor sets the iterator to first incoming edge.
57.329 +
57.330 + /// This constructor set the iterator to the first incoming edge of
57.331 + /// the node.
57.332 + ///@param n the node
57.333 + ///@param g the graph
57.334 + InEdgeIt(const StaticGraph&, const Node&) { }
57.335 + /// Edge -> InEdgeIt conversion
57.336 +
57.337 + /// Sets the iterator to the value of the trivial iterator \c e.
57.338 + /// This feature necessitates that each time we
57.339 + /// iterate the edge-set, the iteration order is the same.
57.340 + InEdgeIt(const StaticGraph&, const Edge&) { }
57.341 + /// Next incoming edge
57.342 +
57.343 + /// Assign the iterator to the next inedge of the corresponding node.
57.344 + ///
57.345 + InEdgeIt& operator++() { return *this; }
57.346 + };
57.347 + /// This iterator goes through each edge.
57.348 +
57.349 + /// This iterator goes through each edge of a graph.
57.350 + /// Its usage is quite simple, for example you can count the number
57.351 + /// of edges in a graph \c g of type \c Graph as follows:
57.352 + /// \code
57.353 + /// int count=0;
57.354 + /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
57.355 + /// \endcode
57.356 + class EdgeIt : public Edge {
57.357 + public:
57.358 + /// Default constructor
57.359 +
57.360 + /// @warning The default constructor sets the iterator
57.361 + /// to an undefined value.
57.362 + EdgeIt() { }
57.363 + /// Copy constructor.
57.364 +
57.365 + /// Copy constructor.
57.366 + ///
57.367 + EdgeIt(const EdgeIt& e) : Edge(e) { }
57.368 + /// Initialize the iterator to be invalid.
57.369 +
57.370 + /// Initialize the iterator to be invalid.
57.371 + ///
57.372 + EdgeIt(Invalid) { }
57.373 + /// This constructor sets the iterator to the first edge.
57.374 +
57.375 + /// This constructor sets the iterator to the first edge of \c g.
57.376 + ///@param g the graph
57.377 + EdgeIt(const StaticGraph&) { }
57.378 + /// Edge -> EdgeIt conversion
57.379 +
57.380 + /// Sets the iterator to the value of the trivial iterator \c e.
57.381 + /// This feature necessitates that each time we
57.382 + /// iterate the edge-set, the iteration order is the same.
57.383 + EdgeIt(const StaticGraph&, const Edge&) { }
57.384 + ///Next edge
57.385 +
57.386 + /// Assign the iterator to the next edge.
57.387 + EdgeIt& operator++() { return *this; }
57.388 + };
57.389 + ///Gives back the target node of an edge.
57.390 +
57.391 + ///Gives back the target node of an edge.
57.392 + ///
57.393 + Node target(Edge) const { return INVALID; }
57.394 + ///Gives back the source node of an edge.
57.395 +
57.396 + ///Gives back the source node of an edge.
57.397 + ///
57.398 + Node source(Edge) const { return INVALID; }
57.399 + /// Read write map of the nodes to type \c T.
57.400 +
57.401 + /// \ingroup concept
57.402 + /// ReadWrite map of the nodes to type \c T.
57.403 + /// \sa Reference
57.404 + /// \warning Making maps that can handle bool type (NodeMap<bool>)
57.405 + /// needs some extra attention!
57.406 + template<class T>
57.407 + class NodeMap : public ReadWriteMap< Node, T >
57.408 + {
57.409 + public:
57.410 +
57.411 + ///\e
57.412 + NodeMap(const StaticGraph&) { }
57.413 + ///\e
57.414 + NodeMap(const StaticGraph&, T) { }
57.415 +
57.416 + ///Copy constructor
57.417 + NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
57.418 + ///Assignment operator
57.419 + NodeMap& operator=(const NodeMap&) { return *this; }
57.420 + // \todo fix this concept
57.421 + };
57.422 +
57.423 + /// Read write map of the edges to type \c T.
57.424 +
57.425 + /// \ingroup concept
57.426 + ///Reference map of the edges to type \c T.
57.427 + /// \sa Reference
57.428 + /// \warning Making maps that can handle bool type (EdgeMap<bool>)
57.429 + /// needs some extra attention!
57.430 + template<class T>
57.431 + class EdgeMap : public ReadWriteMap<Edge,T>
57.432 + {
57.433 + public:
57.434 +
57.435 + ///\e
57.436 + EdgeMap(const StaticGraph&) { }
57.437 + ///\e
57.438 + EdgeMap(const StaticGraph&, T) { }
57.439 + ///Copy constructor
57.440 + EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) { }
57.441 + ///Assignment operator
57.442 + EdgeMap& operator=(const EdgeMap&) { return *this; }
57.443 + // \todo fix this concept
57.444 + };
57.445 +
57.446 + template <typename _Graph>
57.447 + struct Constraints : public _StaticGraph::Constraints<_Graph> {};
57.448 +
57.449 + };
57.450 +
57.451 + /// An empty non-static graph class.
57.452 +
57.453 + /// This class provides everything that \ref StaticGraph does.
57.454 + /// Additionally it enables building graphs from scratch.
57.455 + class ExtendableGraph : public StaticGraph
57.456 + {
57.457 + public:
57.458 + /// Defalult constructor.
57.459 +
57.460 + /// Defalult constructor.
57.461 + ///
57.462 + ExtendableGraph() { }
57.463 + ///Add a new node to the graph.
57.464 +
57.465 + /// \return the new node.
57.466 + ///
57.467 + Node addNode() { return INVALID; }
57.468 + ///Add a new edge to the graph.
57.469 +
57.470 + ///Add a new edge to the graph with source node \c s
57.471 + ///and target node \c t.
57.472 + ///\return the new edge.
57.473 + Edge addEdge(Node, Node) { return INVALID; }
57.474 +
57.475 + /// Resets the graph.
57.476 +
57.477 + /// This function deletes all edges and nodes of the graph.
57.478 + /// It also frees the memory allocated to store them.
57.479 + /// \todo It might belong to \ref ErasableGraph.
57.480 + void clear() { }
57.481 +
57.482 + template <typename _Graph>
57.483 + struct Constraints : public _ExtendableGraph::Constraints<_Graph> {};
57.484 +
57.485 + };
57.486 +
57.487 + /// An empty erasable graph class.
57.488 +
57.489 + /// This class is an extension of \ref ExtendableGraph. It makes it
57.490 + /// possible to erase edges or nodes.
57.491 + class ErasableGraph : public ExtendableGraph
57.492 + {
57.493 + public:
57.494 + /// Defalult constructor.
57.495 +
57.496 + /// Defalult constructor.
57.497 + ///
57.498 + ErasableGraph() { }
57.499 + /// Deletes a node.
57.500 +
57.501 + /// Deletes node \c n node.
57.502 + ///
57.503 + void erase(Node) { }
57.504 + /// Deletes an edge.
57.505 +
57.506 + /// Deletes edge \c e edge.
57.507 + ///
57.508 + void erase(Edge) { }
57.509 +
57.510 + template <typename _Graph>
57.511 + struct Constraints : public _ErasableGraph::Constraints<_Graph> {};
57.512 +
57.513 + };
57.514 +
57.515 +
57.516 + /************* New GraphBase stuff **************/
57.517 +
57.518 +
57.519 +// /// A minimal GraphBase concept
57.520 +
57.521 +// /// This class describes a minimal concept which can be extended to a
57.522 +// /// full-featured graph with \ref GraphFactory.
57.523 +// class GraphBase {
57.524 +// public:
57.525 +
57.526 +// GraphBase() {}
57.527 +
57.528 +// /// \bug Should we demand that Node and Edge be subclasses of the
57.529 +// /// Graph class???
57.530 +
57.531 +// typedef GraphItem<'n'> Node;
57.532 +// typedef GraphItem<'e'> Edge;
57.533 +
57.534 +// // class Node : public BaseGraphItem<'n'> {};
57.535 +// // class Edge : public BaseGraphItem<'e'> {};
57.536 +
57.537 +// // Graph operation
57.538 +// void firstNode(Node &n) const { }
57.539 +// void firstEdge(Edge &e) const { }
57.540 +
57.541 +// void firstOutEdge(Edge &e, Node) const { }
57.542 +// void firstInEdge(Edge &e, Node) const { }
57.543 +
57.544 +// void nextNode(Node &n) const { }
57.545 +// void nextEdge(Edge &e) const { }
57.546 +
57.547 +
57.548 +// // Question: isn't it reasonable if this methods have a Node
57.549 +// // parameter? Like this:
57.550 +// // Edge& nextOut(Edge &e, Node) const { return e; }
57.551 +// void nextOutEdge(Edge &e) const { }
57.552 +// void nextInEdge(Edge &e) const { }
57.553 +
57.554 +// Node target(Edge) const { return Node(); }
57.555 +// Node source(Edge) const { return Node(); }
57.556 +
57.557 +
57.558 +// // Do we need id, nodeNum, edgeNum and co. in this basic graphbase
57.559 +// // concept?
57.560 +
57.561 +
57.562 +// // Maps.
57.563 +// //
57.564 +// // We need a special slimer concept which does not provide maps (it
57.565 +// // wouldn't be strictly slimer, cause for map-factory id() & friends
57.566 +// // a required...)
57.567 +
57.568 +// template<typename T>
57.569 +// class NodeMap : public GraphMap<GraphBase, Node, T> {};
57.570 +
57.571 +// template<typename T>
57.572 +// class EdgeMap : public GraphMap<GraphBase, Node, T> {};
57.573 +// };
57.574 +
57.575 + // @}
57.576 + } //namespace concept
57.577 +} //namespace lemon
57.578 +
57.579 +
57.580 +
57.581 +#endif // LEMON_CONCEPT_GRAPH_H
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/lemon/concept/graph_component.h Mon May 23 04:48:14 2005 +0000
58.3 @@ -0,0 +1,982 @@
58.4 +/* -*- C++ -*-
58.5 + * lemon/concept/graph_component.h - Part of LEMON, a generic C++ optimization library
58.6 + *
58.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
58.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
58.9 + *
58.10 + * Permission to use, modify and distribute this software is granted
58.11 + * provided that this copyright notice appears in all copies. For
58.12 + * precise terms see the accompanying LICENSE file.
58.13 + *
58.14 + * This software is provided "AS IS" with no warranty of any kind,
58.15 + * express or implied, and with no claim as to its suitability for any
58.16 + * purpose.
58.17 + *
58.18 + */
58.19 +
58.20 +///\ingroup graph_concepts
58.21 +///\file
58.22 +///\brief The graph components.
58.23 +
58.24 +
58.25 +#ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H
58.26 +#define LEMON_CONCEPT_GRAPH_COMPONENT_H
58.27 +
58.28 +#include <lemon/invalid.h>
58.29 +#include <lemon/concept/maps.h>
58.30 +
58.31 +#include <lemon/bits/alteration_notifier.h>
58.32 +
58.33 +namespace lemon {
58.34 + namespace concept {
58.35 +
58.36 + /// \addtogroup graph_concepts
58.37 + /// @{
58.38 +
58.39 + /**************** Graph iterator concepts ****************/
58.40 +
58.41 + /// Skeleton class for graph Node and Edge types
58.42 +
58.43 + /// This class describes the interface of Node and Edge (and UndirEdge
58.44 + /// in undirected graphs) subtypes of graph types.
58.45 + ///
58.46 + /// \note This class is a template class so that we can use it to
58.47 + /// create graph skeleton classes. The reason for this is than Node
58.48 + /// and Edge types should \em not derive from the same base class.
58.49 + /// For Node you should instantiate it with character 'n' and for Edge
58.50 + /// with 'e'.
58.51 +
58.52 +#ifndef DOXYGEN
58.53 + template <char _selector = '0'>
58.54 +#endif
58.55 + class GraphItem {
58.56 + public:
58.57 + /// Default constructor.
58.58 +
58.59 + /// \warning The default constructor is not required to set
58.60 + /// the item to some well-defined value. So you should consider it
58.61 + /// as uninitialized.
58.62 + GraphItem() {}
58.63 + /// Copy constructor.
58.64 +
58.65 + /// Copy constructor.
58.66 + ///
58.67 + GraphItem(GraphItem const&) {}
58.68 + /// Invalid constructor \& conversion.
58.69 +
58.70 + /// This constructor initializes the item to be invalid.
58.71 + /// \sa Invalid for more details.
58.72 + GraphItem(Invalid) {}
58.73 + /// Assign operator for nodes.
58.74 +
58.75 + /// The nodes are assignable.
58.76 + ///
58.77 + GraphItem& operator=(GraphItem const&) { return *this; }
58.78 + /// Equality operator.
58.79 +
58.80 + /// Two iterators are equal if and only if they represents the
58.81 + /// same node in the graph or both are invalid.
58.82 + bool operator==(GraphItem) const { return false; }
58.83 + /// Inequality operator.
58.84 +
58.85 + /// \sa operator==(const Node& n)
58.86 + ///
58.87 + bool operator!=(GraphItem) const { return false; }
58.88 +
58.89 + /// Artificial ordering operator.
58.90 +
58.91 + /// To allow the use of graph descriptors as key type in std::map or
58.92 + /// similar associative container we require this.
58.93 + ///
58.94 + /// \note This operator only have to define some strict ordering of
58.95 + /// the items; this order has nothing to do with the iteration
58.96 + /// ordering of the items.
58.97 + ///
58.98 + /// \bug This is a technical requirement. Do we really need this?
58.99 + bool operator<(GraphItem) const { return false; }
58.100 +
58.101 + template<typename _GraphItem>
58.102 + struct Constraints {
58.103 + void constraints() {
58.104 + _GraphItem i1;
58.105 + _GraphItem i2 = i1;
58.106 + _GraphItem i3 = INVALID;
58.107 +
58.108 + i1 = i2 = i3;
58.109 +
58.110 + bool b;
58.111 + // b = (ia == ib) && (ia != ib) && (ia < ib);
58.112 + b = (ia == ib) && (ia != ib);
58.113 + b = (ia == INVALID) && (ib != INVALID);
58.114 + // b = (ia < ib);
58.115 + }
58.116 +
58.117 + const _GraphItem &ia;
58.118 + const _GraphItem &ib;
58.119 + };
58.120 + };
58.121 +
58.122 + /// A type describing the concept of graph node
58.123 +
58.124 + /// This is an instantiation of \ref GraphItem which can be used as a
58.125 + /// Node subtype in graph skeleton definitions
58.126 + typedef GraphItem<'n'> GraphNode;
58.127 +
58.128 + /// A type describing the concept of graph edge
58.129 +
58.130 + /// This is an instantiation of \ref GraphItem which can be used as a
58.131 + /// Edge subtype in graph skeleton definitions
58.132 + typedef GraphItem<'e'> GraphEdge;
58.133 +
58.134 +
58.135 + /**************** Basic features of graphs ****************/
58.136 +
58.137 + /// An empty base graph class.
58.138 +
58.139 + /// This class provides the minimal set of features needed for a graph
58.140 + /// structure. All graph concepts have to be conform to this base
58.141 + /// graph.
58.142 + ///
58.143 + /// \bug This is not true. The minimal graph concept is the
58.144 + /// BaseIterableGraphComponent.
58.145 +
58.146 + class BaseGraphComponent {
58.147 + public:
58.148 +
58.149 + typedef BaseGraphComponent Graph;
58.150 +
58.151 + /// Node class of the graph.
58.152 +
58.153 + /// This class represents the Nodes of the graph.
58.154 + ///
58.155 + typedef GraphItem<'n'> Node;
58.156 +
58.157 + /// Edge class of the graph.
58.158 +
58.159 + /// This class represents the Edges of the graph.
58.160 + ///
58.161 + typedef GraphItem<'e'> Edge;
58.162 +
58.163 + ///Gives back the target node of an edge.
58.164 +
58.165 + ///Gives back the target node of an edge.
58.166 + ///
58.167 + Node target(const Edge&) const { return INVALID;}
58.168 +
58.169 + ///Gives back the source node of an edge.
58.170 +
58.171 + ///Gives back the source node of an edge.
58.172 + ///
58.173 + Node source(const Edge&) const { return INVALID;}
58.174 +
58.175 +
58.176 + template <typename _Graph>
58.177 + struct Constraints {
58.178 + typedef typename _Graph::Node Node;
58.179 + typedef typename _Graph::Edge Edge;
58.180 +
58.181 + void constraints() {
58.182 + checkConcept<GraphItem<'n'>, Node>();
58.183 + checkConcept<GraphItem<'e'>, Edge>();
58.184 + {
58.185 + Node n;
58.186 + Edge e;
58.187 + n = graph.source(e);
58.188 + n = graph.target(e);
58.189 + }
58.190 + }
58.191 +
58.192 + const _Graph& graph;
58.193 + };
58.194 + };
58.195 +
58.196 + /// An empty iterable base graph class.
58.197 +
58.198 + /// This class provides beside the core graph features
58.199 + /// core iterable interface for the graph structure.
58.200 + /// Most of the base graphs should be conform to this concept.
58.201 +
58.202 + class BaseIterableGraphComponent : virtual public BaseGraphComponent {
58.203 + public:
58.204 +
58.205 + typedef BaseGraphComponent::Node Node;
58.206 + typedef BaseGraphComponent::Edge Edge;
58.207 +
58.208 + /// Gives back the first Node in the iterating order.
58.209 +
58.210 + /// Gives back the first Node in the iterating order.
58.211 + ///
58.212 + void first(Node&) const {}
58.213 +
58.214 + /// Gives back the next Node in the iterating order.
58.215 +
58.216 + /// Gives back the next Node in the iterating order.
58.217 + ///
58.218 + void next(Node&) const {}
58.219 +
58.220 + /// Gives back the first Edge in the iterating order.
58.221 +
58.222 + /// Gives back the first Edge in the iterating order.
58.223 + ///
58.224 + void first(Edge&) const {}
58.225 + /// Gives back the next Edge in the iterating order.
58.226 +
58.227 + /// Gives back the next Edge in the iterating order.
58.228 + ///
58.229 + void next(Edge&) const {}
58.230 +
58.231 +
58.232 + /// Gives back the first of the Edges point to the given Node.
58.233 +
58.234 + /// Gives back the first of the Edges point to the given Node.
58.235 + ///
58.236 + void firstIn(Edge&, const Node&) const {}
58.237 +
58.238 + /// Gives back the next of the Edges points to the given Node.
58.239 +
58.240 +
58.241 + /// Gives back the next of the Edges points to the given Node.
58.242 + ///
58.243 + void nextIn(Edge&) const {}
58.244 +
58.245 + /// Gives back the first of the Edges start from the given Node.
58.246 +
58.247 + /// Gives back the first of the Edges start from the given Node.
58.248 + ///
58.249 + void firstOut(Edge&, const Node&) const {}
58.250 +
58.251 + /// Gives back the next of the Edges start from the given Node.
58.252 +
58.253 + /// Gives back the next of the Edges start from the given Node.
58.254 + ///
58.255 + void nextOut(Edge&) const {}
58.256 +
58.257 +
58.258 + template <typename _Graph>
58.259 + struct Constraints {
58.260 +
58.261 + void constraints() {
58.262 + checkConcept< BaseGraphComponent, _Graph >();
58.263 + typename _Graph::Node node;
58.264 + typename _Graph::Edge edge;
58.265 + {
58.266 + graph.first(node);
58.267 + graph.next(node);
58.268 + }
58.269 + {
58.270 + graph.first(edge);
58.271 + graph.next(edge);
58.272 + }
58.273 + {
58.274 + graph.firstIn(edge, node);
58.275 + graph.nextIn(edge);
58.276 + }
58.277 + {
58.278 + graph.firstOut(edge, node);
58.279 + graph.nextOut(edge);
58.280 + }
58.281 + }
58.282 +
58.283 + const _Graph& graph;
58.284 + };
58.285 + };
58.286 +
58.287 + /// An empty idable base graph class.
58.288 +
58.289 + /// This class provides beside the core graph features
58.290 + /// core id functions for the graph structure.
58.291 + /// The most of the base graphs should be conform to this concept.
58.292 + /// The id's are unique and immutable.
58.293 + class IDableGraphComponent : virtual public BaseGraphComponent {
58.294 + public:
58.295 +
58.296 + typedef BaseGraphComponent::Node Node;
58.297 + typedef BaseGraphComponent::Edge Edge;
58.298 +
58.299 + /// Gives back an unique integer id for the Node.
58.300 +
58.301 + /// Gives back an unique integer id for the Node.
58.302 + ///
58.303 + int id(const Node&) const { return -1;}
58.304 +
58.305 + /// \brief Gives back the node by the unique id.
58.306 + ///
58.307 + /// Gives back the node by the unique id.
58.308 + /// If the graph does not contain node with the given id
58.309 + /// then the result of the function is undetermined.
58.310 + Node fromId(int , Node) const { return INVALID;}
58.311 +
58.312 + /// \brief Gives back an unique integer id for the Edge.
58.313 + ///
58.314 + /// Gives back an unique integer id for the Edge.
58.315 + ///
58.316 + int id(const Edge&) const { return -1;}
58.317 +
58.318 + /// \brief Gives back the edge by the unique id.
58.319 + ///
58.320 + /// Gives back the edge by the unique id.
58.321 + /// If the graph does not contain edge with the given id
58.322 + /// then the result of the function is undetermined.
58.323 + Edge fromId(int, Edge) const { return INVALID;}
58.324 +
58.325 + template <typename _Graph>
58.326 + struct Constraints {
58.327 +
58.328 + void constraints() {
58.329 + checkConcept< BaseGraphComponent, _Graph >();
58.330 + typename _Graph::Node node;
58.331 + int nid = graph.id(node);
58.332 + nid = graph.id(node);
58.333 + node = graph.fromId(nid, Node());
58.334 + typename _Graph::Edge edge;
58.335 + int eid = graph.id(edge);
58.336 + eid = graph.id(edge);
58.337 + edge = graph.fromId(eid, Edge());
58.338 + }
58.339 +
58.340 + const _Graph& graph;
58.341 + };
58.342 + };
58.343 +
58.344 +
58.345 + /// An empty max-idable base graph class.
58.346 +
58.347 + /// This class provides beside the core graph features
58.348 + /// core max id functions for the graph structure.
58.349 + /// The most of the base graphs should be conform to this concept.
58.350 + /// The id's are unique and immutable.
58.351 + class MaxIDableGraphComponent : virtual public BaseGraphComponent {
58.352 + public:
58.353 +
58.354 + /// Gives back an integer greater or equal to the maximum Node id.
58.355 +
58.356 + /// Gives back an integer greater or equal to the maximum Node id.
58.357 + ///
58.358 + int maxId(Node = INVALID) const { return -1;}
58.359 +
58.360 + /// Gives back an integer greater or equal to the maximum Edge id.
58.361 +
58.362 + /// Gives back an integer greater or equal to the maximum Edge id.
58.363 + ///
58.364 + int maxId(Edge = INVALID) const { return -1;}
58.365 +
58.366 + template <typename _Graph>
58.367 + struct Constraints {
58.368 +
58.369 + void constraints() {
58.370 + checkConcept<BaseGraphComponent, _Graph>();
58.371 + int nid = graph.maxId(typename _Graph::Node());
58.372 + ignore_unused_variable_warning(nid);
58.373 + int eid = graph.maxId(typename _Graph::Edge());
58.374 + ignore_unused_variable_warning(eid);
58.375 + }
58.376 +
58.377 + const _Graph& graph;
58.378 + };
58.379 + };
58.380 +
58.381 + /// An empty extendable base graph class.
58.382 +
58.383 + /// This class provides beside the core graph features
58.384 + /// core graph extend interface for the graph structure.
58.385 + /// The most of the base graphs should be conform to this concept.
58.386 + class BaseExtendableGraphComponent : virtual public BaseGraphComponent {
58.387 + public:
58.388 +
58.389 + typedef BaseGraphComponent::Node Node;
58.390 + typedef BaseGraphComponent::Edge Edge;
58.391 +
58.392 + /// Adds a new Node to the graph.
58.393 +
58.394 + /// Adds a new Node to the graph.
58.395 + ///
58.396 + Node addNode() {
58.397 + return INVALID;
58.398 + }
58.399 +
58.400 + /// Adds a new Edge connects the two Nodes to the graph.
58.401 +
58.402 + /// Adds a new Edge connects the two Nodes to the graph.
58.403 + ///
58.404 + Edge addEdge(const Node&, const Node&) {
58.405 + return INVALID;
58.406 + }
58.407 +
58.408 + template <typename _Graph>
58.409 + struct Constraints {
58.410 + void constraints() {
58.411 + checkConcept<BaseGraphComponent, _Graph >();
58.412 + typename _Graph::Node node_a, node_b;
58.413 + node_a = graph.addNode();
58.414 + typename _Graph::Edge edge;
58.415 + edge = graph.addEdge(node_a, node_b);
58.416 + }
58.417 +
58.418 + _Graph& graph;
58.419 + };
58.420 + };
58.421 +
58.422 + /// An empty erasable base graph class.
58.423 +
58.424 + /// This class provides beside the core graph features
58.425 + /// core erase functions for the graph structure.
58.426 + /// The most of the base graphs should be conform to this concept.
58.427 + class BaseErasableGraphComponent : virtual public BaseGraphComponent {
58.428 + public:
58.429 +
58.430 + typedef BaseGraphComponent::Node Node;
58.431 + typedef BaseGraphComponent::Edge Edge;
58.432 +
58.433 + /// Erase a Node from the graph.
58.434 +
58.435 + /// Erase a Node from the graph. This function should not
58.436 + /// erase edges connecting to the Node.
58.437 + void erase(const Node&) {}
58.438 +
58.439 + /// Erase an Edge from the graph.
58.440 +
58.441 + /// Erase an Edge from the graph.
58.442 + ///
58.443 + void erase(const Edge&) {}
58.444 +
58.445 + template <typename _Graph>
58.446 + struct Constraints {
58.447 + void constraints() {
58.448 + checkConcept<BaseGraphComponent, _Graph>();
58.449 + typename _Graph::Node node;
58.450 + graph.erase(node);
58.451 + typename _Graph::Edge edge;
58.452 + graph.erase(edge);
58.453 + }
58.454 +
58.455 + _Graph& graph;
58.456 + };
58.457 + };
58.458 +
58.459 + /// An empty clearable base graph class.
58.460 +
58.461 + /// This class provides beside the core graph features
58.462 + /// core clear functions for the graph structure.
58.463 + /// The most of the base graphs should be conform to this concept.
58.464 + class ClearableGraphComponent : virtual public BaseGraphComponent {
58.465 + public:
58.466 +
58.467 + /// Erase all the Nodes and Edges from the graph.
58.468 +
58.469 + /// Erase all the Nodes and Edges from the graph.
58.470 + ///
58.471 + void clear() {}
58.472 +
58.473 + template <typename _Graph>
58.474 + struct Constraints {
58.475 + void constraints() {
58.476 + checkConcept<BaseGraphComponent, _Graph>();
58.477 + graph.clear();
58.478 + }
58.479 +
58.480 + _Graph graph;
58.481 + };
58.482 + };
58.483 +
58.484 +
58.485 + /// Skeleton class for graph NodeIt and EdgeIt
58.486 +
58.487 + /// Skeleton class for graph NodeIt and EdgeIt.
58.488 + ///
58.489 + template <typename _Graph, typename _Item>
58.490 + class GraphIterator : public _Item {
58.491 + public:
58.492 + /// \todo Don't we need the Item type as typedef?
58.493 +
58.494 + /// Default constructor.
58.495 +
58.496 + /// @warning The default constructor sets the iterator
58.497 + /// to an undefined value.
58.498 + GraphIterator() {}
58.499 + /// Copy constructor.
58.500 +
58.501 + /// Copy constructor.
58.502 + ///
58.503 + GraphIterator(GraphIterator const&) {}
58.504 + /// Sets the iterator to the first item.
58.505 +
58.506 + /// Sets the iterator to the first item of \c the graph.
58.507 + ///
58.508 + explicit GraphIterator(const _Graph&) {}
58.509 + /// Invalid constructor \& conversion.
58.510 +
58.511 + /// This constructor initializes the item to be invalid.
58.512 + /// \sa Invalid for more details.
58.513 + GraphIterator(Invalid) {}
58.514 + /// Assign operator for items.
58.515 +
58.516 + /// The items are assignable.
58.517 + ///
58.518 + GraphIterator& operator=(GraphIterator const&) { return *this; }
58.519 + /// Next item.
58.520 +
58.521 + /// Assign the iterator to the next item.
58.522 + ///
58.523 + GraphIterator& operator++() { return *this; }
58.524 + // Node operator*() const { return INVALID; }
58.525 + /// Equality operator
58.526 +
58.527 + /// Two iterators are equal if and only if they point to the
58.528 + /// same object or both are invalid.
58.529 + bool operator==(const GraphIterator&) const { return true;}
58.530 + /// Inequality operator
58.531 +
58.532 + /// \sa operator==(Node n)
58.533 + ///
58.534 + bool operator!=(const GraphIterator&) const { return true;}
58.535 +
58.536 + template<typename _GraphIterator>
58.537 + struct Constraints {
58.538 + void constraints() {
58.539 + // checkConcept< Item, _GraphIterator >();
58.540 + _GraphIterator it1(g);
58.541 +
58.542 + /// \todo Do we need NodeIt(Node) kind of constructor?
58.543 + // _GraphIterator it2(bj);
58.544 + _GraphIterator it2;
58.545 +
58.546 + it2 = ++it1;
58.547 + ++it2 = it1;
58.548 + ++(++it1);
58.549 + /// \bug This should be: is_base_and_derived<BaseItem, _GraphIterator>
58.550 + _Item bi = it1;
58.551 + bi = it2;
58.552 + }
58.553 + _Graph& g;
58.554 + };
58.555 + };
58.556 +
58.557 + /// Skeleton class for graph InEdgeIt and OutEdgeIt
58.558 +
58.559 + /// \note Because InEdgeIt and OutEdgeIt may not inherit from the same
58.560 + /// base class, the _selector is a additional template parameter. For
58.561 + /// InEdgeIt you should instantiate it with character 'i' and for
58.562 + /// OutEdgeIt with 'o'.
58.563 + /// \todo Is this a good name for this concept?
58.564 + template <typename Graph,
58.565 + typename Edge = typename Graph::Edge,
58.566 + char _selector = '0'>
58.567 + class GraphIncIterator : public Edge {
58.568 + public:
58.569 + /// Default constructor.
58.570 +
58.571 + /// @warning The default constructor sets the iterator
58.572 + /// to an undefined value.
58.573 + GraphIncIterator() {}
58.574 + /// Copy constructor.
58.575 +
58.576 + /// Copy constructor.
58.577 + ///
58.578 + GraphIncIterator(GraphIncIterator const& gi) :Edge(gi) {}
58.579 + /// Sets the iterator to the first edge incoming into or outgoing
58.580 + /// from the node.
58.581 +
58.582 + /// Sets the iterator to the first edge incoming into or outgoing
58.583 + /// from the node.
58.584 + ///
58.585 + explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {}
58.586 + /// Invalid constructor \& conversion.
58.587 +
58.588 + /// This constructor initializes the item to be invalid.
58.589 + /// \sa Invalid for more details.
58.590 + GraphIncIterator(Invalid) {}
58.591 + /// Assign operator for nodes.
58.592 +
58.593 + /// The nodes are assignable.
58.594 + ///
58.595 + GraphIncIterator& operator=(GraphIncIterator const&) { return *this; }
58.596 + /// Next edge.
58.597 +
58.598 + /// Assign the iterator to the next node.
58.599 + ///
58.600 + GraphIncIterator& operator++() { return *this; }
58.601 +
58.602 + // Node operator*() const { return INVALID; }
58.603 +
58.604 + /// Equality operator
58.605 +
58.606 + /// Two iterators are equal if and only if they point to the
58.607 + /// same object or both are invalid.
58.608 + bool operator==(const GraphIncIterator&) const { return true;}
58.609 +
58.610 + /// Inequality operator
58.611 +
58.612 + /// \sa operator==(Node n)
58.613 + ///
58.614 + bool operator!=(const GraphIncIterator&) const { return true;}
58.615 +
58.616 + template <typename _GraphIncIterator>
58.617 + struct Constraints {
58.618 + typedef typename Graph::Node Node;
58.619 + void constraints() {
58.620 + checkConcept<GraphItem<'e'>, _GraphIncIterator>();
58.621 + _GraphIncIterator it1(graph, node);
58.622 + /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
58.623 + // _GraphIncIterator it2(edge);
58.624 + _GraphIncIterator it2;
58.625 +
58.626 + it2 = ++it1;
58.627 + ++it2 = it1;
58.628 + ++(++it1);
58.629 + Edge e = it1;
58.630 + e = it2;
58.631 +
58.632 + const_constraits();
58.633 + }
58.634 +
58.635 + void const_constraits() {
58.636 + Node n = graph.baseNode(it);
58.637 + n = graph.runningNode(it);
58.638 + }
58.639 +
58.640 + Edge edge;
58.641 + Node node;
58.642 + Graph graph;
58.643 + _GraphIncIterator it;
58.644 + };
58.645 + };
58.646 +
58.647 +
58.648 + /// An empty iterable base graph class.
58.649 +
58.650 + /// This class provides beside the core graph features
58.651 + /// iterator based iterable interface for the graph structure.
58.652 + /// This concept is part of the StaticGraphConcept.
58.653 + class IterableGraphComponent : virtual public BaseGraphComponent {
58.654 +
58.655 + public:
58.656 +
58.657 + typedef IterableGraphComponent Graph;
58.658 +
58.659 + typedef BaseGraphComponent::Node Node;
58.660 + typedef BaseGraphComponent::Edge Edge;
58.661 +
58.662 + /// This iterator goes through each node.
58.663 +
58.664 + /// This iterator goes through each node.
58.665 + ///
58.666 + typedef GraphIterator<Graph, Node> NodeIt;
58.667 + /// This iterator goes through each node.
58.668 +
58.669 + /// This iterator goes through each node.
58.670 + ///
58.671 + typedef GraphIterator<Graph, Edge> EdgeIt;
58.672 + /// This iterator goes trough the incoming edges of a node.
58.673 +
58.674 + /// This iterator goes trough the \e inccoming edges of a certain node
58.675 + /// of a graph.
58.676 + typedef GraphIncIterator<Graph, Edge, 'i'> InEdgeIt;
58.677 + /// This iterator goes trough the outgoing edges of a node.
58.678 +
58.679 + /// This iterator goes trough the \e outgoing edges of a certain node
58.680 + /// of a graph.
58.681 + typedef GraphIncIterator<Graph, Edge, 'o'> OutEdgeIt;
58.682 + };
58.683 +
58.684 + template <typename _Graph>
58.685 + struct Constraints {
58.686 + void constraints() {
58.687 + checkConcept< BaseGraphComponent, _Graph>();
58.688 +
58.689 + checkConcept<GraphIterator<_Graph, typename _Graph::Edge>,
58.690 + typename _Graph::EdgeIt >();
58.691 + checkConcept<GraphIterator<_Graph, typename _Graph::Node>,
58.692 + typename _Graph::NodeIt >();
58.693 + checkConcept<GraphIncIterator<_Graph>, typename _Graph::InEdgeIt >();
58.694 + checkConcept<GraphIncIterator<_Graph>, typename _Graph::OutEdgeIt >();
58.695 + }
58.696 + };
58.697 +
58.698 + /// An empty alteration notifier base graph class.
58.699 +
58.700 + /// This class provides beside the core graph features
58.701 + /// alteration notifier interface for the graph structure.
58.702 + /// This is an observer-notifier pattern. More Obsevers can
58.703 + /// be registered into the notifier and whenever an alteration
58.704 + /// occured in the graph all the observers will notified about it.
58.705 + class AlterableGraphComponent : virtual public BaseGraphComponent {
58.706 + public:
58.707 +
58.708 + /// The edge observer registry.
58.709 + typedef AlterationNotifier<Edge> EdgeNotifier;
58.710 + /// The node observer registry.
58.711 + typedef AlterationNotifier<Node> NodeNotifier;
58.712 +
58.713 + /// \brief Gives back the edge alteration notifier.
58.714 + ///
58.715 + /// Gives back the edge alteration notifier.
58.716 + EdgeNotifier getNotifier(Edge) const {
58.717 + return EdgeNotifier();
58.718 + }
58.719 +
58.720 + /// \brief Gives back the node alteration notifier.
58.721 + ///
58.722 + /// Gives back the node alteration notifier.
58.723 + NodeNotifier getNotifier(Node) const {
58.724 + return NodeNotifier();
58.725 + }
58.726 +
58.727 + };
58.728 +
58.729 +
58.730 + /// Class describing the concept of graph maps
58.731 +
58.732 + /// This class describes the common interface of the graph maps
58.733 + /// (NodeMap, EdgeMap), that is \ref maps-pages "maps" which can be used to
58.734 + /// associate data to graph descriptors (nodes or edges).
58.735 + template <typename Graph, typename Item, typename _Value>
58.736 + class GraphMap : public ReadWriteMap<Item, _Value> {
58.737 + protected:
58.738 + GraphMap() {}
58.739 + public:
58.740 + /// \brief Construct a new map.
58.741 + ///
58.742 + /// Construct a new map for the graph.
58.743 + explicit GraphMap(const Graph&) {}
58.744 + /// \brief Construct a new map with default value.
58.745 + ///
58.746 + /// Construct a new map for the graph and initalise the values.
58.747 + GraphMap(const Graph&, const _Value&) {}
58.748 + /// \brief Copy constructor.
58.749 + ///
58.750 + /// Copy Constructor.
58.751 + GraphMap(const GraphMap& gm) :ReadWriteMap<Item, _Value>(gm) {}
58.752 +
58.753 + /// \brief Assign operator.
58.754 + ///
58.755 + /// Assign operator.
58.756 + GraphMap& operator=(const GraphMap&) { return *this;}
58.757 +
58.758 + template<typename _Map>
58.759 + struct Constraints {
58.760 + void constraints() {
58.761 + checkConcept<ReadWriteMap<Item, _Value>, _Map >();
58.762 + // Construction with a graph parameter
58.763 + _Map a(g);
58.764 + // Constructor with a graph and a default value parameter
58.765 + _Map a2(g,t);
58.766 + // Copy constructor. Do we need it?
58.767 + _Map b=c;
58.768 + // Copy operator. Do we need it?
58.769 + a=b;
58.770 +
58.771 + ignore_unused_variable_warning(a2);
58.772 + }
58.773 +
58.774 + const _Map &c;
58.775 + const Graph &g;
58.776 + const typename GraphMap::Value &t;
58.777 + };
58.778 +
58.779 + };
58.780 +
58.781 + /// An empty mappable base graph class.
58.782 +
58.783 + /// This class provides beside the core graph features
58.784 + /// map interface for the graph structure.
58.785 + /// This concept is part of the StaticGraphConcept.
58.786 + class MappableGraphComponent : virtual public BaseGraphComponent {
58.787 + public:
58.788 +
58.789 + typedef MappableGraphComponent Graph;
58.790 +
58.791 + typedef BaseGraphComponent::Node Node;
58.792 + typedef BaseGraphComponent::Edge Edge;
58.793 +
58.794 + /// ReadWrite map of the nodes.
58.795 +
58.796 + /// ReadWrite map of the nodes.
58.797 + ///
58.798 + template <typename _Value>
58.799 + class NodeMap : public GraphMap<Graph, Node, _Value> {
58.800 + private:
58.801 + NodeMap();
58.802 + public:
58.803 + /// \brief Construct a new map.
58.804 + ///
58.805 + /// Construct a new map for the graph.
58.806 + /// \todo call the right parent class constructor
58.807 + explicit NodeMap(const Graph&) {}
58.808 + /// \brief Construct a new map with default value.
58.809 + ///
58.810 + /// Construct a new map for the graph and initalise the values.
58.811 + NodeMap(const Graph&, const _Value&) {}
58.812 + /// \brief Copy constructor.
58.813 + ///
58.814 + /// Copy Constructor.
58.815 + NodeMap(const NodeMap& nm) : GraphMap<Graph, Node, _Value>(nm) {}
58.816 +
58.817 + /// \brief Assign operator.
58.818 + ///
58.819 + /// Assign operator.
58.820 + NodeMap& operator=(const NodeMap&) { return *this;}
58.821 +
58.822 + };
58.823 +
58.824 + /// ReadWrite map of the edges.
58.825 +
58.826 + /// ReadWrite map of the edges.
58.827 + ///
58.828 + template <typename _Value>
58.829 + class EdgeMap : public GraphMap<Graph, Edge, _Value> {
58.830 + private:
58.831 + EdgeMap();
58.832 + public:
58.833 + /// \brief Construct a new map.
58.834 + ///
58.835 + /// Construct a new map for the graph.
58.836 + /// \todo call the right parent class constructor
58.837 + explicit EdgeMap(const Graph&) {}
58.838 + /// \brief Construct a new map with default value.
58.839 + ///
58.840 + /// Construct a new map for the graph and initalise the values.
58.841 + EdgeMap(const Graph&, const _Value&) {}
58.842 + /// \brief Copy constructor.
58.843 + ///
58.844 + /// Copy Constructor.
58.845 + EdgeMap(const EdgeMap& em) :GraphMap<Graph, Edge, _Value>(em) {}
58.846 +
58.847 + /// \brief Assign operator.
58.848 + ///
58.849 + /// Assign operator.
58.850 + EdgeMap& operator=(const EdgeMap&) { return *this;}
58.851 +
58.852 + };
58.853 +
58.854 + template <typename _Graph>
58.855 + struct Constraints {
58.856 +
58.857 + struct Type {
58.858 + int value;
58.859 + Type() : value(0) {}
58.860 + Type(int _v) : value(_v) {}
58.861 + };
58.862 +
58.863 + void constraints() {
58.864 + checkConcept<BaseGraphComponent, _Graph>();
58.865 + { // int map test
58.866 + typedef typename _Graph::template NodeMap<int> IntNodeMap;
58.867 + checkConcept<GraphMap<_Graph, typename _Graph::Node, int>,
58.868 + IntNodeMap >();
58.869 + } { // bool map test
58.870 + typedef typename _Graph::template NodeMap<bool> BoolNodeMap;
58.871 + checkConcept<GraphMap<_Graph, typename _Graph::Node, bool>,
58.872 + BoolNodeMap >();
58.873 + } { // Type map test
58.874 + typedef typename _Graph::template NodeMap<Type> TypeNodeMap;
58.875 + checkConcept<GraphMap<_Graph, typename _Graph::Node, Type>,
58.876 + TypeNodeMap >();
58.877 + }
58.878 +
58.879 + { // int map test
58.880 + typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
58.881 + checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
58.882 + IntEdgeMap >();
58.883 + } { // bool map test
58.884 + typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
58.885 + checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
58.886 + BoolEdgeMap >();
58.887 + } { // Type map test
58.888 + typedef typename _Graph::template EdgeMap<Type> TypeEdgeMap;
58.889 + checkConcept<GraphMap<_Graph, typename _Graph::Edge, Type>,
58.890 + TypeEdgeMap >();
58.891 + }
58.892 + }
58.893 +
58.894 + _Graph& graph;
58.895 + };
58.896 + };
58.897 +
58.898 + /// \brief An empty extendable extended graph class.
58.899 + ///
58.900 + /// This class provides beside the core graph features
58.901 + /// item addition interface for the graph structure.
58.902 + /// The difference between this class and the
58.903 + /// \c BaseExtendableGraphComponent is that it should
58.904 + /// notify the item alteration observers.
58.905 + class ExtendableGraphComponent : virtual public BaseGraphComponent {
58.906 + public:
58.907 +
58.908 + typedef ExtendableGraphComponent Graph;
58.909 +
58.910 + typedef BaseGraphComponent::Node Node;
58.911 + typedef BaseGraphComponent::Edge Edge;
58.912 +
58.913 + /// \brief Add a node to the graph.
58.914 + ///
58.915 + /// Add a node to the graph and notify the observers.
58.916 + Node addNode() {
58.917 + return INVALID;
58.918 + }
58.919 +
58.920 + /// \brief Add an edge to the graph.
58.921 + ///
58.922 + /// Add an edge to the graph and notify the observers.
58.923 + Edge addEdge(const Node&, const Node&) {
58.924 + return INVALID;
58.925 + }
58.926 +
58.927 + template <typename _Graph>
58.928 + struct Constraints {
58.929 + void constraints() {
58.930 + checkConcept<BaseGraphComponent, _Graph >();
58.931 + typename _Graph::Node node_a, node_b;
58.932 + node_a = graph.addNode();
58.933 + typename _Graph::Edge edge;
58.934 + edge = graph.addEdge(node_a, node_b);
58.935 + }
58.936 + _Graph& graph;
58.937 + };
58.938 + };
58.939 +
58.940 + /// \brief An empty erasable extended graph class.
58.941 + ///
58.942 + /// This class provides beside the core graph features
58.943 + /// item erase interface for the graph structure.
58.944 + /// The difference between this class and the
58.945 + /// \c BaseErasableGraphComponent is that it should
58.946 + /// notify the item alteration observers.
58.947 + class ErasableGraphComponent : virtual public BaseGraphComponent {
58.948 + public:
58.949 +
58.950 + typedef ErasableGraphComponent Graph;
58.951 +
58.952 + typedef BaseGraphComponent::Node Node;
58.953 + typedef BaseGraphComponent::Edge Edge;
58.954 +
58.955 + /// \brief Erase the Node and notify the node alteration observers.
58.956 + ///
58.957 + /// Erase the Node and notify the node alteration observers.
58.958 + void erase(const Node&) {}
58.959 +
58.960 + /// \brief Erase the Edge and notify the edge alteration observers.
58.961 + ///
58.962 + /// Erase the Edge and notify the edge alteration observers.
58.963 + void erase(const Edge&) {}
58.964 +
58.965 + template <typename _Graph>
58.966 + struct Constraints {
58.967 + void constraints() {
58.968 + checkConcept<BaseGraphComponent, _Graph >();
58.969 + typename _Graph::Node node;
58.970 + graph.erase(node);
58.971 + typename _Graph::Edge edge;
58.972 + graph.erase(edge);
58.973 + }
58.974 +
58.975 + _Graph& graph;
58.976 + };
58.977 + };
58.978 +
58.979 + /// @}
58.980 +
58.981 + }
58.982 +
58.983 +}
58.984 +
58.985 +#endif
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/lemon/concept/heap.h Mon May 23 04:48:14 2005 +0000
59.3 @@ -0,0 +1,201 @@
59.4 +/* -*- C++ -*-
59.5 + * lemon/concept/heap.h - Part of LEMON, a generic C++ optimization library
59.6 + *
59.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
59.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
59.9 + *
59.10 + * Permission to use, modify and distribute this software is granted
59.11 + * provided that this copyright notice appears in all copies. For
59.12 + * precise terms see the accompanying LICENSE file.
59.13 + *
59.14 + * This software is provided "AS IS" with no warranty of any kind,
59.15 + * express or implied, and with no claim as to its suitability for any
59.16 + * purpose.
59.17 + *
59.18 + */
59.19 +
59.20 +///\ingroup concept
59.21 +///\file
59.22 +///\brief Classes for representing heaps.
59.23 +///
59.24 +
59.25 +#ifndef LEMON_CONCEPT_HEAP_H
59.26 +#define LEMON_CONCEPT_HEAP_H
59.27 +
59.28 +#include <lemon/invalid.h>
59.29 +
59.30 +namespace lemon {
59.31 + namespace concept {
59.32 + /// \addtogroup concept
59.33 + /// @{
59.34 +
59.35 +
59.36 + /// \brief A concept structure describes the main interface of heaps.
59.37 + ///
59.38 + /// A concept structure describes the main interface of heaps.
59.39 + ///
59.40 + template <typename Item, typename Prio, typename ItemIntMap>
59.41 + class Heap {
59.42 + public:
59.43 +
59.44 +
59.45 + /// \brief Type to represent the items states.
59.46 + ///
59.47 + /// Each Item element have a state associated to it. It may be "in heap",
59.48 + /// "pre heap" or "post heap". The later two are indifferent from the
59.49 + /// heap's point of view, but may be useful to the user.
59.50 + ///
59.51 + /// The ItemIntMap _should_ be initialized in such way, that it maps
59.52 + /// PRE_HEAP (-1) to any element to be put in the heap...
59.53 + enum state_enum {
59.54 + IN_HEAP = 0,
59.55 + PRE_HEAP = -1,
59.56 + POST_HEAP = -2
59.57 + };
59.58 +
59.59 + /// \brief The constructor.
59.60 + ///
59.61 + /// The constructor.
59.62 + /// \param _iim should be given to the constructor, since it is used
59.63 + /// internally to handle the cross references. The value of the map
59.64 + /// should be PRE_HEAP (-1) for each element.
59.65 + explicit Heap(ItemIntMap &_iim) {}
59.66 +
59.67 + /// The number of items stored in the heap.
59.68 + ///
59.69 + /// \brief Returns the number of items stored in the heap.
59.70 + int size() const { return 0; }
59.71 + /// \brief Checks if the heap stores no items.
59.72 + ///
59.73 + /// Returns \c true if and only if the heap stores no items.
59.74 + bool empty() const { return false; }
59.75 +
59.76 + /// \brief Insert an item into the heap with the given heap.
59.77 + ///
59.78 + /// Adds \c i to the heap with priority \c p.
59.79 + /// \param i The item to insert.
59.80 + /// \param p The priority of the item.
59.81 + void push(const Item &i, const Prio &p) {}
59.82 +
59.83 + /// \brief Returns the item with minimum priority.
59.84 + ///
59.85 + /// This method returns the item with minimum priority.
59.86 + /// \pre The heap must be nonempty.
59.87 + Item top() const {}
59.88 +
59.89 + /// \brief Returns the minimum priority.
59.90 + ///
59.91 + /// It returns the minimum priority.
59.92 + /// \pre The heap must be nonempty.
59.93 + Prio prio() const {}
59.94 +
59.95 + /// \brief Deletes the item with minimum priority.
59.96 + ///
59.97 + /// This method deletes the item with minimum priority.
59.98 + /// \pre The heap must be non-empty.
59.99 + void pop() {}
59.100 +
59.101 + /// \brief Deletes \c i from the heap.
59.102 + ///
59.103 + /// This method deletes item \c i from the heap, if \c i was
59.104 + /// already stored in the heap.
59.105 + /// \param i The item to erase.
59.106 + void erase(const Item &i) {}
59.107 +
59.108 + /// \brief Returns the priority of \c i.
59.109 + ///
59.110 + /// This function returns the priority of item \c i.
59.111 + /// \pre \c i must be in the heap.
59.112 + /// \param i The item.
59.113 + Prio operator[](const Item &i) const {}
59.114 +
59.115 + /// \brief \c i gets to the heap with priority \c p independently
59.116 + /// if \c i was already there.
59.117 + ///
59.118 + /// This method calls \ref push(\c i, \c p) if \c i is not stored
59.119 + /// in the heap and sets the priority of \c i to \c p otherwise.
59.120 + /// It may throw an \e UnderFlowPriorityException.
59.121 + /// \param i The item.
59.122 + /// \param p The priority.
59.123 + void set(const Item &i, const Prio &p) {}
59.124 +
59.125 + /// \brief Decreases the priority of \c i to \c p.
59.126 + ///
59.127 + /// This method decreases the priority of item \c i to \c p.
59.128 + /// \pre \c i must be stored in the heap with priority at least \c p.
59.129 + /// \param i The item.
59.130 + /// \param p The priority.
59.131 + void decrease(const Item &i, const Prio &p) {}
59.132 +
59.133 + /// \brief Increases the priority of \c i to \c p.
59.134 + ///
59.135 + /// This method sets the priority of item \c i to \c p.
59.136 + /// \pre \c i must be stored in the heap with priority at most \c
59.137 + /// p relative to \c Compare.
59.138 + /// \param i The item.
59.139 + /// \param p The priority.
59.140 + void increase(const Item &i, const Prio &p) {}
59.141 +
59.142 + /// \brief Returns if \c item is in, has already been in, or has
59.143 + /// never been in the heap.
59.144 + ///
59.145 + /// This method returns PRE_HEAP if \c item has never been in the
59.146 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
59.147 + /// otherwise. In the latter case it is possible that \c item will
59.148 + /// get back to the heap again.
59.149 + /// \param i The item.
59.150 + state_enum state(const Item &i) const {}
59.151 +
59.152 +
59.153 + template <typename _Heap>
59.154 + struct Constraints {
59.155 + public:
59.156 +
59.157 + void constraints() {
59.158 + Item item;
59.159 + Prio prio;
59.160 +
59.161 + ignore_unused_variable_warning(item);
59.162 + ignore_unused_variable_warning(prio);
59.163 +
59.164 + typedef typename _Heap::state_enum state_enum;
59.165 + state_enum state;
59.166 +
59.167 + ignore_unused_variable_warning(state);
59.168 +
59.169 + _Heap heap1 = _Heap(map);
59.170 +
59.171 + ignore_unused_variable_warning(heap1);
59.172 +
59.173 + heap.push(item, prio);
59.174 +
59.175 + prio = heap.prio();
59.176 + item = heap.top();
59.177 +
59.178 + heap.pop();
59.179 +
59.180 + heap.set(item, prio);
59.181 + heap.decrease(item, prio);
59.182 + heap.increase(item, prio);
59.183 + prio = heap[item];
59.184 +
59.185 + heap.erase(item);
59.186 +
59.187 + state = heap.state(item);
59.188 +
59.189 + state = _Heap::PRE_HEAP;
59.190 + state = _Heap::IN_HEAP;
59.191 + state = _Heap::POST_HEAP;
59.192 + }
59.193 +
59.194 + _Heap& heap;
59.195 + ItemIntMap& map;
59.196 +
59.197 + Constraints() : heap(0), map(0) {}
59.198 + };
59.199 + };
59.200 +
59.201 + /// @}
59.202 + } // namespace lemon
59.203 +}
59.204 +#endif // LEMON_CONCEPT_PATH_H
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/lemon/concept/maps.h Mon May 23 04:48:14 2005 +0000
60.3 @@ -0,0 +1,187 @@
60.4 +/* -*- C++ -*-
60.5 + * lemon/concept/maps.h - Part of LEMON, a generic C++ optimization library
60.6 + *
60.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
60.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
60.9 + *
60.10 + * Permission to use, modify and distribute this software is granted
60.11 + * provided that this copyright notice appears in all copies. For
60.12 + * precise terms see the accompanying LICENSE file.
60.13 + *
60.14 + * This software is provided "AS IS" with no warranty of any kind,
60.15 + * express or implied, and with no claim as to its suitability for any
60.16 + * purpose.
60.17 + *
60.18 + */
60.19 +
60.20 +#ifndef LEMON_CONCEPT_MAPS_H
60.21 +#define LEMON_CONCEPT_MAPS_H
60.22 +
60.23 +#include <lemon/concept_check.h>
60.24 +
60.25 +///\ingroup concept
60.26 +///\file
60.27 +///\brief Map concepts checking classes for testing and documenting.
60.28 +
60.29 +namespace lemon {
60.30 +
60.31 + namespace concept {
60.32 +
60.33 + /// \addtogroup concept
60.34 + /// @{
60.35 +
60.36 + /// Readable map concept
60.37 + template<typename K, typename T>
60.38 + class ReadMap
60.39 + {
60.40 + public:
60.41 + /// Map's key type.
60.42 + typedef K Key;
60.43 + /// Map's value type. (The type of objects associated with the keys).
60.44 + typedef T Value;
60.45 +
60.46 + // \bug Value don't need to be default constructible.
60.47 + /// Returns the value associated with a key.
60.48 + Value operator[](const Key &) const {return Value();}
60.49 +
60.50 + template<typename _ReadMap>
60.51 + struct Constraints {
60.52 +
60.53 + void constraints() {
60.54 + Value val = m[key];
60.55 + val = m[key];
60.56 + typename _ReadMap::Value own_val = m[own_key];
60.57 + own_val = m[own_key];
60.58 +
60.59 + ignore_unused_variable_warning(val);
60.60 + ignore_unused_variable_warning(own_val);
60.61 + ignore_unused_variable_warning(key);
60.62 + }
60.63 + Key& key;
60.64 + typename _ReadMap::Key& own_key;
60.65 + _ReadMap& m;
60.66 + };
60.67 +
60.68 + };
60.69 +
60.70 +
60.71 + /// Writable map concept
60.72 + template<typename K, typename T>
60.73 + class WriteMap
60.74 + {
60.75 + public:
60.76 + /// Map's key type.
60.77 + typedef K Key;
60.78 + /// Map's value type. (The type of objects associated with the keys).
60.79 + typedef T Value;
60.80 +
60.81 + /// Sets the value associated with a key.
60.82 + void set(const Key &,const Value &) {}
60.83 +
60.84 + ///Default constructor
60.85 + WriteMap() {}
60.86 +
60.87 + template <typename _WriteMap>
60.88 + struct Constraints {
60.89 + void constraints() {
60.90 + // No constraints for constructor.
60.91 + m.set(key, val);
60.92 + m.set(own_key, own_val);
60.93 + ignore_unused_variable_warning(key);
60.94 + ignore_unused_variable_warning(val);
60.95 + ignore_unused_variable_warning(own_key);
60.96 + ignore_unused_variable_warning(own_val);
60.97 + }
60.98 +
60.99 + Value& val;
60.100 + typename _WriteMap::Value own_val;
60.101 + Key& key;
60.102 + typename _WriteMap::Key& own_key;
60.103 + WriteMap& m;
60.104 +
60.105 + };
60.106 + };
60.107 +
60.108 + ///Read/Writable map concept
60.109 + template<typename K, typename T>
60.110 + class ReadWriteMap : public ReadMap<K,T>,
60.111 + public WriteMap<K,T>
60.112 + {
60.113 + public:
60.114 + /// Map's key type.
60.115 + typedef K Key;
60.116 + /// Map's value type. (The type of objects associated with the keys).
60.117 + typedef T Value;
60.118 +
60.119 + /// Returns the value associated with a key.
60.120 + Value operator[](const Key &) const {return Value();}
60.121 + /// Sets the value associated with a key.
60.122 + void set(const Key & ,const Value &) {}
60.123 +
60.124 + template<typename _ReadWriteMap>
60.125 + struct Constraints {
60.126 + void constraints() {
60.127 + checkConcept<ReadMap<K, T>, _ReadWriteMap >();
60.128 + checkConcept<ReadMap<K, T>, _ReadWriteMap >();
60.129 + }
60.130 + };
60.131 + };
60.132 +
60.133 +
60.134 + ///Dereferable map concept
60.135 + template<typename K, typename T, typename R, typename CR>
60.136 + class ReferenceMap : public ReadWriteMap<K,T>
60.137 + {
60.138 + public:
60.139 + /// Map's key type.
60.140 + typedef K Key;
60.141 + /// Map's value type. (The type of objects associated with the keys).
60.142 + typedef T Value;
60.143 + /// Map's reference type.
60.144 + typedef R Reference;
60.145 + /// Map's const reference type.
60.146 + typedef CR ConstReference;
60.147 +
60.148 + protected:
60.149 + Value tmp;
60.150 + public:
60.151 +
60.152 + ///Returns a reference to the value associated to a key.
60.153 + Reference operator[](const Key &) { return tmp; }
60.154 + ///Returns a const reference to the value associated to a key.
60.155 + ConstReference operator[](const Key &) const
60.156 + { return tmp; }
60.157 + /// Sets the value associated with a key.
60.158 + void set(const Key &k,const Value &t) { operator[](k)=t; }
60.159 +
60.160 + // \todo rethink this concept
60.161 + template<typename _ReferenceMap>
60.162 + struct ReferenceMapConcept {
60.163 +
60.164 + void constraints() {
60.165 + checkConcept<ReadWriteMap, _ReferenceMap >();
60.166 + m[key] = val;
60.167 + val = m[key];
60.168 + m[key] = ref;
60.169 + ref = m[key];
60.170 + m[own_key] = own_val;
60.171 + own_val = m[own_key];
60.172 + m[own_key] = own_ref;
60.173 + own_ref = m[own_key];
60.174 + }
60.175 +
60.176 + typename _ReferenceMap::Key& own_key;
60.177 + typename _ReferenceMap::Value& own_val;
60.178 + typename _ReferenceMap::Reference& own_ref;
60.179 + Key& key;
60.180 + Value& val;
60.181 + Reference& ref;
60.182 + ReferenceMap& m;
60.183 + };
60.184 + };
60.185 +
60.186 + // @}
60.187 +
60.188 + } //namespace concept
60.189 +} //namespace lemon
60.190 +#endif // LEMON_CONCEPT_MAPS_H
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/lemon/concept/path.h Mon May 23 04:48:14 2005 +0000
61.3 @@ -0,0 +1,236 @@
61.4 +/* -*- C++ -*-
61.5 + * lemon/concept/path.h - Part of LEMON, a generic C++ optimization library
61.6 + *
61.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
61.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
61.9 + *
61.10 + * Permission to use, modify and distribute this software is granted
61.11 + * provided that this copyright notice appears in all copies. For
61.12 + * precise terms see the accompanying LICENSE file.
61.13 + *
61.14 + * This software is provided "AS IS" with no warranty of any kind,
61.15 + * express or implied, and with no claim as to its suitability for any
61.16 + * purpose.
61.17 + *
61.18 + */
61.19 +
61.20 +///\ingroup concept
61.21 +///\file
61.22 +///\brief Classes for representing paths in graphs.
61.23 +///
61.24 +///\todo Iterators have obsolete style
61.25 +
61.26 +#ifndef LEMON_CONCEPT_PATH_H
61.27 +#define LEMON_CONCEPT_PATH_H
61.28 +
61.29 +#include <lemon/invalid.h>
61.30 +
61.31 +namespace lemon {
61.32 + namespace concept {
61.33 + /// \addtogroup concept
61.34 + /// @{
61.35 +
61.36 +
61.37 + //! \brief A skeleton structure for representing directed paths in a graph.
61.38 + //!
61.39 + //! A skeleton structure for representing directed paths in a graph.
61.40 + //! \param GR The graph type in which the path is.
61.41 + //!
61.42 + //! In a sense, the path can be treated as a graph, for it has \c NodeIt
61.43 + //! and \c EdgeIt with the same usage. These types converts to the \c Node
61.44 + //! and \c Edge of the original graph.
61.45 + template<typename GR>
61.46 + class Path {
61.47 + public:
61.48 +
61.49 + /// Type of the underlying graph.
61.50 + typedef /*typename*/ GR Graph;
61.51 + /// Edge type of the underlying graph.
61.52 + typedef typename Graph::Edge GraphEdge;
61.53 + /// Node type of the underlying graph.
61.54 + typedef typename Graph::Node GraphNode;
61.55 + class NodeIt;
61.56 + class EdgeIt;
61.57 +
61.58 + /// \param _G The graph in which the path is.
61.59 + ///
61.60 + Path(const Graph &) {}
61.61 +
61.62 + /// Length of the path.
61.63 + int length() const {return 0;}
61.64 + /// Returns whether the path is empty.
61.65 + bool empty() const { return true;}
61.66 +
61.67 + /// Resets the path to an empty path.
61.68 + void clear() {}
61.69 +
61.70 + /// \brief Starting point of the path.
61.71 + ///
61.72 + /// Starting point of the path.
61.73 + /// Returns INVALID if the path is empty.
61.74 + GraphNode/*It*/ target() const {return INVALID;}
61.75 + /// \brief End point of the path.
61.76 + ///
61.77 + /// End point of the path.
61.78 + /// Returns INVALID if the path is empty.
61.79 + GraphNode/*It*/ source() const {return INVALID;}
61.80 +
61.81 + /// \brief First NodeIt/EdgeIt.
61.82 + ///
61.83 + /// Initializes node or edge iterator to point to the first
61.84 + /// node or edge.
61.85 + template<typename It>
61.86 + It& first(It &i) const { return i=It(*this); }
61.87 +
61.88 + /// \brief The target of an edge.
61.89 + ///
61.90 + /// Returns node iterator pointing to the target node of the
61.91 + /// given edge iterator.
61.92 + NodeIt target(const EdgeIt&) const {return INVALID;}
61.93 +
61.94 + /// \brief The source of an edge.
61.95 + ///
61.96 + /// Returns node iterator pointing to the source node of the
61.97 + /// given edge iterator.
61.98 + NodeIt source(const EdgeIt&) const {return INVALID;}
61.99 +
61.100 +
61.101 + /* Iterator classes */
61.102 +
61.103 + /**
61.104 + * \brief Iterator class to iterate on the edges of the paths
61.105 + *
61.106 + * This class is used to iterate on the edges of the paths
61.107 + *
61.108 + * Of course it converts to Graph::Edge
61.109 + *
61.110 + */
61.111 + class EdgeIt {
61.112 + public:
61.113 + /// Default constructor
61.114 + EdgeIt() {}
61.115 + /// Invalid constructor
61.116 + EdgeIt(Invalid) {}
61.117 + /// Constructor with starting point
61.118 + EdgeIt(const Path &) {}
61.119 +
61.120 + operator GraphEdge () const {}
61.121 +
61.122 + /// Next edge
61.123 + EdgeIt& operator++() {return *this;}
61.124 +
61.125 + /// Comparison operator
61.126 + bool operator==(const EdgeIt&) const {return true;}
61.127 + /// Comparison operator
61.128 + bool operator!=(const EdgeIt&) const {return true;}
61.129 +// /// Comparison operator
61.130 +// /// \todo It is not clear what is the "natural" ordering.
61.131 +// bool operator<(const EdgeIt& e) const {}
61.132 +
61.133 + };
61.134 +
61.135 + /**
61.136 + * \brief Iterator class to iterate on the nodes of the paths
61.137 + *
61.138 + * This class is used to iterate on the nodes of the paths
61.139 + *
61.140 + * Of course it converts to Graph::Node.
61.141 + *
61.142 + */
61.143 + class NodeIt {
61.144 + public:
61.145 + /// Default constructor
61.146 + NodeIt() {}
61.147 + /// Invalid constructor
61.148 + NodeIt(Invalid) {}
61.149 + /// Constructor with starting point
61.150 + NodeIt(const Path &) {}
61.151 +
61.152 + ///Conversion to Graph::Node
61.153 + operator const GraphNode& () const {}
61.154 + /// Next node
61.155 + NodeIt& operator++() {return *this;}
61.156 +
61.157 + /// Comparison operator
61.158 + bool operator==(const NodeIt&) const {return true;}
61.159 + /// Comparison operator
61.160 + bool operator!=(const NodeIt&) const {return true;}
61.161 +// /// Comparison operator
61.162 +// /// \todo It is not clear what is the "natural" ordering.
61.163 +// bool operator<(const NodeIt& e) const {}
61.164 +
61.165 + };
61.166 +
61.167 + friend class Builder;
61.168 +
61.169 + /**
61.170 + * \brief Class to build paths
61.171 + *
61.172 + * This class is used to fill a path with edges.
61.173 + *
61.174 + * You can push new edges to the front and to the back of the path in
61.175 + * arbitrary order then you should commit these changes to the graph.
61.176 + *
61.177 + * While the builder is active (after the first modifying
61.178 + * operation and until the call of \ref commit()) the
61.179 + * underlining Path is in a "transitional" state (operations on
61.180 + * it have undefined result).
61.181 + */
61.182 + class Builder {
61.183 + public:
61.184 +
61.185 + Path &P;
61.186 +
61.187 + ///\param _P the path you want to fill in.
61.188 + ///
61.189 +
61.190 + Builder(Path &_p) : P(_p) {}
61.191 +
61.192 + /// Sets the starting node of the path.
61.193 +
61.194 + /// Sets the starting node of the path. Edge added to the path
61.195 + /// afterwards have to be incident to this node.
61.196 + /// You \em must start building an empty path with these functions.
61.197 + /// (And you \em must \em not use it later).
61.198 + /// \sa pushFront()
61.199 + /// \sa pushBack()
61.200 + void setStartNode(const GraphNode &) {}
61.201 +
61.202 + ///Push a new edge to the front of the path
61.203 +
61.204 + ///Push a new edge to the front of the path.
61.205 + ///If the path is empty, you \em must call \ref setStartNode() before
61.206 + ///the first use of \ref pushFront().
61.207 + void pushFront(const GraphEdge&) {}
61.208 +
61.209 + ///Push a new edge to the back of the path
61.210 +
61.211 + ///Push a new edge to the back of the path.
61.212 + ///If the path is empty, you \em must call \ref setStartNode() before
61.213 + ///the first use of \ref pushBack().
61.214 + void pushBack(const GraphEdge&) {}
61.215 +
61.216 + ///Commit the changes to the path.
61.217 + void commit() {}
61.218 +
61.219 + ///Reserve (front) storage for the builder in advance.
61.220 +
61.221 + ///If you know a reasonable upper bound on the number of the edges
61.222 + ///to add to the front of the path,
61.223 + ///using this function you may speed up the building.
61.224 + void reserveFront(size_t) {}
61.225 + ///Reserve (back) storage for the builder in advance.
61.226 +
61.227 + ///If you know a reasonable upper bound on the number of the edges
61.228 + ///to add to the back of the path,
61.229 + ///using this function you may speed up the building.
61.230 + void reserveBack(size_t) {}
61.231 + };
61.232 + };
61.233 +
61.234 + ///@}
61.235 + }
61.236 +
61.237 +} // namespace lemon
61.238 +
61.239 +#endif // LEMON_CONCEPT_PATH_H
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/lemon/concept/sym_graph.h Mon May 23 04:48:14 2005 +0000
62.3 @@ -0,0 +1,653 @@
62.4 +/* -*- C++ -*-
62.5 + * lemon/concept/graph.h - Part of LEMON, a generic C++ optimization library
62.6 + *
62.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
62.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
62.9 + *
62.10 + * Permission to use, modify and distribute this software is granted
62.11 + * provided that this copyright notice appears in all copies. For
62.12 + * precise terms see the accompanying LICENSE file.
62.13 + *
62.14 + * This software is provided "AS IS" with no warranty of any kind,
62.15 + * express or implied, and with no claim as to its suitability for any
62.16 + * purpose.
62.17 + *
62.18 + */
62.19 +
62.20 +#ifndef LEMON_CONCEPT_SYM_GRAPH_H
62.21 +#define LEMON_CONCEPT_SYM_GRAPH_H
62.22 +
62.23 +///\ingroup concept
62.24 +///\file
62.25 +///\brief Declaration of SymGraph.
62.26 +
62.27 +#include <lemon/invalid.h>
62.28 +#include <lemon/concept/graph.h>
62.29 +#include <lemon/concept/maps.h>
62.30 +
62.31 +namespace lemon {
62.32 + namespace concept {
62.33 +
62.34 + /// \addtogroup concept
62.35 + /// @{
62.36 +
62.37 + /// An empty static graph class.
62.38 +
62.39 + /// This class provides all the common features of a symmetric
62.40 + /// graph structure, however completely without implementations and
62.41 + /// real data structures behind the interface.
62.42 + /// All graph algorithms should compile with this class, but it will not
62.43 + /// run properly, of course.
62.44 + ///
62.45 + /// It can be used for checking the interface compatibility,
62.46 + /// or it can serve as a skeleton of a new symmetric graph structure.
62.47 + ///
62.48 + /// Also, you will find here the full documentation of a certain graph
62.49 + /// feature, the documentation of a real symmetric graph imlementation
62.50 + /// like @ref SymListGraph or
62.51 + /// @ref lemon::SymSmartGraph will just refer to this structure.
62.52 + class StaticSymGraph
62.53 + {
62.54 + public:
62.55 + /// Defalult constructor.
62.56 +
62.57 + /// Defalult constructor.
62.58 + ///
62.59 + StaticSymGraph() { }
62.60 + ///Copy consructor.
62.61 +
62.62 +// ///\todo It is not clear, what we expect from a copy constructor.
62.63 +// ///E.g. How to assign the nodes/edges to each other? What about maps?
62.64 +// StaticGraph(const StaticGraph& g) { }
62.65 +
62.66 + /// The base type of node iterators,
62.67 + /// or in other words, the trivial node iterator.
62.68 +
62.69 + /// This is the base type of each node iterator,
62.70 + /// thus each kind of node iterator converts to this.
62.71 + /// More precisely each kind of node iterator should be inherited
62.72 + /// from the trivial node iterator.
62.73 + class Node {
62.74 + public:
62.75 + /// Default constructor
62.76 +
62.77 + /// @warning The default constructor sets the iterator
62.78 + /// to an undefined value.
62.79 + Node() { }
62.80 + /// Copy constructor.
62.81 +
62.82 + /// Copy constructor.
62.83 + ///
62.84 + Node(const Node&) { }
62.85 +
62.86 + /// Invalid constructor \& conversion.
62.87 +
62.88 + /// This constructor initializes the iterator to be invalid.
62.89 + /// \sa Invalid for more details.
62.90 + Node(Invalid) { }
62.91 + /// Equality operator
62.92 +
62.93 + /// Two iterators are equal if and only if they point to the
62.94 + /// same object or both are invalid.
62.95 + bool operator==(Node) const { return true; }
62.96 +
62.97 + /// Inequality operator
62.98 +
62.99 + /// \sa operator==(Node n)
62.100 + ///
62.101 + bool operator!=(Node) const { return true; }
62.102 +
62.103 + ///Comparison operator.
62.104 +
62.105 + ///This is a strict ordering between the nodes.
62.106 + ///
62.107 + ///This ordering can be different from the order in which NodeIt
62.108 + ///goes through the nodes.
62.109 + ///\todo Possibly we don't need it.
62.110 + bool operator<(Node) const { return true; }
62.111 + };
62.112 +
62.113 + /// This iterator goes through each node.
62.114 +
62.115 + /// This iterator goes through each node.
62.116 + /// Its usage is quite simple, for example you can count the number
62.117 + /// of nodes in graph \c g of type \c Graph like this:
62.118 + /// \code
62.119 + /// int count=0;
62.120 + /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
62.121 + /// \endcode
62.122 + class NodeIt : public Node {
62.123 + public:
62.124 + /// Default constructor
62.125 +
62.126 + /// @warning The default constructor sets the iterator
62.127 + /// to an undefined value.
62.128 + NodeIt() { }
62.129 + /// Copy constructor.
62.130 +
62.131 + /// Copy constructor.
62.132 + ///
62.133 + NodeIt(const NodeIt&) { }
62.134 + /// Invalid constructor \& conversion.
62.135 +
62.136 + /// Initialize the iterator to be invalid.
62.137 + /// \sa Invalid for more details.
62.138 + NodeIt(Invalid) { }
62.139 + /// Sets the iterator to the first node.
62.140 +
62.141 + /// Sets the iterator to the first node of \c g.
62.142 + ///
62.143 + NodeIt(const StaticSymGraph& g) { }
62.144 + /// Node -> NodeIt conversion.
62.145 +
62.146 + /// Sets the iterator to the node of \c g pointed by the trivial
62.147 + /// iterator n.
62.148 + /// This feature necessitates that each time we
62.149 + /// iterate the edge-set, the iteration order is the same.
62.150 + NodeIt(const StaticSymGraph& g, const Node& n) { }
62.151 + /// Next node.
62.152 +
62.153 + /// Assign the iterator to the next node.
62.154 + ///
62.155 + NodeIt& operator++() { return *this; }
62.156 + };
62.157 +
62.158 +
62.159 + /// The base type of the symmetric edge iterators.
62.160 +
62.161 + /// The base type of the symmetric edge iterators.
62.162 + ///
62.163 + class SymEdge {
62.164 + public:
62.165 + /// Default constructor
62.166 +
62.167 + /// @warning The default constructor sets the iterator
62.168 + /// to an undefined value.
62.169 + SymEdge() { }
62.170 + /// Copy constructor.
62.171 +
62.172 + /// Copy constructor.
62.173 + ///
62.174 + SymEdge(const SymEdge&) { }
62.175 + /// Initialize the iterator to be invalid.
62.176 +
62.177 + /// Initialize the iterator to be invalid.
62.178 + ///
62.179 + SymEdge(Invalid) { }
62.180 + /// Equality operator
62.181 +
62.182 + /// Two iterators are equal if and only if they point to the
62.183 + /// same object or both are invalid.
62.184 + bool operator==(SymEdge) const { return true; }
62.185 + /// Inequality operator
62.186 +
62.187 + /// \sa operator==(Node n)
62.188 + ///
62.189 + bool operator!=(SymEdge) const { return true; }
62.190 + ///Comparison operator.
62.191 +
62.192 + ///This is a strict ordering between the nodes.
62.193 + ///
62.194 + ///This ordering can be different from the order in which NodeIt
62.195 + ///goes through the nodes.
62.196 + ///\todo Possibly we don't need it.
62.197 + bool operator<(SymEdge) const { return true; }
62.198 + };
62.199 +
62.200 +
62.201 + /// The base type of the edge iterators.
62.202 +
62.203 + /// The base type of the edge iterators.
62.204 + ///
62.205 + class Edge : public SymEdge {
62.206 + public:
62.207 + /// Default constructor
62.208 +
62.209 + /// @warning The default constructor sets the iterator
62.210 + /// to an undefined value.
62.211 + Edge() { }
62.212 + /// Copy constructor.
62.213 +
62.214 + /// Copy constructor.
62.215 + ///
62.216 + Edge(const Edge&) { }
62.217 + /// Initialize the iterator to be invalid.
62.218 +
62.219 + /// Initialize the iterator to be invalid.
62.220 + ///
62.221 + Edge(Invalid) { }
62.222 + /// Equality operator
62.223 +
62.224 + /// Two iterators are equal if and only if they point to the
62.225 + /// same object or both are invalid.
62.226 + bool operator==(Edge) const { return true; }
62.227 + /// Inequality operator
62.228 +
62.229 + /// \sa operator==(Node n)
62.230 + ///
62.231 + bool operator!=(Edge) const { return true; }
62.232 + ///Comparison operator.
62.233 +
62.234 + ///This is a strict ordering between the nodes.
62.235 + ///
62.236 + ///This ordering can be different from the order in which NodeIt
62.237 + ///goes through the nodes.
62.238 + ///\todo Possibly we don't need it.
62.239 + bool operator<(Edge) const { return true; }
62.240 + };
62.241 +
62.242 + /// This iterator goes trough the outgoing edges of a node.
62.243 +
62.244 + /// This iterator goes trough the \e outgoing edges of a certain node
62.245 + /// of a graph.
62.246 + /// Its usage is quite simple, for example you can count the number
62.247 + /// of outgoing edges of a node \c n
62.248 + /// in graph \c g of type \c Graph as follows.
62.249 + /// \code
62.250 + /// int count=0;
62.251 + /// for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) ++count;
62.252 + /// \endcode
62.253 +
62.254 + class OutEdgeIt : public Edge {
62.255 + public:
62.256 + /// Default constructor
62.257 +
62.258 + /// @warning The default constructor sets the iterator
62.259 + /// to an undefined value.
62.260 + OutEdgeIt() { }
62.261 + /// Copy constructor.
62.262 +
62.263 + /// Copy constructor.
62.264 + ///
62.265 + OutEdgeIt(const OutEdgeIt&) { }
62.266 + /// Initialize the iterator to be invalid.
62.267 +
62.268 + /// Initialize the iterator to be invalid.
62.269 + ///
62.270 + OutEdgeIt(Invalid) { }
62.271 + /// This constructor sets the iterator to first outgoing edge.
62.272 +
62.273 + /// This constructor set the iterator to the first outgoing edge of
62.274 + /// node
62.275 + ///@param n the node
62.276 + ///@param g the graph
62.277 + OutEdgeIt(const StaticSymGraph& g, const Node& n) { }
62.278 + /// Edge -> OutEdgeIt conversion
62.279 +
62.280 + /// Sets the iterator to the value of the trivial iterator \c e.
62.281 + /// This feature necessitates that each time we
62.282 + /// iterate the edge-set, the iteration order is the same.
62.283 + OutEdgeIt(const StaticSymGraph& g, const Edge& e) { }
62.284 + ///Next outgoing edge
62.285 +
62.286 + /// Assign the iterator to the next
62.287 + /// outgoing edge of the corresponding node.
62.288 + OutEdgeIt& operator++() { return *this; }
62.289 + };
62.290 +
62.291 + /// This iterator goes trough the incoming edges of a node.
62.292 +
62.293 + /// This iterator goes trough the \e incoming edges of a certain node
62.294 + /// of a graph.
62.295 + /// Its usage is quite simple, for example you can count the number
62.296 + /// of outgoing edges of a node \c n
62.297 + /// in graph \c g of type \c Graph as follows.
62.298 + /// \code
62.299 + /// int count=0;
62.300 + /// for(Graph::InEdgeIt e(g, n); e!=INVALID; ++e) ++count;
62.301 + /// \endcode
62.302 +
62.303 + class InEdgeIt : public Edge {
62.304 + public:
62.305 + /// Default constructor
62.306 +
62.307 + /// @warning The default constructor sets the iterator
62.308 + /// to an undefined value.
62.309 + InEdgeIt() { }
62.310 + /// Copy constructor.
62.311 +
62.312 + /// Copy constructor.
62.313 + ///
62.314 + InEdgeIt(const InEdgeIt&) { }
62.315 + /// Initialize the iterator to be invalid.
62.316 +
62.317 + /// Initialize the iterator to be invalid.
62.318 + ///
62.319 + InEdgeIt(Invalid) { }
62.320 + /// This constructor sets the iterator to first incoming edge.
62.321 +
62.322 + /// This constructor set the iterator to the first incoming edge of
62.323 + /// node
62.324 + ///@param n the node
62.325 + ///@param g the graph
62.326 + InEdgeIt(const StaticSymGraph& g, const Node& n) { }
62.327 + /// Edge -> InEdgeIt conversion
62.328 +
62.329 + /// Sets the iterator to the value of the trivial iterator \c e.
62.330 + /// This feature necessitates that each time we
62.331 + /// iterate the edge-set, the iteration order is the same.
62.332 + InEdgeIt(const StaticSymGraph& g, const Edge& n) { }
62.333 + /// Next incoming edge
62.334 +
62.335 + /// Assign the iterator to the next inedge of the corresponding node.
62.336 + ///
62.337 + InEdgeIt& operator++() { return *this; }
62.338 + };
62.339 + /// This iterator goes through each symmetric edge.
62.340 +
62.341 + /// This iterator goes through each symmetric edge of a graph.
62.342 + /// Its usage is quite simple, for example you can count the number
62.343 + /// of symmetric edges in a graph \c g of type \c Graph as follows:
62.344 + /// \code
62.345 + /// int count=0;
62.346 + /// for(Graph::SymEdgeIt e(g); e!=INVALID; ++e) ++count;
62.347 + /// \endcode
62.348 + class SymEdgeIt : public SymEdge {
62.349 + public:
62.350 + /// Default constructor
62.351 +
62.352 + /// @warning The default constructor sets the iterator
62.353 + /// to an undefined value.
62.354 + SymEdgeIt() { }
62.355 + /// Copy constructor.
62.356 +
62.357 + /// Copy constructor.
62.358 + ///
62.359 + SymEdgeIt(const SymEdgeIt&) { }
62.360 + /// Initialize the iterator to be invalid.
62.361 +
62.362 + /// Initialize the iterator to be invalid.
62.363 + ///
62.364 + SymEdgeIt(Invalid) { }
62.365 + /// This constructor sets the iterator to first edge.
62.366 +
62.367 + /// This constructor set the iterator to the first edge of
62.368 + /// node
62.369 + ///@param g the graph
62.370 + SymEdgeIt(const StaticSymGraph& g) { }
62.371 + /// Edge -> EdgeIt conversion
62.372 +
62.373 + /// Sets the iterator to the value of the trivial iterator \c e.
62.374 + /// This feature necessitates that each time we
62.375 + /// iterate the edge-set, the iteration order is the same.
62.376 + SymEdgeIt(const StaticSymGraph&, const SymEdge&) { }
62.377 + ///Next edge
62.378 +
62.379 + /// Assign the iterator to the next
62.380 + /// edge of the corresponding node.
62.381 + SymEdgeIt& operator++() { return *this; }
62.382 + };
62.383 + /// This iterator goes through each edge.
62.384 +
62.385 + /// This iterator goes through each edge of a graph.
62.386 + /// Its usage is quite simple, for example you can count the number
62.387 + /// of edges in a graph \c g of type \c Graph as follows:
62.388 + /// \code
62.389 + /// int count=0;
62.390 + /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
62.391 + /// \endcode
62.392 + class EdgeIt : public Edge {
62.393 + public:
62.394 + /// Default constructor
62.395 +
62.396 + /// @warning The default constructor sets the iterator
62.397 + /// to an undefined value.
62.398 + EdgeIt() { }
62.399 + /// Copy constructor.
62.400 +
62.401 + /// Copy constructor.
62.402 + ///
62.403 + EdgeIt(const EdgeIt&) { }
62.404 + /// Initialize the iterator to be invalid.
62.405 +
62.406 + /// Initialize the iterator to be invalid.
62.407 + ///
62.408 + EdgeIt(Invalid) { }
62.409 + /// This constructor sets the iterator to first edge.
62.410 +
62.411 + /// This constructor set the iterator to the first edge of
62.412 + /// node
62.413 + ///@param g the graph
62.414 + EdgeIt(const StaticSymGraph& g) { }
62.415 + /// Edge -> EdgeIt conversion
62.416 +
62.417 + /// Sets the iterator to the value of the trivial iterator \c e.
62.418 + /// This feature necessitates that each time we
62.419 + /// iterate the edge-set, the iteration order is the same.
62.420 + EdgeIt(const StaticSymGraph&, const Edge&) { }
62.421 + ///Next edge
62.422 +
62.423 + /// Assign the iterator to the next
62.424 + /// edge of the corresponding node.
62.425 + EdgeIt& operator++() { return *this; }
62.426 + };
62.427 +
62.428 + /// First node of the graph.
62.429 +
62.430 + /// \retval i the first node.
62.431 + /// \return the first node.
62.432 + ///
62.433 + NodeIt& first(NodeIt& i) const { return i; }
62.434 +
62.435 + /// The first incoming edge.
62.436 +
62.437 + /// The first incoming edge.
62.438 + ///
62.439 + InEdgeIt& first(InEdgeIt &i, Node) const { return i; }
62.440 + /// The first outgoing edge.
62.441 +
62.442 + /// The first outgoing edge.
62.443 + ///
62.444 + OutEdgeIt& first(OutEdgeIt& i, Node) const { return i; }
62.445 + /// The first edge of the Graph.
62.446 +
62.447 + /// The first edge of the Graph.
62.448 + ///
62.449 + EdgeIt& first(EdgeIt& i) const { return i; }
62.450 + /// The first symmetric edge of the Graph.
62.451 +
62.452 + /// The first symmetric edge of the Graph.
62.453 + ///
62.454 + SymEdgeIt& first(SymEdgeIt& i) const { return i; }
62.455 +
62.456 + ///Gives back the target node of an edge.
62.457 +
62.458 + ///Gives back the target node of an edge.
62.459 + ///
62.460 + Node target(Edge) const { return INVALID; }
62.461 + ///Gives back the source node of an edge.
62.462 +
62.463 + ///Gives back the source node of an edge.
62.464 + ///
62.465 + Node source(Edge) const { return INVALID; }
62.466 +
62.467 + ///Gives back the first node of an symmetric edge.
62.468 +
62.469 + ///Gives back the first node of an symmetric edge.
62.470 + ///
62.471 + Node target(SymEdge) const { return INVALID; }
62.472 + ///Gives back the second node of an symmetric edge.
62.473 +
62.474 + ///Gives back the second node of an symmetric edge.
62.475 + ///
62.476 + Node source(SymEdge) const { return INVALID; }
62.477 + ///Gives back the \e id of a node.
62.478 +
62.479 + ///\warning Not all graph structures provide this feature.
62.480 + ///
62.481 + ///\todo Should each graph provide \c id?
62.482 + int id(const Node&) const { return 0; }
62.483 + ///Gives back the \e id of an edge.
62.484 +
62.485 + ///\warning Not all graph structures provide this feature.
62.486 + ///
62.487 + ///\todo Should each graph provide \c id?
62.488 + int id(const Edge&) const { return 0; }
62.489 +
62.490 + ///\warning Not all graph structures provide this feature.
62.491 + ///
62.492 + ///\todo Should each graph provide \c id?
62.493 + int id(const SymEdge&) const { return 0; }
62.494 +
62.495 + ///\e
62.496 +
62.497 + ///\todo Should it be in the concept?
62.498 + ///
62.499 + int nodeNum() const { return 0; }
62.500 + ///\e
62.501 +
62.502 + ///\todo Should it be in the concept?
62.503 + ///
62.504 + int edgeNum() const { return 0; }
62.505 +
62.506 + ///\todo Should it be in the concept?
62.507 + ///
62.508 + int symEdgeNum() const { return 0; }
62.509 +
62.510 +
62.511 + /// Gives back the forward directed edge of the symmetric edge.
62.512 + Edge forward(SymEdge) const {return INVALID;}
62.513 +
62.514 + /// Gives back the backward directed edge of the symmetric edge.
62.515 + Edge backward(SymEdge) const {return INVALID;};
62.516 +
62.517 + /// Gives back the opposite of the edge.
62.518 + Edge opposite(Edge) const {return INVALID;}
62.519 +
62.520 + ///Reference map of the nodes to type \c T.
62.521 + /// \ingroup concept
62.522 + ///Reference map of the nodes to type \c T.
62.523 + /// \sa Reference
62.524 + /// \warning Making maps that can handle bool type (NodeMap<bool>)
62.525 + /// needs some extra attention!
62.526 + template<class T> class NodeMap : public ReferenceMap< Node, T >
62.527 + {
62.528 + public:
62.529 +
62.530 + ///\e
62.531 + NodeMap(const StaticSymGraph&) { }
62.532 + ///\e
62.533 + NodeMap(const StaticSymGraph&, T) { }
62.534 +
62.535 + ///Copy constructor
62.536 + template<typename TT> NodeMap(const NodeMap<TT>&) { }
62.537 + ///Assignment operator
62.538 + template<typename TT> NodeMap& operator=(const NodeMap<TT>&)
62.539 + { return *this; }
62.540 + };
62.541 +
62.542 + ///Reference map of the edges to type \c T.
62.543 +
62.544 + /// \ingroup concept
62.545 + ///Reference map of the edges to type \c T.
62.546 + /// \sa Reference
62.547 + /// \warning Making maps that can handle bool type (EdgeMap<bool>)
62.548 + /// needs some extra attention!
62.549 + template<class T> class EdgeMap
62.550 + : public ReferenceMap<Edge,T>
62.551 + {
62.552 + public:
62.553 +
62.554 + ///\e
62.555 + EdgeMap(const StaticSymGraph&) { }
62.556 + ///\e
62.557 + EdgeMap(const StaticSymGraph&, T) { }
62.558 +
62.559 + ///Copy constructor
62.560 + template<typename TT> EdgeMap(const EdgeMap<TT>&) { }
62.561 + ///Assignment operator
62.562 + template<typename TT> EdgeMap &operator=(const EdgeMap<TT>&)
62.563 + { return *this; }
62.564 + };
62.565 +
62.566 + ///Reference map of the edges to type \c T.
62.567 +
62.568 + /// \ingroup concept
62.569 + ///Reference map of the symmetric edges to type \c T.
62.570 + /// \sa Reference
62.571 + /// \warning Making maps that can handle bool type (EdgeMap<bool>)
62.572 + /// needs some extra attention!
62.573 + template<class T> class SymEdgeMap
62.574 + : public ReferenceMap<SymEdge,T>
62.575 + {
62.576 + public:
62.577 +
62.578 + ///\e
62.579 + SymEdgeMap(const StaticSymGraph&) { }
62.580 + ///\e
62.581 + SymEdgeMap(const StaticSymGraph&, T) { }
62.582 +
62.583 + ///Copy constructor
62.584 + template<typename TT> SymEdgeMap(const SymEdgeMap<TT>&) { }
62.585 + ///Assignment operator
62.586 + template<typename TT> SymEdgeMap &operator=(const SymEdgeMap<TT>&)
62.587 + { return *this; }
62.588 + };
62.589 + };
62.590 +
62.591 +
62.592 +
62.593 + /// An empty non-static graph class.
62.594 +
62.595 + /// This class provides everything that \ref StaticGraph
62.596 + /// with additional functionality which enables to build a
62.597 + /// graph from scratch.
62.598 + class ExtendableSymGraph : public StaticSymGraph
62.599 + {
62.600 + public:
62.601 + /// Defalult constructor.
62.602 +
62.603 + /// Defalult constructor.
62.604 + ///
62.605 + ExtendableSymGraph() { }
62.606 + ///Add a new node to the graph.
62.607 +
62.608 + /// \return the new node.
62.609 + ///
62.610 + Node addNode() { return INVALID; }
62.611 + ///Add a new edge to the graph.
62.612 +
62.613 + ///Add a new symmetric edge to the graph with source node \c t
62.614 + ///and target node \c h.
62.615 + ///\return the new edge.
62.616 + SymEdge addEdge(Node h, Node t) { return INVALID; }
62.617 +
62.618 + /// Resets the graph.
62.619 +
62.620 + /// This function deletes all edges and nodes of the graph.
62.621 + /// It also frees the memory allocated to store them.
62.622 + /// \todo It might belong to \ref ErasableGraph.
62.623 + void clear() { }
62.624 + };
62.625 +
62.626 + /// An empty erasable graph class.
62.627 +
62.628 + /// This class is an extension of \ref ExtendableGraph. It also makes it
62.629 + /// possible to erase edges or nodes.
62.630 + class ErasableSymGraph : public ExtendableSymGraph
62.631 + {
62.632 + public:
62.633 + /// Defalult constructor.
62.634 +
62.635 + /// Defalult constructor.
62.636 + ///
62.637 + ErasableSymGraph() { }
62.638 + /// Deletes a node.
62.639 +
62.640 + /// Deletes node \c n node.
62.641 + ///
62.642 + void erase(Node n) { }
62.643 + /// Deletes an edge.
62.644 +
62.645 + /// Deletes edge \c e edge.
62.646 + ///
62.647 + void erase(SymEdge e) { }
62.648 + };
62.649 +
62.650 + // @}
62.651 + } //namespace concept
62.652 +} //namespace lemon
62.653 +
62.654 +
62.655 +
62.656 +#endif // LEMON_CONCEPT_GRAPH_H
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/lemon/concept/undir_graph.h Mon May 23 04:48:14 2005 +0000
63.3 @@ -0,0 +1,531 @@
63.4 +/* -*- C++ -*-
63.5 + *
63.6 + * lemon/concept/undir_graph_component.h - Part of LEMON, a generic
63.7 + * C++ optimization library
63.8 + *
63.9 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
63.10 + * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
63.11 + * EGRES).
63.12 + *
63.13 + * Permission to use, modify and distribute this software is granted
63.14 + * provided that this copyright notice appears in all copies. For
63.15 + * precise terms see the accompanying LICENSE file.
63.16 + *
63.17 + * This software is provided "AS IS" with no warranty of any kind,
63.18 + * express or implied, and with no claim as to its suitability for any
63.19 + * purpose.
63.20 + *
63.21 + */
63.22 +
63.23 +///\ingroup graph_concepts
63.24 +///\file
63.25 +///\brief Undirected graphs and components of.
63.26 +
63.27 +
63.28 +#ifndef LEMON_CONCEPT_UNDIR_GRAPH_H
63.29 +#define LEMON_CONCEPT_UNDIR_GRAPH_H
63.30 +
63.31 +#include <lemon/concept/graph_component.h>
63.32 +
63.33 +namespace lemon {
63.34 + namespace concept {
63.35 +
63.36 + /// \addtogroup graph_concepts
63.37 + /// @{
63.38 +
63.39 +
63.40 + /// Skeleton class which describes an edge with direction in \ref
63.41 + /// UndirGraph "undirected graph".
63.42 + template <typename UndirGraph>
63.43 + class UndirGraphEdge : public UndirGraph::UndirEdge {
63.44 + typedef typename UndirGraph::UndirEdge UndirEdge;
63.45 + typedef typename UndirGraph::Node Node;
63.46 + public:
63.47 +
63.48 + /// \e
63.49 + UndirGraphEdge() {}
63.50 +
63.51 + /// \e
63.52 + UndirGraphEdge(const UndirGraphEdge& e) : UndirGraph::UndirEdge(e) {}
63.53 +
63.54 + /// \e
63.55 + UndirGraphEdge(Invalid) {}
63.56 +
63.57 + /// \brief Directed edge from undirected edge and a source node.
63.58 + ///
63.59 + /// Constructs a directed edge from undirected edge and a source node.
63.60 + ///
63.61 + /// \note You have to specify the graph for this constructor.
63.62 + UndirGraphEdge(const UndirGraph &g,
63.63 + UndirEdge undir_edge, Node n) {
63.64 + ignore_unused_variable_warning(undir_edge);
63.65 + ignore_unused_variable_warning(g);
63.66 + ignore_unused_variable_warning(n);
63.67 + }
63.68 +
63.69 + /// \e
63.70 + UndirGraphEdge& operator=(UndirGraphEdge) { return *this; }
63.71 +
63.72 + /// \e
63.73 + bool operator==(UndirGraphEdge) const { return true; }
63.74 + /// \e
63.75 + bool operator!=(UndirGraphEdge) const { return false; }
63.76 +
63.77 + /// \e
63.78 + bool operator<(UndirGraphEdge) const { return false; }
63.79 +
63.80 + template <typename Edge>
63.81 + struct Constraints {
63.82 + void constraints() {
63.83 + const_constraints();
63.84 + }
63.85 + void const_constraints() const {
63.86 + /// \bug This should be is_base_and_derived ...
63.87 + UndirEdge ue = e;
63.88 + ue = e;
63.89 +
63.90 + Edge e_with_source(graph,ue,n);
63.91 + ignore_unused_variable_warning(e_with_source);
63.92 + }
63.93 + Edge e;
63.94 + UndirEdge ue;
63.95 + UndirGraph graph;
63.96 + Node n;
63.97 + };
63.98 + };
63.99 +
63.100 +
63.101 + struct BaseIterableUndirGraphConcept {
63.102 +
63.103 + template <typename Graph>
63.104 + struct Constraints {
63.105 +
63.106 + typedef typename Graph::UndirEdge UndirEdge;
63.107 + typedef typename Graph::Edge Edge;
63.108 + typedef typename Graph::Node Node;
63.109 +
63.110 + void constraints() {
63.111 + checkConcept<BaseIterableGraphComponent, Graph>();
63.112 + checkConcept<GraphItem<>, UndirEdge>();
63.113 + checkConcept<UndirGraphEdge<Graph>, Edge>();
63.114 +
63.115 + graph.first(ue);
63.116 + graph.next(ue);
63.117 +
63.118 + const_constraints();
63.119 + }
63.120 + void const_constraints() {
63.121 + Node n;
63.122 + n = graph.target(ue);
63.123 + n = graph.source(ue);
63.124 + n = graph.oppositeNode(n0, ue);
63.125 +
63.126 + bool b;
63.127 + b = graph.forward(e);
63.128 + ignore_unused_variable_warning(b);
63.129 + }
63.130 +
63.131 + Graph graph;
63.132 + Edge e;
63.133 + Node n0;
63.134 + UndirEdge ue;
63.135 + };
63.136 +
63.137 + };
63.138 +
63.139 +
63.140 + struct IterableUndirGraphConcept {
63.141 +
63.142 + template <typename Graph>
63.143 + struct Constraints {
63.144 + void constraints() {
63.145 + /// \todo we don't need the iterable component to be base iterable
63.146 + /// Don't we really???
63.147 + //checkConcept< BaseIterableUndirGraphConcept, Graph > ();
63.148 +
63.149 + checkConcept<IterableGraphComponent, Graph> ();
63.150 +
63.151 + typedef typename Graph::UndirEdge UndirEdge;
63.152 + typedef typename Graph::UndirEdgeIt UndirEdgeIt;
63.153 + typedef typename Graph::IncEdgeIt IncEdgeIt;
63.154 +
63.155 + checkConcept<GraphIterator<Graph, UndirEdge>, UndirEdgeIt>();
63.156 + checkConcept<GraphIncIterator<Graph, UndirEdge>, IncEdgeIt>();
63.157 + }
63.158 + };
63.159 +
63.160 + };
63.161 +
63.162 + struct MappableUndirGraphConcept {
63.163 +
63.164 + template <typename Graph>
63.165 + struct Constraints {
63.166 +
63.167 + struct Dummy {
63.168 + int value;
63.169 + Dummy() : value(0) {}
63.170 + Dummy(int _v) : value(_v) {}
63.171 + };
63.172 +
63.173 + void constraints() {
63.174 + checkConcept<MappableGraphComponent, Graph>();
63.175 +
63.176 + typedef typename Graph::template UndirEdgeMap<int> IntMap;
63.177 + checkConcept<GraphMap<Graph, typename Graph::UndirEdge, int>,
63.178 + IntMap >();
63.179 +
63.180 + typedef typename Graph::template UndirEdgeMap<bool> BoolMap;
63.181 + checkConcept<GraphMap<Graph, typename Graph::UndirEdge, bool>,
63.182 + BoolMap >();
63.183 +
63.184 + typedef typename Graph::template UndirEdgeMap<Dummy> DummyMap;
63.185 + checkConcept<GraphMap<Graph, typename Graph::UndirEdge, Dummy>,
63.186 + DummyMap >();
63.187 + }
63.188 + };
63.189 +
63.190 + };
63.191 +
63.192 + struct ExtendableUndirGraphConcept {
63.193 +
63.194 + template <typename Graph>
63.195 + struct Constraints {
63.196 + void constraints() {
63.197 + node_a = graph.addNode();
63.198 + uedge = graph.addEdge(node_a, node_b);
63.199 + }
63.200 + typename Graph::Node node_a, node_b;
63.201 + typename Graph::UndirEdge uedge;
63.202 + Graph graph;
63.203 + };
63.204 +
63.205 + };
63.206 +
63.207 + struct ErasableUndirGraphConcept {
63.208 +
63.209 + template <typename Graph>
63.210 + struct Constraints {
63.211 + void constraints() {
63.212 + graph.erase(n);
63.213 + graph.erase(e);
63.214 + }
63.215 + Graph graph;
63.216 + typename Graph::Node n;
63.217 + typename Graph::UndirEdge e;
63.218 + };
63.219 +
63.220 + };
63.221 +
63.222 + /// Class describing the concept of Undirected Graphs.
63.223 +
63.224 + /// This class describes the common interface of all Undirected
63.225 + /// Graphs.
63.226 + ///
63.227 + /// As all concept describing classes it provides only interface
63.228 + /// without any sensible implementation. So any algorithm for
63.229 + /// undirected graph should compile with this class, but it will not
63.230 + /// run properly, of couse.
63.231 + ///
63.232 + /// In LEMON undirected graphs also fulfill the concept of directed
63.233 + /// graphs (\ref lemon::concept::Graph "Graph Concept"). For
63.234 + /// explanation of this and more see also the page \ref undir_graphs,
63.235 + /// a tutorial about undirected graphs.
63.236 +
63.237 + class UndirGraph {
63.238 + public:
63.239 +
63.240 + /// Type describing a node in the graph
63.241 + typedef GraphNode Node;
63.242 +
63.243 + /// Type describing an undirected edge
63.244 + typedef GraphItem<'u'> UndirEdge;
63.245 +
63.246 + /// Type describing an UndirEdge with direction
63.247 +#ifndef DOXYGEN
63.248 + typedef UndirGraphEdge<UndirGraph> Edge;
63.249 +#else
63.250 + typedef UndirGraphEdge Edge;
63.251 +#endif
63.252 +
63.253 + /// Iterator type which iterates over all nodes
63.254 +#ifndef DOXYGEN
63.255 + typedef GraphIterator<UndirGraph, Node> NodeIt;
63.256 +#else
63.257 + typedef GraphIterator NodeIt;
63.258 +#endif
63.259 +
63.260 + /// Iterator type which iterates over all undirected edges
63.261 +#ifndef DOXYGEN
63.262 + typedef GraphIterator<UndirGraph, UndirEdge> UndirEdgeIt;
63.263 +#else
63.264 + typedef GraphIterator UndirEdgeIt;
63.265 +#endif
63.266 +
63.267 + /// Iterator type which iterates over all directed edges.
63.268 +
63.269 + /// Iterator type which iterates over all edges (each undirected
63.270 + /// edge occurs twice with both directions.
63.271 +#ifndef DOXYGEN
63.272 + typedef GraphIterator<UndirGraph, Edge> EdgeIt;
63.273 +#else
63.274 + typedef GraphIterator EdgeIt;
63.275 +#endif
63.276 +
63.277 +
63.278 + /// Iterator of undirected edges incident to a node
63.279 +#ifndef DOXYGEN
63.280 + typedef GraphIncIterator<UndirGraph, UndirEdge, 'u'> IncEdgeIt;
63.281 +#else
63.282 + typedef GraphIncIterator IncEdgeIt;
63.283 +#endif
63.284 +
63.285 + /// Iterator of edges incoming to a node
63.286 +#ifndef DOXYGEN
63.287 + typedef GraphIncIterator<UndirGraph, Edge, 'i'> InEdgeIt;
63.288 +#else
63.289 + typedef GraphIncIterator InEdgeIt;
63.290 +#endif
63.291 +
63.292 + /// Iterator of edges outgoing from a node
63.293 +#ifndef DOXYGEN
63.294 + typedef GraphIncIterator<UndirGraph, Edge, 'o'> OutEdgeIt;
63.295 +#else
63.296 + typedef GraphIncIterator OutEdgeIt;
63.297 +#endif
63.298 +
63.299 + /// NodeMap template
63.300 +#ifdef DOXYGEN
63.301 + typedef GraphMap NodeMap<T>;
63.302 +#endif
63.303 +
63.304 + /// UndirEdgeMap template
63.305 +#ifdef DOXYGEN
63.306 + typedef GraphMap UndirEdgeMap<T>;
63.307 +#endif
63.308 +
63.309 + /// EdgeMap template
63.310 +#ifdef DOXYGEN
63.311 + typedef GraphMap EdgeMap<T>;
63.312 +#endif
63.313 +
63.314 + template <typename T>
63.315 + class NodeMap : public GraphMap<UndirGraph, Node, T> {
63.316 + typedef GraphMap<UndirGraph, Node, T> Parent;
63.317 + public:
63.318 +
63.319 + explicit NodeMap(const UndirGraph &g) : Parent(g) {}
63.320 + NodeMap(const UndirGraph &g, T t) : Parent(g, t) {}
63.321 + };
63.322 +
63.323 + template <typename T>
63.324 + class UndirEdgeMap : public GraphMap<UndirGraph, UndirEdge, T> {
63.325 + typedef GraphMap<UndirGraph, UndirEdge, T> Parent;
63.326 + public:
63.327 +
63.328 + explicit UndirEdgeMap(const UndirGraph &g) : Parent(g) {}
63.329 + UndirEdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
63.330 + };
63.331 +
63.332 + template <typename T>
63.333 + class EdgeMap : public GraphMap<UndirGraph, Edge, T> {
63.334 + typedef GraphMap<UndirGraph, Edge, T> Parent;
63.335 + public:
63.336 +
63.337 + explicit EdgeMap(const UndirGraph &g) : Parent(g) {}
63.338 + EdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
63.339 + };
63.340 +
63.341 + /// Is the Edge oriented "forward"?
63.342 +
63.343 + /// Returns whether the given directed edge is same orientation as
63.344 + /// the corresponding undirected edge.
63.345 + ///
63.346 + /// \todo "What does the direction of an undirected edge mean?"
63.347 + bool forward(Edge) const { return true; }
63.348 +
63.349 + /// Opposite node on an edge
63.350 +
63.351 + /// \return the opposite of the given Node on the given Edge
63.352 + ///
63.353 + /// \todo What should we do if given Node and Edge are not incident?
63.354 + Node oppositeNode(Node, UndirEdge) const { return INVALID; }
63.355 +
63.356 + /// First node of the undirected edge.
63.357 +
63.358 + /// \return the first node of the given UndirEdge.
63.359 + ///
63.360 + /// Naturally undirectected edges don't have direction and thus
63.361 + /// don't have source and target node. But we use these two methods
63.362 + /// to query the two endnodes of the edge. The direction of the edge
63.363 + /// which arises this way is called the inherent direction of the
63.364 + /// undirected edge, and is used to define the "forward" direction
63.365 + /// of the directed versions of the edges.
63.366 + /// \sa forward
63.367 + Node source(UndirEdge) const { return INVALID; }
63.368 +
63.369 + /// Second node of the undirected edge.
63.370 + Node target(UndirEdge) const { return INVALID; }
63.371 +
63.372 + /// Source node of the directed edge.
63.373 + Node source(Edge) const { return INVALID; }
63.374 +
63.375 + /// Target node of the directed edge.
63.376 + Node target(Edge) const { return INVALID; }
63.377 +
63.378 + /// First node of the graph
63.379 +
63.380 + /// \note This method is part of so called \ref
63.381 + /// developpers_interface "Developpers' interface", so it shouldn't
63.382 + /// be used in an end-user program.
63.383 + void first(Node&) const {}
63.384 + /// Next node of the graph
63.385 +
63.386 + /// \note This method is part of so called \ref
63.387 + /// developpers_interface "Developpers' interface", so it shouldn't
63.388 + /// be used in an end-user program.
63.389 + void next(Node&) const {}
63.390 +
63.391 + /// First undirected edge of the graph
63.392 +
63.393 + /// \note This method is part of so called \ref
63.394 + /// developpers_interface "Developpers' interface", so it shouldn't
63.395 + /// be used in an end-user program.
63.396 + void first(UndirEdge&) const {}
63.397 + /// Next undirected edge of the graph
63.398 +
63.399 + /// \note This method is part of so called \ref
63.400 + /// developpers_interface "Developpers' interface", so it shouldn't
63.401 + /// be used in an end-user program.
63.402 + void next(UndirEdge&) const {}
63.403 +
63.404 + /// First directed edge of the graph
63.405 +
63.406 + /// \note This method is part of so called \ref
63.407 + /// developpers_interface "Developpers' interface", so it shouldn't
63.408 + /// be used in an end-user program.
63.409 + void first(Edge&) const {}
63.410 + /// Next directed edge of the graph
63.411 +
63.412 + /// \note This method is part of so called \ref
63.413 + /// developpers_interface "Developpers' interface", so it shouldn't
63.414 + /// be used in an end-user program.
63.415 + void next(Edge&) const {}
63.416 +
63.417 + /// First outgoing edge from a given node
63.418 +
63.419 + /// \note This method is part of so called \ref
63.420 + /// developpers_interface "Developpers' interface", so it shouldn't
63.421 + /// be used in an end-user program.
63.422 + void firstOut(Edge&, Node) const {}
63.423 + /// Next outgoing edge to a node
63.424 +
63.425 + /// \note This method is part of so called \ref
63.426 + /// developpers_interface "Developpers' interface", so it shouldn't
63.427 + /// be used in an end-user program.
63.428 + void nextOut(Edge&) const {}
63.429 +
63.430 + /// First incoming edge to a given node
63.431 +
63.432 + /// \note This method is part of so called \ref
63.433 + /// developpers_interface "Developpers' interface", so it shouldn't
63.434 + /// be used in an end-user program.
63.435 + void firstIn(Edge&, Node) const {}
63.436 + /// Next incoming edge to a node
63.437 +
63.438 + /// \note This method is part of so called \ref
63.439 + /// developpers_interface "Developpers' interface", so it shouldn't
63.440 + /// be used in an end-user program.
63.441 + void nextIn(Edge&) const {}
63.442 +
63.443 +
63.444 + /// Base node of the iterator
63.445 + ///
63.446 + /// Returns the base node (the source in this case) of the iterator
63.447 + Node baseNode(OutEdgeIt e) const {
63.448 + return source(e);
63.449 + }
63.450 + /// Running node of the iterator
63.451 + ///
63.452 + /// Returns the running node (the target in this case) of the
63.453 + /// iterator
63.454 + Node runningNode(OutEdgeIt e) const {
63.455 + return target(e);
63.456 + }
63.457 +
63.458 + /// Base node of the iterator
63.459 + ///
63.460 + /// Returns the base node (the target in this case) of the iterator
63.461 + Node baseNode(InEdgeIt e) const {
63.462 + return target(e);
63.463 + }
63.464 + /// Running node of the iterator
63.465 + ///
63.466 + /// Returns the running node (the source in this case) of the
63.467 + /// iterator
63.468 + Node runningNode(InEdgeIt e) const {
63.469 + return source(e);
63.470 + }
63.471 +
63.472 + /// Base node of the iterator
63.473 + ///
63.474 + /// Returns the base node of the iterator
63.475 + Node baseNode(IncEdgeIt) const {
63.476 + return INVALID;
63.477 + }
63.478 + /// Running node of the iterator
63.479 + ///
63.480 + /// Returns the running node of the iterator
63.481 + Node runningNode(IncEdgeIt) const {
63.482 + return INVALID;
63.483 + }
63.484 +
63.485 +
63.486 + template <typename Graph>
63.487 + struct Constraints {
63.488 + void constraints() {
63.489 + checkConcept<BaseIterableUndirGraphConcept, Graph>();
63.490 + checkConcept<IterableUndirGraphConcept, Graph>();
63.491 + checkConcept<MappableUndirGraphConcept, Graph>();
63.492 + }
63.493 + };
63.494 +
63.495 + };
63.496 +
63.497 + class ExtendableUndirGraph : public UndirGraph {
63.498 + public:
63.499 +
63.500 + template <typename Graph>
63.501 + struct Constraints {
63.502 + void constraints() {
63.503 + checkConcept<BaseIterableUndirGraphConcept, Graph>();
63.504 + checkConcept<IterableUndirGraphConcept, Graph>();
63.505 + checkConcept<MappableUndirGraphConcept, Graph>();
63.506 +
63.507 + checkConcept<UndirGraph, Graph>();
63.508 + checkConcept<ExtendableUndirGraphConcept, Graph>();
63.509 + checkConcept<ClearableGraphComponent, Graph>();
63.510 + }
63.511 + };
63.512 +
63.513 + };
63.514 +
63.515 + class ErasableUndirGraph : public ExtendableUndirGraph {
63.516 + public:
63.517 +
63.518 + template <typename Graph>
63.519 + struct Constraints {
63.520 + void constraints() {
63.521 + checkConcept<ExtendableUndirGraph, Graph>();
63.522 + checkConcept<ErasableUndirGraphConcept, Graph>();
63.523 + }
63.524 + };
63.525 +
63.526 + };
63.527 +
63.528 + /// @}
63.529 +
63.530 + }
63.531 +
63.532 +}
63.533 +
63.534 +#endif
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/lemon/concept_check.h Mon May 23 04:48:14 2005 +0000
64.3 @@ -0,0 +1,89 @@
64.4 +// -*- C++ -*-
64.5 +// Modified for use in LEMON.
64.6 +// We should really consider using Boost...
64.7 +
64.8 +
64.9 +//
64.10 +// (C) Copyright Jeremy Siek 2000.
64.11 +// Distributed under the Boost Software License, Version 1.0. (See
64.12 +// accompanying file LICENSE_1_0.txt or copy at
64.13 +// http://www.boost.org/LICENSE_1_0.txt)
64.14 +//
64.15 +// Revision History:
64.16 +// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
64.17 +// 02 April 2001: Removed limits header altogether. (Jeremy Siek)
64.18 +// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
64.19 +//
64.20 +
64.21 +// See http://www.boost.org/libs/concept_check for documentation.
64.22 +
64.23 +#ifndef LEMON_BOOST_CONCEPT_CHECKS_HPP
64.24 +#define LEMON_BOOST_CONCEPT_CHECKS_HPP
64.25 +
64.26 +namespace lemon {
64.27 +
64.28 + /*
64.29 + "inline" is used for ignore_unused_variable_warning()
64.30 + and function_requires() to make sure there is no
64.31 + overtarget with g++.
64.32 + */
64.33 +
64.34 + template <class T> inline void ignore_unused_variable_warning(const T&) { }
64.35 +
64.36 + template <class Concept>
64.37 + inline void function_requires()
64.38 + {
64.39 +#if !defined(NDEBUG)
64.40 + void (Concept::*x)() = & Concept::constraints;
64.41 + ignore_unused_variable_warning(x);
64.42 +#endif
64.43 + }
64.44 +
64.45 + template <typename Concept, typename Type>
64.46 + inline void checkConcept() {
64.47 +#if !defined(NDEBUG)
64.48 + typedef typename Concept::template Constraints<Type> ConceptCheck;
64.49 + void (ConceptCheck::*x)() = & ConceptCheck::constraints;
64.50 + ignore_unused_variable_warning(x);
64.51 +#endif
64.52 + }
64.53 +
64.54 +#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
64.55 + typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
64.56 + template <func##type_var##concept Tp1_> \
64.57 + struct concept_checking_##type_var##concept { }; \
64.58 + typedef concept_checking_##type_var##concept< \
64.59 + BOOST_FPTR ns::concept<type_var>::constraints> \
64.60 + concept_checking_typedef_##type_var##concept
64.61 +
64.62 +#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
64.63 + typedef void (ns::concept <type_var1,type_var2>::* \
64.64 + func##type_var1##type_var2##concept)(); \
64.65 + template <func##type_var1##type_var2##concept Tp1_> \
64.66 + struct concept_checking_##type_var1##type_var2##concept { }; \
64.67 + typedef concept_checking_##type_var1##type_var2##concept< \
64.68 + BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
64.69 + concept_checking_typedef_##type_var1##type_var2##concept
64.70 +
64.71 +#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
64.72 + typedef void (ns::concept <tv1,tv2,tv3>::* \
64.73 + func##tv1##tv2##tv3##concept)(); \
64.74 + template <func##tv1##tv2##tv3##concept Tp1_> \
64.75 + struct concept_checking_##tv1##tv2##tv3##concept { }; \
64.76 + typedef concept_checking_##tv1##tv2##tv3##concept< \
64.77 + BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
64.78 + concept_checking_typedef_##tv1##tv2##tv3##concept
64.79 +
64.80 +#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
64.81 + typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
64.82 + func##tv1##tv2##tv3##tv4##concept)(); \
64.83 + template <func##tv1##tv2##tv3##tv4##concept Tp1_> \
64.84 + struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
64.85 + typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
64.86 + BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
64.87 + concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
64.88 +
64.89 +
64.90 +} // namespace lemon
64.91 +
64.92 +#endif // LEMON_BOOST_CONCEPT_CHECKS_HPP
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/lemon/config.h.in Mon May 23 04:48:14 2005 +0000
65.3 @@ -0,0 +1,5 @@
65.4 +/* Define to 1 if you have CPLEX. */
65.5 +#undef HAVE_CPLEX
65.6 +
65.7 +/* Define to 1 if you have GLPK. */
65.8 +#undef HAVE_GLPK
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/lemon/dfs.h Mon May 23 04:48:14 2005 +0000
66.3 @@ -0,0 +1,1136 @@
66.4 +/* -*- C++ -*-
66.5 + * lemon/dfs.h - Part of LEMON, a generic C++ optimization library
66.6 + *
66.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
66.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
66.9 + *
66.10 + * Permission to use, modify and distribute this software is granted
66.11 + * provided that this copyright notice appears in all copies. For
66.12 + * precise terms see the accompanying LICENSE file.
66.13 + *
66.14 + * This software is provided "AS IS" with no warranty of any kind,
66.15 + * express or implied, and with no claim as to its suitability for any
66.16 + * purpose.
66.17 + *
66.18 + */
66.19 +
66.20 +#ifndef LEMON_DFS_H
66.21 +#define LEMON_DFS_H
66.22 +
66.23 +///\ingroup flowalgs
66.24 +///\file
66.25 +///\brief Dfs algorithm.
66.26 +
66.27 +#include <lemon/list_graph.h>
66.28 +#include <lemon/graph_utils.h>
66.29 +#include <lemon/invalid.h>
66.30 +#include <lemon/error.h>
66.31 +#include <lemon/maps.h>
66.32 +
66.33 +namespace lemon {
66.34 +
66.35 +
66.36 +
66.37 + ///Default traits class of Dfs class.
66.38 +
66.39 + ///Default traits class of Dfs class.
66.40 + ///\param GR Graph type.
66.41 + template<class GR>
66.42 + struct DfsDefaultTraits
66.43 + {
66.44 + ///The graph type the algorithm runs on.
66.45 + typedef GR Graph;
66.46 + ///\brief The type of the map that stores the last
66.47 + ///edges of the %DFS paths.
66.48 + ///
66.49 + ///The type of the map that stores the last
66.50 + ///edges of the %DFS paths.
66.51 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.52 + ///
66.53 + typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
66.54 + ///Instantiates a PredMap.
66.55 +
66.56 + ///This function instantiates a \ref PredMap.
66.57 + ///\param G is the graph, to which we would like to define the PredMap.
66.58 + ///\todo The graph alone may be insufficient to initialize
66.59 + static PredMap *createPredMap(const GR &G)
66.60 + {
66.61 + return new PredMap(G);
66.62 + }
66.63 +// ///\brief The type of the map that stores the last but one
66.64 +// ///nodes of the %DFS paths.
66.65 +// ///
66.66 +// ///The type of the map that stores the last but one
66.67 +// ///nodes of the %DFS paths.
66.68 +// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.69 +// ///
66.70 +// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
66.71 +// ///Instantiates a PredNodeMap.
66.72 +
66.73 +// ///This function instantiates a \ref PredNodeMap.
66.74 +// ///\param G is the graph, to which
66.75 +// ///we would like to define the \ref PredNodeMap
66.76 +// static PredNodeMap *createPredNodeMap(const GR &G)
66.77 +// {
66.78 +// return new PredNodeMap();
66.79 +// }
66.80 +
66.81 + ///The type of the map that indicates which nodes are processed.
66.82 +
66.83 + ///The type of the map that indicates which nodes are processed.
66.84 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.85 + ///\todo named parameter to set this type, function to read and write.
66.86 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
66.87 + ///Instantiates a ProcessedMap.
66.88 +
66.89 + ///This function instantiates a \ref ProcessedMap.
66.90 + ///\param G is the graph, to which
66.91 + ///we would like to define the \ref ProcessedMap
66.92 + static ProcessedMap *createProcessedMap(const GR &)
66.93 + {
66.94 + return new ProcessedMap();
66.95 + }
66.96 + ///The type of the map that indicates which nodes are reached.
66.97 +
66.98 + ///The type of the map that indicates which nodes are reached.
66.99 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.100 + ///\todo named parameter to set this type, function to read and write.
66.101 + typedef typename Graph::template NodeMap<bool> ReachedMap;
66.102 + ///Instantiates a ReachedMap.
66.103 +
66.104 + ///This function instantiates a \ref ReachedMap.
66.105 + ///\param G is the graph, to which
66.106 + ///we would like to define the \ref ReachedMap.
66.107 + static ReachedMap *createReachedMap(const GR &G)
66.108 + {
66.109 + return new ReachedMap(G);
66.110 + }
66.111 + ///The type of the map that stores the dists of the nodes.
66.112 +
66.113 + ///The type of the map that stores the dists of the nodes.
66.114 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.115 + ///
66.116 + typedef typename Graph::template NodeMap<int> DistMap;
66.117 + ///Instantiates a DistMap.
66.118 +
66.119 + ///This function instantiates a \ref DistMap.
66.120 + ///\param G is the graph, to which we would like to define the \ref DistMap
66.121 + static DistMap *createDistMap(const GR &G)
66.122 + {
66.123 + return new DistMap(G);
66.124 + }
66.125 + };
66.126 +
66.127 + ///%DFS algorithm class.
66.128 +
66.129 + ///\ingroup flowalgs
66.130 + ///This class provides an efficient implementation of the %DFS algorithm.
66.131 + ///
66.132 + ///\param GR The graph type the algorithm runs on. The default value is
66.133 + ///\ref ListGraph. The value of GR is not used directly by Dfs, it
66.134 + ///is only passed to \ref DfsDefaultTraits.
66.135 + ///\param TR Traits class to set various data types used by the algorithm.
66.136 + ///The default traits class is
66.137 + ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
66.138 + ///See \ref DfsDefaultTraits for the documentation of
66.139 + ///a Dfs traits class.
66.140 + ///
66.141 + ///\author Jacint Szabo and Alpar Juttner
66.142 + ///\todo A compare object would be nice.
66.143 +
66.144 +#ifdef DOXYGEN
66.145 + template <typename GR,
66.146 + typename TR>
66.147 +#else
66.148 + template <typename GR=ListGraph,
66.149 + typename TR=DfsDefaultTraits<GR> >
66.150 +#endif
66.151 + class Dfs {
66.152 + public:
66.153 + /**
66.154 + * \brief \ref Exception for uninitialized parameters.
66.155 + *
66.156 + * This error represents problems in the initialization
66.157 + * of the parameters of the algorithms.
66.158 + */
66.159 + class UninitializedParameter : public lemon::UninitializedParameter {
66.160 + public:
66.161 + virtual const char* exceptionName() const {
66.162 + return "lemon::Dfs::UninitializedParameter";
66.163 + }
66.164 + };
66.165 +
66.166 + typedef TR Traits;
66.167 + ///The type of the underlying graph.
66.168 + typedef typename TR::Graph Graph;
66.169 + ///\e
66.170 + typedef typename Graph::Node Node;
66.171 + ///\e
66.172 + typedef typename Graph::NodeIt NodeIt;
66.173 + ///\e
66.174 + typedef typename Graph::Edge Edge;
66.175 + ///\e
66.176 + typedef typename Graph::OutEdgeIt OutEdgeIt;
66.177 +
66.178 + ///\brief The type of the map that stores the last
66.179 + ///edges of the %DFS paths.
66.180 + typedef typename TR::PredMap PredMap;
66.181 +// ///\brief The type of the map that stores the last but one
66.182 +// ///nodes of the %DFS paths.
66.183 +// typedef typename TR::PredNodeMap PredNodeMap;
66.184 + ///The type of the map indicating which nodes are reached.
66.185 + typedef typename TR::ReachedMap ReachedMap;
66.186 + ///The type of the map indicating which nodes are processed.
66.187 + typedef typename TR::ProcessedMap ProcessedMap;
66.188 + ///The type of the map that stores the dists of the nodes.
66.189 + typedef typename TR::DistMap DistMap;
66.190 + private:
66.191 + /// Pointer to the underlying graph.
66.192 + const Graph *G;
66.193 + ///Pointer to the map of predecessors edges.
66.194 + PredMap *_pred;
66.195 + ///Indicates if \ref _pred is locally allocated (\c true) or not.
66.196 + bool local_pred;
66.197 +// ///Pointer to the map of predecessors nodes.
66.198 +// PredNodeMap *_predNode;
66.199 +// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
66.200 +// bool local_predNode;
66.201 + ///Pointer to the map of distances.
66.202 + DistMap *_dist;
66.203 + ///Indicates if \ref _dist is locally allocated (\c true) or not.
66.204 + bool local_dist;
66.205 + ///Pointer to the map of reached status of the nodes.
66.206 + ReachedMap *_reached;
66.207 + ///Indicates if \ref _reached is locally allocated (\c true) or not.
66.208 + bool local_reached;
66.209 + ///Pointer to the map of processed status of the nodes.
66.210 + ProcessedMap *_processed;
66.211 + ///Indicates if \ref _processed is locally allocated (\c true) or not.
66.212 + bool local_processed;
66.213 +
66.214 + std::vector<typename Graph::OutEdgeIt> _stack;
66.215 + int _stack_head;
66.216 +// ///The source node of the last execution.
66.217 +// Node source;
66.218 +
66.219 + ///Creates the maps if necessary.
66.220 +
66.221 + ///\todo Error if \c G are \c NULL.
66.222 + ///\todo Better memory allocation (instead of new).
66.223 + void create_maps()
66.224 + {
66.225 + if(!_pred) {
66.226 + local_pred = true;
66.227 + _pred = Traits::createPredMap(*G);
66.228 + }
66.229 +// if(!_predNode) {
66.230 +// local_predNode = true;
66.231 +// _predNode = Traits::createPredNodeMap(*G);
66.232 +// }
66.233 + if(!_dist) {
66.234 + local_dist = true;
66.235 + _dist = Traits::createDistMap(*G);
66.236 + }
66.237 + if(!_reached) {
66.238 + local_reached = true;
66.239 + _reached = Traits::createReachedMap(*G);
66.240 + }
66.241 + if(!_processed) {
66.242 + local_processed = true;
66.243 + _processed = Traits::createProcessedMap(*G);
66.244 + }
66.245 + }
66.246 +
66.247 + public :
66.248 +
66.249 + ///\name Named template parameters
66.250 +
66.251 + ///@{
66.252 +
66.253 + template <class T>
66.254 + struct DefPredMapTraits : public Traits {
66.255 + typedef T PredMap;
66.256 + static PredMap *createPredMap(const Graph &G)
66.257 + {
66.258 + throw UninitializedParameter();
66.259 + }
66.260 + };
66.261 + ///\ref named-templ-param "Named parameter" for setting PredMap type
66.262 +
66.263 + ///\ref named-templ-param "Named parameter" for setting PredMap type
66.264 + ///
66.265 + template <class T>
66.266 + class DefPredMap : public Dfs< Graph,
66.267 + DefPredMapTraits<T> > { };
66.268 +
66.269 +// template <class T>
66.270 +// struct DefPredNodeMapTraits : public Traits {
66.271 +// typedef T PredNodeMap;
66.272 +// static PredNodeMap *createPredNodeMap(const Graph &G)
66.273 +// {
66.274 +// throw UninitializedParameter();
66.275 +// }
66.276 +// };
66.277 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
66.278 +
66.279 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
66.280 +// ///
66.281 +// template <class T>
66.282 +// class DefPredNodeMap : public Dfs< Graph,
66.283 +// LengthMap,
66.284 +// DefPredNodeMapTraits<T> > { };
66.285 +
66.286 + template <class T>
66.287 + struct DefDistMapTraits : public Traits {
66.288 + typedef T DistMap;
66.289 + static DistMap *createDistMap(const Graph &G)
66.290 + {
66.291 + throw UninitializedParameter();
66.292 + }
66.293 + };
66.294 + ///\ref named-templ-param "Named parameter" for setting DistMap type
66.295 +
66.296 + ///\ref named-templ-param "Named parameter" for setting DistMap type
66.297 + ///
66.298 + template <class T>
66.299 + class DefDistMap : public Dfs< Graph,
66.300 + DefDistMapTraits<T> > { };
66.301 +
66.302 + template <class T>
66.303 + struct DefReachedMapTraits : public Traits {
66.304 + typedef T ReachedMap;
66.305 + static ReachedMap *createReachedMap(const Graph &G)
66.306 + {
66.307 + throw UninitializedParameter();
66.308 + }
66.309 + };
66.310 + ///\ref named-templ-param "Named parameter" for setting ReachedMap type
66.311 +
66.312 + ///\ref named-templ-param "Named parameter" for setting ReachedMap type
66.313 + ///
66.314 + template <class T>
66.315 + class DefReachedMap : public Dfs< Graph,
66.316 + DefReachedMapTraits<T> > { };
66.317 +
66.318 + struct DefGraphReachedMapTraits : public Traits {
66.319 + typedef typename Graph::template NodeMap<bool> ReachedMap;
66.320 + static ReachedMap *createReachedMap(const Graph &G)
66.321 + {
66.322 + return new ReachedMap(G);
66.323 + }
66.324 + };
66.325 + template <class T>
66.326 + struct DefProcessedMapTraits : public Traits {
66.327 + typedef T ProcessedMap;
66.328 + static ProcessedMap *createProcessedMap(const Graph &G)
66.329 + {
66.330 + throw UninitializedParameter();
66.331 + }
66.332 + };
66.333 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
66.334 +
66.335 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
66.336 + ///
66.337 + template <class T>
66.338 + class DefProcessedMap : public Dfs< Graph,
66.339 + DefProcessedMapTraits<T> > { };
66.340 +
66.341 + struct DefGraphProcessedMapTraits : public Traits {
66.342 + typedef typename Graph::template NodeMap<bool> ProcessedMap;
66.343 + static ProcessedMap *createProcessedMap(const Graph &G)
66.344 + {
66.345 + return new ProcessedMap(G);
66.346 + }
66.347 + };
66.348 + ///\brief \ref named-templ-param "Named parameter"
66.349 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
66.350 + ///
66.351 + ///\ref named-templ-param "Named parameter"
66.352 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
66.353 + ///If you don't set it explicitely, it will be automatically allocated.
66.354 + template <class T>
66.355 + class DefProcessedMapToBeDefaultMap :
66.356 + public Dfs< Graph,
66.357 + DefGraphProcessedMapTraits> { };
66.358 +
66.359 + ///@}
66.360 +
66.361 + public:
66.362 +
66.363 + ///Constructor.
66.364 +
66.365 + ///\param _G the graph the algorithm will run on.
66.366 + ///
66.367 + Dfs(const Graph& _G) :
66.368 + G(&_G),
66.369 + _pred(NULL), local_pred(false),
66.370 +// _predNode(NULL), local_predNode(false),
66.371 + _dist(NULL), local_dist(false),
66.372 + _reached(NULL), local_reached(false),
66.373 + _processed(NULL), local_processed(false)
66.374 + { }
66.375 +
66.376 + ///Destructor.
66.377 + ~Dfs()
66.378 + {
66.379 + if(local_pred) delete _pred;
66.380 +// if(local_predNode) delete _predNode;
66.381 + if(local_dist) delete _dist;
66.382 + if(local_reached) delete _reached;
66.383 + if(local_processed) delete _processed;
66.384 + }
66.385 +
66.386 + ///Sets the map storing the predecessor edges.
66.387 +
66.388 + ///Sets the map storing the predecessor edges.
66.389 + ///If you don't use this function before calling \ref run(),
66.390 + ///it will allocate one. The destuctor deallocates this
66.391 + ///automatically allocated map, of course.
66.392 + ///\return <tt> (*this) </tt>
66.393 + Dfs &predMap(PredMap &m)
66.394 + {
66.395 + if(local_pred) {
66.396 + delete _pred;
66.397 + local_pred=false;
66.398 + }
66.399 + _pred = &m;
66.400 + return *this;
66.401 + }
66.402 +
66.403 +// ///Sets the map storing the predecessor nodes.
66.404 +
66.405 +// ///Sets the map storing the predecessor nodes.
66.406 +// ///If you don't use this function before calling \ref run(),
66.407 +// ///it will allocate one. The destuctor deallocates this
66.408 +// ///automatically allocated map, of course.
66.409 +// ///\return <tt> (*this) </tt>
66.410 +// Dfs &predNodeMap(PredNodeMap &m)
66.411 +// {
66.412 +// if(local_predNode) {
66.413 +// delete _predNode;
66.414 +// local_predNode=false;
66.415 +// }
66.416 +// _predNode = &m;
66.417 +// return *this;
66.418 +// }
66.419 +
66.420 + ///Sets the map storing the distances calculated by the algorithm.
66.421 +
66.422 + ///Sets the map storing the distances calculated by the algorithm.
66.423 + ///If you don't use this function before calling \ref run(),
66.424 + ///it will allocate one. The destuctor deallocates this
66.425 + ///automatically allocated map, of course.
66.426 + ///\return <tt> (*this) </tt>
66.427 + Dfs &distMap(DistMap &m)
66.428 + {
66.429 + if(local_dist) {
66.430 + delete _dist;
66.431 + local_dist=false;
66.432 + }
66.433 + _dist = &m;
66.434 + return *this;
66.435 + }
66.436 +
66.437 + ///Sets the map indicating if a node is reached.
66.438 +
66.439 + ///Sets the map indicating if a node is reached.
66.440 + ///If you don't use this function before calling \ref run(),
66.441 + ///it will allocate one. The destuctor deallocates this
66.442 + ///automatically allocated map, of course.
66.443 + ///\return <tt> (*this) </tt>
66.444 + Dfs &reachedMap(ReachedMap &m)
66.445 + {
66.446 + if(local_reached) {
66.447 + delete _reached;
66.448 + local_reached=false;
66.449 + }
66.450 + _reached = &m;
66.451 + return *this;
66.452 + }
66.453 +
66.454 + ///Sets the map indicating if a node is processed.
66.455 +
66.456 + ///Sets the map indicating if a node is processed.
66.457 + ///If you don't use this function before calling \ref run(),
66.458 + ///it will allocate one. The destuctor deallocates this
66.459 + ///automatically allocated map, of course.
66.460 + ///\return <tt> (*this) </tt>
66.461 + Dfs &processedMap(ProcessedMap &m)
66.462 + {
66.463 + if(local_processed) {
66.464 + delete _processed;
66.465 + local_processed=false;
66.466 + }
66.467 + _processed = &m;
66.468 + return *this;
66.469 + }
66.470 +
66.471 + public:
66.472 + ///\name Execution control
66.473 + ///The simplest way to execute the algorithm is to use
66.474 + ///one of the member functions called \c run(...).
66.475 + ///\n
66.476 + ///If you need more control on the execution,
66.477 + ///first you must call \ref init(), then you can add several source nodes
66.478 + ///with \ref addSource().
66.479 + ///Finally \ref start() will perform the actual path
66.480 + ///computation.
66.481 +
66.482 + ///@{
66.483 +
66.484 + ///Initializes the internal data structures.
66.485 +
66.486 + ///Initializes the internal data structures.
66.487 + ///
66.488 + void init()
66.489 + {
66.490 + create_maps();
66.491 + _stack.resize(countNodes(*G));
66.492 + _stack_head=-1;
66.493 + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
66.494 + _pred->set(u,INVALID);
66.495 + // _predNode->set(u,INVALID);
66.496 + _reached->set(u,false);
66.497 + _processed->set(u,false);
66.498 + }
66.499 + }
66.500 +
66.501 + ///Adds a new source node.
66.502 +
66.503 + ///Adds a new source node to the set of nodes to be processed.
66.504 + ///
66.505 + ///\bug dist's are wrong (or at least strange) in case of multiple sources.
66.506 + void addSource(Node s)
66.507 + {
66.508 + if(!(*_reached)[s])
66.509 + {
66.510 + _reached->set(s,true);
66.511 + _pred->set(s,INVALID);
66.512 + // _predNode->set(u,INVALID);
66.513 + _stack[++_stack_head]=OutEdgeIt(*G,s);
66.514 + _dist->set(s,_stack_head);
66.515 + }
66.516 + }
66.517 +
66.518 + ///Processes the next node.
66.519 +
66.520 + ///Processes the next node.
66.521 + ///
66.522 + ///\warning The stack must not be empty!
66.523 + void processNextEdge()
66.524 + {
66.525 + Node m;
66.526 + Edge e=_stack[_stack_head];
66.527 + if(!(*_reached)[m=G->target(e)]) {
66.528 + _pred->set(m,e);
66.529 + _reached->set(m,true);
66.530 + // _pred_node->set(m,G->source(e));
66.531 + ++_stack_head;
66.532 + _stack[_stack_head] = OutEdgeIt(*G, m);
66.533 + _dist->set(m,_stack_head);
66.534 + }
66.535 + else {
66.536 + Node n;
66.537 + while(_stack_head>=0 &&
66.538 + (n=G->source(_stack[_stack_head]),
66.539 + ++_stack[_stack_head]==INVALID))
66.540 + {
66.541 + _processed->set(n,true);
66.542 + --_stack_head;
66.543 + }
66.544 + }
66.545 + }
66.546 +
66.547 + ///\brief Returns \c false if there are nodes
66.548 + ///to be processed in the queue
66.549 + ///
66.550 + ///Returns \c false if there are nodes
66.551 + ///to be processed in the queue
66.552 + bool emptyQueue() { return _stack_head<0; }
66.553 + ///Returns the number of the nodes to be processed.
66.554 +
66.555 + ///Returns the number of the nodes to be processed in the queue.
66.556 + ///
66.557 + int queueSize() { return _stack_head+1; }
66.558 +
66.559 + ///Executes the algorithm.
66.560 +
66.561 + ///Executes the algorithm.
66.562 + ///
66.563 + ///\pre init() must be called and at least one node should be added
66.564 + ///with addSource() before using this function.
66.565 + ///
66.566 + ///This method runs the %DFS algorithm from the root node(s)
66.567 + ///in order to
66.568 + ///compute the
66.569 + ///%DFS path to each node. The algorithm computes
66.570 + ///- The %DFS tree.
66.571 + ///- The distance of each node from the root(s).
66.572 + ///
66.573 + void start()
66.574 + {
66.575 + while ( !emptyQueue() ) processNextEdge();
66.576 + }
66.577 +
66.578 + ///Executes the algorithm until \c dest is reached.
66.579 +
66.580 + ///Executes the algorithm until \c dest is reached.
66.581 + ///
66.582 + ///\pre init() must be called and at least one node should be added
66.583 + ///with addSource() before using this function.
66.584 + ///
66.585 + ///This method runs the %DFS algorithm from the root node(s)
66.586 + ///in order to
66.587 + ///compute the
66.588 + ///%DFS path to \c dest. The algorithm computes
66.589 + ///- The %DFS path to \c dest.
66.590 + ///- The distance of \c dest from the root(s).
66.591 + ///
66.592 + void start(Node dest)
66.593 + {
66.594 + while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
66.595 + processNextEdge();
66.596 + }
66.597 +
66.598 + ///Executes the algorithm until a condition is met.
66.599 +
66.600 + ///Executes the algorithm until a condition is met.
66.601 + ///
66.602 + ///\pre init() must be called and at least one node should be added
66.603 + ///with addSource() before using this function.
66.604 + ///
66.605 + ///\param nm must be a bool (or convertible) edge map. The algorithm
66.606 + ///will stop when it reaches a edge \c v with <tt>nm[v]==true</tt>.
66.607 + ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c mn is an edge map,
66.608 + ///not a node map.
66.609 + template<class NM>
66.610 + void start(const NM &nm)
66.611 + {
66.612 + while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
66.613 + }
66.614 +
66.615 + ///Runs %DFS algorithm from node \c s.
66.616 +
66.617 + ///This method runs the %DFS algorithm from a root node \c s
66.618 + ///in order to
66.619 + ///compute the
66.620 + ///%DFS path to each node. The algorithm computes
66.621 + ///- The %DFS tree.
66.622 + ///- The distance of each node from the root.
66.623 + ///
66.624 + ///\note d.run(s) is just a shortcut of the following code.
66.625 + ///\code
66.626 + /// d.init();
66.627 + /// d.addSource(s);
66.628 + /// d.start();
66.629 + ///\endcode
66.630 + void run(Node s) {
66.631 + init();
66.632 + addSource(s);
66.633 + start();
66.634 + }
66.635 +
66.636 + ///Finds the %DFS path between \c s and \c t.
66.637 +
66.638 + ///Finds the %DFS path between \c s and \c t.
66.639 + ///
66.640 + ///\return The length of the %DFS s---t path if there exists one,
66.641 + ///0 otherwise.
66.642 + ///\note Apart from the return value, d.run(s) is
66.643 + ///just a shortcut of the following code.
66.644 + ///\code
66.645 + /// d.init();
66.646 + /// d.addSource(s);
66.647 + /// d.start(t);
66.648 + ///\endcode
66.649 + int run(Node s,Node t) {
66.650 + init();
66.651 + addSource(s);
66.652 + start(t);
66.653 + return reached(t)?_stack_head+1:0;
66.654 + }
66.655 +
66.656 + ///@}
66.657 +
66.658 + ///\name Query Functions
66.659 + ///The result of the %DFS algorithm can be obtained using these
66.660 + ///functions.\n
66.661 + ///Before the use of these functions,
66.662 + ///either run() or start() must be called.
66.663 +
66.664 + ///@{
66.665 +
66.666 + ///Copies the path to \c t on the DFS tree into \c p
66.667 +
66.668 + ///This function copies the path on the DFS tree to \c t into \c p.
66.669 + ///If it \c \t is a source itself or unreachable, then it does not
66.670 + ///alter \c p.
66.671 + ///\todo Is it the right way to handle unreachable nodes?
66.672 + ///\return Returns \c true if a path to \c t was actually copied to \c p,
66.673 + ///\c false otherwise.
66.674 + ///\sa DirPath
66.675 + template<class P>
66.676 + bool getPath(P &p,Node t)
66.677 + {
66.678 + if(reached(t)) {
66.679 + p.clear();
66.680 + typename P::Builder b(p);
66.681 + for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
66.682 + b.pushFront(pred(t));
66.683 + b.commit();
66.684 + return true;
66.685 + }
66.686 + return false;
66.687 + }
66.688 +
66.689 + ///The distance of a node from the root(s).
66.690 +
66.691 + ///Returns the distance of a node from the root(s).
66.692 + ///\pre \ref run() must be called before using this function.
66.693 + ///\warning If node \c v in unreachable from the root(s) the return value
66.694 + ///of this funcion is undefined.
66.695 + int dist(Node v) const { return (*_dist)[v]; }
66.696 +
66.697 + ///Returns the 'previous edge' of the %DFS tree.
66.698 +
66.699 + ///For a node \c v it returns the 'previous edge'
66.700 + ///of the %DFS path,
66.701 + ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
66.702 + ///v. It is \ref INVALID
66.703 + ///if \c v is unreachable from the root(s) or \c v is a root. The
66.704 + ///%DFS tree used here is equal to the %DFS tree used in
66.705 + ///\ref predNode(Node v).
66.706 + ///\pre Either \ref run() or \ref start() must be called before using
66.707 + ///this function.
66.708 + ///\todo predEdge could be a better name.
66.709 + Edge pred(Node v) const { return (*_pred)[v];}
66.710 +
66.711 + ///Returns the 'previous node' of the %DFS tree.
66.712 +
66.713 + ///For a node \c v it returns the 'previous node'
66.714 + ///of the %DFS tree,
66.715 + ///i.e. it returns the last but one node from a %DFS path from the
66.716 + ///root(a) to \c /v.
66.717 + ///It is INVALID if \c v is unreachable from the root(s) or
66.718 + ///if \c v itself a root.
66.719 + ///The %DFS tree used here is equal to the %DFS
66.720 + ///tree used in \ref pred(Node v).
66.721 + ///\pre Either \ref run() or \ref start() must be called before
66.722 + ///using this function.
66.723 + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
66.724 + G->source((*_pred)[v]); }
66.725 +
66.726 + ///Returns a reference to the NodeMap of distances.
66.727 +
66.728 + ///Returns a reference to the NodeMap of distances.
66.729 + ///\pre Either \ref run() or \ref init() must
66.730 + ///be called before using this function.
66.731 + const DistMap &distMap() const { return *_dist;}
66.732 +
66.733 + ///Returns a reference to the %DFS edge-tree map.
66.734 +
66.735 + ///Returns a reference to the NodeMap of the edges of the
66.736 + ///%DFS tree.
66.737 + ///\pre Either \ref run() or \ref init()
66.738 + ///must be called before using this function.
66.739 + const PredMap &predMap() const { return *_pred;}
66.740 +
66.741 +// ///Returns a reference to the map of nodes of %DFS paths.
66.742 +
66.743 +// ///Returns a reference to the NodeMap of the last but one nodes of the
66.744 +// ///%DFS tree.
66.745 +// ///\pre \ref run() must be called before using this function.
66.746 +// const PredNodeMap &predNodeMap() const { return *_predNode;}
66.747 +
66.748 + ///Checks if a node is reachable from the root.
66.749 +
66.750 + ///Returns \c true if \c v is reachable from the root.
66.751 + ///\warning The source nodes are inditated as unreached.
66.752 + ///\pre Either \ref run() or \ref start()
66.753 + ///must be called before using this function.
66.754 + ///
66.755 + bool reached(Node v) { return (*_reached)[v]; }
66.756 +
66.757 + ///@}
66.758 + };
66.759 +
66.760 + ///Default traits class of Dfs function.
66.761 +
66.762 + ///Default traits class of Dfs function.
66.763 + ///\param GR Graph type.
66.764 + template<class GR>
66.765 + struct DfsWizardDefaultTraits
66.766 + {
66.767 + ///The graph type the algorithm runs on.
66.768 + typedef GR Graph;
66.769 + ///\brief The type of the map that stores the last
66.770 + ///edges of the %DFS paths.
66.771 + ///
66.772 + ///The type of the map that stores the last
66.773 + ///edges of the %DFS paths.
66.774 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.775 + ///
66.776 + typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
66.777 + ///Instantiates a PredMap.
66.778 +
66.779 + ///This function instantiates a \ref PredMap.
66.780 + ///\param G is the graph, to which we would like to define the PredMap.
66.781 + ///\todo The graph alone may be insufficient to initialize
66.782 + static PredMap *createPredMap(const GR &)
66.783 + {
66.784 + return new PredMap();
66.785 + }
66.786 +// ///\brief The type of the map that stores the last but one
66.787 +// ///nodes of the %DFS paths.
66.788 +// ///
66.789 +// ///The type of the map that stores the last but one
66.790 +// ///nodes of the %DFS paths.
66.791 +// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.792 +// ///
66.793 +// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
66.794 +// ///Instantiates a PredNodeMap.
66.795 +
66.796 +// ///This function instantiates a \ref PredNodeMap.
66.797 +// ///\param G is the graph, to which
66.798 +// ///we would like to define the \ref PredNodeMap
66.799 +// static PredNodeMap *createPredNodeMap(const GR &G)
66.800 +// {
66.801 +// return new PredNodeMap();
66.802 +// }
66.803 +
66.804 + ///The type of the map that indicates which nodes are processed.
66.805 +
66.806 + ///The type of the map that indicates which nodes are processed.
66.807 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.808 + ///\todo named parameter to set this type, function to read and write.
66.809 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
66.810 + ///Instantiates a ProcessedMap.
66.811 +
66.812 + ///This function instantiates a \ref ProcessedMap.
66.813 + ///\param G is the graph, to which
66.814 + ///we would like to define the \ref ProcessedMap
66.815 + static ProcessedMap *createProcessedMap(const GR &)
66.816 + {
66.817 + return new ProcessedMap();
66.818 + }
66.819 + ///The type of the map that indicates which nodes are reached.
66.820 +
66.821 + ///The type of the map that indicates which nodes are reached.
66.822 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.823 + ///\todo named parameter to set this type, function to read and write.
66.824 + typedef typename Graph::template NodeMap<bool> ReachedMap;
66.825 + ///Instantiates a ReachedMap.
66.826 +
66.827 + ///This function instantiates a \ref ReachedMap.
66.828 + ///\param G is the graph, to which
66.829 + ///we would like to define the \ref ReachedMap.
66.830 + static ReachedMap *createReachedMap(const GR &G)
66.831 + {
66.832 + return new ReachedMap(G);
66.833 + }
66.834 + ///The type of the map that stores the dists of the nodes.
66.835 +
66.836 + ///The type of the map that stores the dists of the nodes.
66.837 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
66.838 + ///
66.839 + typedef NullMap<typename Graph::Node,int> DistMap;
66.840 + ///Instantiates a DistMap.
66.841 +
66.842 + ///This function instantiates a \ref DistMap.
66.843 + ///\param G is the graph, to which we would like to define the \ref DistMap
66.844 + static DistMap *createDistMap(const GR &)
66.845 + {
66.846 + return new DistMap();
66.847 + }
66.848 + };
66.849 +
66.850 + /// Default traits used by \ref DfsWizard
66.851 +
66.852 + /// To make it easier to use Dfs algorithm
66.853 + ///we have created a wizard class.
66.854 + /// This \ref DfsWizard class needs default traits,
66.855 + ///as well as the \ref Dfs class.
66.856 + /// The \ref DfsWizardBase is a class to be the default traits of the
66.857 + /// \ref DfsWizard class.
66.858 + template<class GR>
66.859 + class DfsWizardBase : public DfsWizardDefaultTraits<GR>
66.860 + {
66.861 +
66.862 + typedef DfsWizardDefaultTraits<GR> Base;
66.863 + protected:
66.864 + /// Type of the nodes in the graph.
66.865 + typedef typename Base::Graph::Node Node;
66.866 +
66.867 + /// Pointer to the underlying graph.
66.868 + void *_g;
66.869 + ///Pointer to the map of reached nodes.
66.870 + void *_reached;
66.871 + ///Pointer to the map of processed nodes.
66.872 + void *_processed;
66.873 + ///Pointer to the map of predecessors edges.
66.874 + void *_pred;
66.875 +// ///Pointer to the map of predecessors nodes.
66.876 +// void *_predNode;
66.877 + ///Pointer to the map of distances.
66.878 + void *_dist;
66.879 + ///Pointer to the source node.
66.880 + Node _source;
66.881 +
66.882 + public:
66.883 + /// Constructor.
66.884 +
66.885 + /// This constructor does not require parameters, therefore it initiates
66.886 + /// all of the attributes to default values (0, INVALID).
66.887 + DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
66.888 +// _predNode(0),
66.889 + _dist(0), _source(INVALID) {}
66.890 +
66.891 + /// Constructor.
66.892 +
66.893 + /// This constructor requires some parameters,
66.894 + /// listed in the parameters list.
66.895 + /// Others are initiated to 0.
66.896 + /// \param g is the initial value of \ref _g
66.897 + /// \param s is the initial value of \ref _source
66.898 + DfsWizardBase(const GR &g, Node s=INVALID) :
66.899 + _g((void *)&g), _reached(0), _processed(0), _pred(0),
66.900 +// _predNode(0),
66.901 + _dist(0), _source(s) {}
66.902 +
66.903 + };
66.904 +
66.905 + /// A class to make the usage of Dfs algorithm easier
66.906 +
66.907 + /// This class is created to make it easier to use Dfs algorithm.
66.908 + /// It uses the functions and features of the plain \ref Dfs,
66.909 + /// but it is much simpler to use it.
66.910 + ///
66.911 + /// Simplicity means that the way to change the types defined
66.912 + /// in the traits class is based on functions that returns the new class
66.913 + /// and not on templatable built-in classes.
66.914 + /// When using the plain \ref Dfs
66.915 + /// the new class with the modified type comes from
66.916 + /// the original class by using the ::
66.917 + /// operator. In the case of \ref DfsWizard only
66.918 + /// a function have to be called and it will
66.919 + /// return the needed class.
66.920 + ///
66.921 + /// It does not have own \ref run method. When its \ref run method is called
66.922 + /// it initiates a plain \ref Dfs class, and calls the \ref Dfs::run
66.923 + /// method of it.
66.924 + template<class TR>
66.925 + class DfsWizard : public TR
66.926 + {
66.927 + typedef TR Base;
66.928 +
66.929 + ///The type of the underlying graph.
66.930 + typedef typename TR::Graph Graph;
66.931 + //\e
66.932 + typedef typename Graph::Node Node;
66.933 + //\e
66.934 + typedef typename Graph::NodeIt NodeIt;
66.935 + //\e
66.936 + typedef typename Graph::Edge Edge;
66.937 + //\e
66.938 + typedef typename Graph::OutEdgeIt OutEdgeIt;
66.939 +
66.940 + ///\brief The type of the map that stores
66.941 + ///the reached nodes
66.942 + typedef typename TR::ReachedMap ReachedMap;
66.943 + ///\brief The type of the map that stores
66.944 + ///the processed nodes
66.945 + typedef typename TR::ProcessedMap ProcessedMap;
66.946 + ///\brief The type of the map that stores the last
66.947 + ///edges of the %DFS paths.
66.948 + typedef typename TR::PredMap PredMap;
66.949 +// ///\brief The type of the map that stores the last but one
66.950 +// ///nodes of the %DFS paths.
66.951 +// typedef typename TR::PredNodeMap PredNodeMap;
66.952 + ///The type of the map that stores the dists of the nodes.
66.953 + typedef typename TR::DistMap DistMap;
66.954 +
66.955 +public:
66.956 + /// Constructor.
66.957 + DfsWizard() : TR() {}
66.958 +
66.959 + /// Constructor that requires parameters.
66.960 +
66.961 + /// Constructor that requires parameters.
66.962 + /// These parameters will be the default values for the traits class.
66.963 + DfsWizard(const Graph &g, Node s=INVALID) :
66.964 + TR(g,s) {}
66.965 +
66.966 + ///Copy constructor
66.967 + DfsWizard(const TR &b) : TR(b) {}
66.968 +
66.969 + ~DfsWizard() {}
66.970 +
66.971 + ///Runs Dfs algorithm from a given node.
66.972 +
66.973 + ///Runs Dfs algorithm from a given node.
66.974 + ///The node can be given by the \ref source function.
66.975 + void run()
66.976 + {
66.977 + if(Base::_source==INVALID) throw UninitializedParameter();
66.978 + Dfs<Graph,TR> alg(*(Graph*)Base::_g);
66.979 + if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
66.980 + if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
66.981 + if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
66.982 +// if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
66.983 + if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
66.984 + alg.run(Base::_source);
66.985 + }
66.986 +
66.987 + ///Runs Dfs algorithm from the given node.
66.988 +
66.989 + ///Runs Dfs algorithm from the given node.
66.990 + ///\param s is the given source.
66.991 + void run(Node s)
66.992 + {
66.993 + Base::_source=s;
66.994 + run();
66.995 + }
66.996 +
66.997 + template<class T>
66.998 + struct DefPredMapBase : public Base {
66.999 + typedef T PredMap;
66.1000 + static PredMap *createPredMap(const Graph &) { return 0; };
66.1001 + DefPredMapBase(const TR &b) : TR(b) {}
66.1002 + };
66.1003 +
66.1004 + ///\brief \ref named-templ-param "Named parameter"
66.1005 + ///function for setting PredMap type
66.1006 + ///
66.1007 + /// \ref named-templ-param "Named parameter"
66.1008 + ///function for setting PredMap type
66.1009 + ///
66.1010 + template<class T>
66.1011 + DfsWizard<DefPredMapBase<T> > predMap(const T &t)
66.1012 + {
66.1013 + Base::_pred=(void *)&t;
66.1014 + return DfsWizard<DefPredMapBase<T> >(*this);
66.1015 + }
66.1016 +
66.1017 +
66.1018 + template<class T>
66.1019 + struct DefReachedMapBase : public Base {
66.1020 + typedef T ReachedMap;
66.1021 + static ReachedMap *createReachedMap(const Graph &) { return 0; };
66.1022 + DefReachedMapBase(const TR &b) : TR(b) {}
66.1023 + };
66.1024 +
66.1025 + ///\brief \ref named-templ-param "Named parameter"
66.1026 + ///function for setting ReachedMap
66.1027 + ///
66.1028 + /// \ref named-templ-param "Named parameter"
66.1029 + ///function for setting ReachedMap
66.1030 + ///
66.1031 + template<class T>
66.1032 + DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
66.1033 + {
66.1034 + Base::_pred=(void *)&t;
66.1035 + return DfsWizard<DefReachedMapBase<T> >(*this);
66.1036 + }
66.1037 +
66.1038 +
66.1039 + template<class T>
66.1040 + struct DefProcessedMapBase : public Base {
66.1041 + typedef T ProcessedMap;
66.1042 + static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
66.1043 + DefProcessedMapBase(const TR &b) : TR(b) {}
66.1044 + };
66.1045 +
66.1046 + ///\brief \ref named-templ-param "Named parameter"
66.1047 + ///function for setting ProcessedMap
66.1048 + ///
66.1049 + /// \ref named-templ-param "Named parameter"
66.1050 + ///function for setting ProcessedMap
66.1051 + ///
66.1052 + template<class T>
66.1053 + DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
66.1054 + {
66.1055 + Base::_pred=(void *)&t;
66.1056 + return DfsWizard<DefProcessedMapBase<T> >(*this);
66.1057 + }
66.1058 +
66.1059 +
66.1060 +// template<class T>
66.1061 +// struct DefPredNodeMapBase : public Base {
66.1062 +// typedef T PredNodeMap;
66.1063 +// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
66.1064 +// DefPredNodeMapBase(const TR &b) : TR(b) {}
66.1065 +// };
66.1066 +
66.1067 +// ///\brief \ref named-templ-param "Named parameter"
66.1068 +// ///function for setting PredNodeMap type
66.1069 +// ///
66.1070 +// /// \ref named-templ-param "Named parameter"
66.1071 +// ///function for setting PredNodeMap type
66.1072 +// ///
66.1073 +// template<class T>
66.1074 +// DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
66.1075 +// {
66.1076 +// Base::_predNode=(void *)&t;
66.1077 +// return DfsWizard<DefPredNodeMapBase<T> >(*this);
66.1078 +// }
66.1079 +
66.1080 + template<class T>
66.1081 + struct DefDistMapBase : public Base {
66.1082 + typedef T DistMap;
66.1083 + static DistMap *createDistMap(const Graph &) { return 0; };
66.1084 + DefDistMapBase(const TR &b) : TR(b) {}
66.1085 + };
66.1086 +
66.1087 + ///\brief \ref named-templ-param "Named parameter"
66.1088 + ///function for setting DistMap type
66.1089 + ///
66.1090 + /// \ref named-templ-param "Named parameter"
66.1091 + ///function for setting DistMap type
66.1092 + ///
66.1093 + template<class T>
66.1094 + DfsWizard<DefDistMapBase<T> > distMap(const T &t)
66.1095 + {
66.1096 + Base::_dist=(void *)&t;
66.1097 + return DfsWizard<DefDistMapBase<T> >(*this);
66.1098 + }
66.1099 +
66.1100 + /// Sets the source node, from which the Dfs algorithm runs.
66.1101 +
66.1102 + /// Sets the source node, from which the Dfs algorithm runs.
66.1103 + /// \param s is the source node.
66.1104 + DfsWizard<TR> &source(Node s)
66.1105 + {
66.1106 + Base::_source=s;
66.1107 + return *this;
66.1108 + }
66.1109 +
66.1110 + };
66.1111 +
66.1112 + ///Function type interface for Dfs algorithm.
66.1113 +
66.1114 + /// \ingroup flowalgs
66.1115 + ///Function type interface for Dfs algorithm.
66.1116 + ///
66.1117 + ///This function also has several
66.1118 + ///\ref named-templ-func-param "named parameters",
66.1119 + ///they are declared as the members of class \ref DfsWizard.
66.1120 + ///The following
66.1121 + ///example shows how to use these parameters.
66.1122 + ///\code
66.1123 + /// dfs(g,source).predMap(preds).run();
66.1124 + ///\endcode
66.1125 + ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
66.1126 + ///to the end of the parameter list.
66.1127 + ///\sa DfsWizard
66.1128 + ///\sa Dfs
66.1129 + template<class GR>
66.1130 + DfsWizard<DfsWizardBase<GR> >
66.1131 + dfs(const GR &g,typename GR::Node s=INVALID)
66.1132 + {
66.1133 + return DfsWizard<DfsWizardBase<GR> >(g,s);
66.1134 + }
66.1135 +
66.1136 +} //END OF NAMESPACE LEMON
66.1137 +
66.1138 +#endif
66.1139 +
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/lemon/dijkstra.h Mon May 23 04:48:14 2005 +0000
67.3 @@ -0,0 +1,1074 @@
67.4 +/* -*- C++ -*-
67.5 + * lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library
67.6 + *
67.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
67.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
67.9 + *
67.10 + * Permission to use, modify and distribute this software is granted
67.11 + * provided that this copyright notice appears in all copies. For
67.12 + * precise terms see the accompanying LICENSE file.
67.13 + *
67.14 + * This software is provided "AS IS" with no warranty of any kind,
67.15 + * express or implied, and with no claim as to its suitability for any
67.16 + * purpose.
67.17 + *
67.18 + */
67.19 +
67.20 +#ifndef LEMON_DIJKSTRA_H
67.21 +#define LEMON_DIJKSTRA_H
67.22 +
67.23 +///\ingroup flowalgs
67.24 +///\file
67.25 +///\brief Dijkstra algorithm.
67.26 +///
67.27 +///\todo getPath() should be implemented! (also for BFS and DFS)
67.28 +
67.29 +#include <lemon/list_graph.h>
67.30 +#include <lemon/bin_heap.h>
67.31 +#include <lemon/invalid.h>
67.32 +#include <lemon/error.h>
67.33 +#include <lemon/maps.h>
67.34 +
67.35 +namespace lemon {
67.36 +
67.37 +
67.38 +
67.39 + ///Default traits class of Dijkstra class.
67.40 +
67.41 + ///Default traits class of Dijkstra class.
67.42 + ///\param GR Graph type.
67.43 + ///\param LM Type of length map.
67.44 + template<class GR, class LM>
67.45 + struct DijkstraDefaultTraits
67.46 + {
67.47 + ///The graph type the algorithm runs on.
67.48 + typedef GR Graph;
67.49 + ///The type of the map that stores the edge lengths.
67.50 +
67.51 + ///The type of the map that stores the edge lengths.
67.52 + ///It must meet the \ref concept::ReadMap "ReadMap" concept.
67.53 + typedef LM LengthMap;
67.54 + //The type of the length of the edges.
67.55 + typedef typename LM::Value Value;
67.56 + ///The heap type used by Dijkstra algorithm.
67.57 +
67.58 + ///The heap type used by Dijkstra algorithm.
67.59 + ///
67.60 + ///\sa BinHeap
67.61 + ///\sa Dijkstra
67.62 + typedef BinHeap<typename Graph::Node,
67.63 + typename LM::Value,
67.64 + typename GR::template NodeMap<int>,
67.65 + std::less<Value> > Heap;
67.66 +
67.67 + ///\brief The type of the map that stores the last
67.68 + ///edges of the shortest paths.
67.69 + ///
67.70 + ///The type of the map that stores the last
67.71 + ///edges of the shortest paths.
67.72 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.73 + ///
67.74 + typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
67.75 + ///Instantiates a PredMap.
67.76 +
67.77 + ///This function instantiates a \ref PredMap.
67.78 + ///\param G is the graph, to which we would like to define the PredMap.
67.79 + ///\todo The graph alone may be insufficient for the initialization
67.80 + static PredMap *createPredMap(const GR &G)
67.81 + {
67.82 + return new PredMap(G);
67.83 + }
67.84 +// ///\brief The type of the map that stores the last but one
67.85 +// ///nodes of the shortest paths.
67.86 +// ///
67.87 +// ///The type of the map that stores the last but one
67.88 +// ///nodes of the shortest paths.
67.89 +// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.90 +// ///
67.91 +// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
67.92 +// ///Instantiates a PredNodeMap.
67.93 +
67.94 +// ///This function instantiates a \ref PredNodeMap.
67.95 +// ///\param G is the graph, to which
67.96 +// ///we would like to define the \ref PredNodeMap
67.97 +// static PredNodeMap *createPredNodeMap(const GR &G)
67.98 +// {
67.99 +// return new PredNodeMap();
67.100 +// }
67.101 +
67.102 + ///The type of the map that stores whether a nodes is processed.
67.103 +
67.104 + ///The type of the map that stores whether a nodes is processed.
67.105 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.106 + ///By default it is a NullMap.
67.107 + ///\todo If it is set to a real map,
67.108 + ///Dijkstra::processed() should read this.
67.109 + ///\todo named parameter to set this type, function to read and write.
67.110 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
67.111 + ///Instantiates a ProcessedMap.
67.112 +
67.113 + ///This function instantiates a \ref ProcessedMap.
67.114 + ///\param G is the graph, to which
67.115 + ///we would like to define the \ref ProcessedMap
67.116 + static ProcessedMap *createProcessedMap(const GR &)
67.117 + {
67.118 + return new ProcessedMap();
67.119 + }
67.120 + ///The type of the map that stores the dists of the nodes.
67.121 +
67.122 + ///The type of the map that stores the dists of the nodes.
67.123 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.124 + ///
67.125 + typedef typename Graph::template NodeMap<typename LM::Value> DistMap;
67.126 + ///Instantiates a DistMap.
67.127 +
67.128 + ///This function instantiates a \ref DistMap.
67.129 + ///\param G is the graph, to which we would like to define the \ref DistMap
67.130 + static DistMap *createDistMap(const GR &G)
67.131 + {
67.132 + return new DistMap(G);
67.133 + }
67.134 + };
67.135 +
67.136 + ///%Dijkstra algorithm class.
67.137 +
67.138 + /// \ingroup flowalgs
67.139 + ///This class provides an efficient implementation of %Dijkstra algorithm.
67.140 + ///The edge lengths are passed to the algorithm using a
67.141 + ///\ref concept::ReadMap "ReadMap",
67.142 + ///so it is easy to change it to any kind of length.
67.143 + ///
67.144 + ///The type of the length is determined by the
67.145 + ///\ref concept::ReadMap::Value "Value" of the length map.
67.146 + ///
67.147 + ///It is also possible to change the underlying priority heap.
67.148 + ///
67.149 + ///\param GR The graph type the algorithm runs on. The default value
67.150 + ///is \ref ListGraph. The value of GR is not used directly by
67.151 + ///Dijkstra, it is only passed to \ref DijkstraDefaultTraits.
67.152 + ///\param LM This read-only EdgeMap determines the lengths of the
67.153 + ///edges. It is read once for each edge, so the map may involve in
67.154 + ///relatively time consuming process to compute the edge length if
67.155 + ///it is necessary. The default map type is \ref
67.156 + ///concept::StaticGraph::EdgeMap "Graph::EdgeMap<int>". The value
67.157 + ///of LM is not used directly by Dijkstra, it is only passed to \ref
67.158 + ///DijkstraDefaultTraits. \param TR Traits class to set
67.159 + ///various data types used by the algorithm. The default traits
67.160 + ///class is \ref DijkstraDefaultTraits
67.161 + ///"DijkstraDefaultTraits<GR,LM>". See \ref
67.162 + ///DijkstraDefaultTraits for the documentation of a Dijkstra traits
67.163 + ///class.
67.164 + ///
67.165 + ///\author Jacint Szabo and Alpar Juttner
67.166 + ///\todo A compare object would be nice.
67.167 +
67.168 +#ifdef DOXYGEN
67.169 + template <typename GR,
67.170 + typename LM,
67.171 + typename TR>
67.172 +#else
67.173 + template <typename GR=ListGraph,
67.174 + typename LM=typename GR::template EdgeMap<int>,
67.175 + typename TR=DijkstraDefaultTraits<GR,LM> >
67.176 +#endif
67.177 + class Dijkstra {
67.178 + public:
67.179 + /**
67.180 + * \brief \ref Exception for uninitialized parameters.
67.181 + *
67.182 + * This error represents problems in the initialization
67.183 + * of the parameters of the algorithms.
67.184 + */
67.185 + class UninitializedParameter : public lemon::UninitializedParameter {
67.186 + public:
67.187 + virtual const char* exceptionName() const {
67.188 + return "lemon::Dijkstra::UninitializedParameter";
67.189 + }
67.190 + };
67.191 +
67.192 + typedef TR Traits;
67.193 + ///The type of the underlying graph.
67.194 + typedef typename TR::Graph Graph;
67.195 + ///\e
67.196 + typedef typename Graph::Node Node;
67.197 + ///\e
67.198 + typedef typename Graph::NodeIt NodeIt;
67.199 + ///\e
67.200 + typedef typename Graph::Edge Edge;
67.201 + ///\e
67.202 + typedef typename Graph::OutEdgeIt OutEdgeIt;
67.203 +
67.204 + ///The type of the length of the edges.
67.205 + typedef typename TR::LengthMap::Value Value;
67.206 + ///The type of the map that stores the edge lengths.
67.207 + typedef typename TR::LengthMap LengthMap;
67.208 + ///\brief The type of the map that stores the last
67.209 + ///edges of the shortest paths.
67.210 + typedef typename TR::PredMap PredMap;
67.211 +// ///\brief The type of the map that stores the last but one
67.212 +// ///nodes of the shortest paths.
67.213 +// typedef typename TR::PredNodeMap PredNodeMap;
67.214 + ///The type of the map indicating if a node is processed.
67.215 + typedef typename TR::ProcessedMap ProcessedMap;
67.216 + ///The type of the map that stores the dists of the nodes.
67.217 + typedef typename TR::DistMap DistMap;
67.218 + ///The heap type used by the dijkstra algorithm.
67.219 + typedef typename TR::Heap Heap;
67.220 + private:
67.221 + /// Pointer to the underlying graph.
67.222 + const Graph *G;
67.223 + /// Pointer to the length map
67.224 + const LengthMap *length;
67.225 + ///Pointer to the map of predecessors edges.
67.226 + PredMap *_pred;
67.227 + ///Indicates if \ref _pred is locally allocated (\c true) or not.
67.228 + bool local_pred;
67.229 +// ///Pointer to the map of predecessors nodes.
67.230 +// PredNodeMap *_predNode;
67.231 +// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
67.232 +// bool local_predNode;
67.233 + ///Pointer to the map of distances.
67.234 + DistMap *_dist;
67.235 + ///Indicates if \ref _dist is locally allocated (\c true) or not.
67.236 + bool local_dist;
67.237 + ///Pointer to the map of processed status of the nodes.
67.238 + ProcessedMap *_processed;
67.239 + ///Indicates if \ref _processed is locally allocated (\c true) or not.
67.240 + bool local_processed;
67.241 +
67.242 +// ///The source node of the last execution.
67.243 +// Node source;
67.244 +
67.245 + ///Creates the maps if necessary.
67.246 +
67.247 + ///\todo Error if \c G or are \c NULL. What about \c length?
67.248 + ///\todo Better memory allocation (instead of new).
67.249 + void create_maps()
67.250 + {
67.251 + if(!_pred) {
67.252 + local_pred = true;
67.253 + _pred = Traits::createPredMap(*G);
67.254 + }
67.255 +// if(!_predNode) {
67.256 +// local_predNode = true;
67.257 +// _predNode = Traits::createPredNodeMap(*G);
67.258 +// }
67.259 + if(!_dist) {
67.260 + local_dist = true;
67.261 + _dist = Traits::createDistMap(*G);
67.262 + }
67.263 + if(!_processed) {
67.264 + local_processed = true;
67.265 + _processed = Traits::createProcessedMap(*G);
67.266 + }
67.267 + }
67.268 +
67.269 + public :
67.270 +
67.271 + ///\name Named template parameters
67.272 +
67.273 + ///@{
67.274 +
67.275 + template <class T>
67.276 + struct DefPredMapTraits : public Traits {
67.277 + typedef T PredMap;
67.278 + static PredMap *createPredMap(const Graph &G)
67.279 + {
67.280 + throw UninitializedParameter();
67.281 + }
67.282 + };
67.283 + ///\ref named-templ-param "Named parameter" for setting PredMap type
67.284 +
67.285 + ///\ref named-templ-param "Named parameter" for setting PredMap type
67.286 + ///
67.287 + template <class T>
67.288 + class DefPredMap : public Dijkstra< Graph,
67.289 + LengthMap,
67.290 + DefPredMapTraits<T> > { };
67.291 +
67.292 +// template <class T>
67.293 +// struct DefPredNodeMapTraits : public Traits {
67.294 +// typedef T PredNodeMap;
67.295 +// static PredNodeMap *createPredNodeMap(const Graph &G)
67.296 +// {
67.297 +// throw UninitializedParameter();
67.298 +// }
67.299 +// };
67.300 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
67.301 +
67.302 +// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
67.303 +// ///
67.304 +// template <class T>
67.305 +// class DefPredNodeMap : public Dijkstra< Graph,
67.306 +// LengthMap,
67.307 +// DefPredNodeMapTraits<T> > { };
67.308 +
67.309 + template <class T>
67.310 + struct DefDistMapTraits : public Traits {
67.311 + typedef T DistMap;
67.312 + static DistMap *createDistMap(const Graph &G)
67.313 + {
67.314 + throw UninitializedParameter();
67.315 + }
67.316 + };
67.317 + ///\ref named-templ-param "Named parameter" for setting DistMap type
67.318 +
67.319 + ///\ref named-templ-param "Named parameter" for setting DistMap type
67.320 + ///
67.321 + template <class T>
67.322 + class DefDistMap : public Dijkstra< Graph,
67.323 + LengthMap,
67.324 + DefDistMapTraits<T> > { };
67.325 +
67.326 + template <class T>
67.327 + struct DefProcessedMapTraits : public Traits {
67.328 + typedef T ProcessedMap;
67.329 + static ProcessedMap *createProcessedMap(const Graph &G)
67.330 + {
67.331 + throw UninitializedParameter();
67.332 + }
67.333 + };
67.334 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
67.335 +
67.336 + ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
67.337 + ///
67.338 + template <class T>
67.339 + class DefProcessedMap : public Dijkstra< Graph,
67.340 + LengthMap,
67.341 + DefProcessedMapTraits<T> > { };
67.342 +
67.343 + struct DefGraphProcessedMapTraits : public Traits {
67.344 + typedef typename Graph::template NodeMap<bool> ProcessedMap;
67.345 + static ProcessedMap *createProcessedMap(const Graph &G)
67.346 + {
67.347 + return new ProcessedMap(G);
67.348 + }
67.349 + };
67.350 + ///\brief \ref named-templ-param "Named parameter"
67.351 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
67.352 + ///
67.353 + ///\ref named-templ-param "Named parameter"
67.354 + ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
67.355 + ///If you don't set it explicitely, it will be automatically allocated.
67.356 + template <class T>
67.357 + class DefProcessedMapToBeDefaultMap :
67.358 + public Dijkstra< Graph,
67.359 + LengthMap,
67.360 + DefGraphProcessedMapTraits> { };
67.361 +
67.362 + ///@}
67.363 +
67.364 +
67.365 + private:
67.366 + typename Graph::template NodeMap<int> _heap_map;
67.367 + Heap _heap;
67.368 + public:
67.369 +
67.370 + ///Constructor.
67.371 +
67.372 + ///\param _G the graph the algorithm will run on.
67.373 + ///\param _length the length map used by the algorithm.
67.374 + Dijkstra(const Graph& _G, const LengthMap& _length) :
67.375 + G(&_G), length(&_length),
67.376 + _pred(NULL), local_pred(false),
67.377 +// _predNode(NULL), local_predNode(false),
67.378 + _dist(NULL), local_dist(false),
67.379 + _processed(NULL), local_processed(false),
67.380 + _heap_map(*G,-1),_heap(_heap_map)
67.381 + { }
67.382 +
67.383 + ///Destructor.
67.384 + ~Dijkstra()
67.385 + {
67.386 + if(local_pred) delete _pred;
67.387 +// if(local_predNode) delete _predNode;
67.388 + if(local_dist) delete _dist;
67.389 + if(local_processed) delete _processed;
67.390 + }
67.391 +
67.392 + ///Sets the length map.
67.393 +
67.394 + ///Sets the length map.
67.395 + ///\return <tt> (*this) </tt>
67.396 + Dijkstra &lengthMap(const LengthMap &m)
67.397 + {
67.398 + length = &m;
67.399 + return *this;
67.400 + }
67.401 +
67.402 + ///Sets the map storing the predecessor edges.
67.403 +
67.404 + ///Sets the map storing the predecessor edges.
67.405 + ///If you don't use this function before calling \ref run(),
67.406 + ///it will allocate one. The destuctor deallocates this
67.407 + ///automatically allocated map, of course.
67.408 + ///\return <tt> (*this) </tt>
67.409 + Dijkstra &predMap(PredMap &m)
67.410 + {
67.411 + if(local_pred) {
67.412 + delete _pred;
67.413 + local_pred=false;
67.414 + }
67.415 + _pred = &m;
67.416 + return *this;
67.417 + }
67.418 +
67.419 +// ///Sets the map storing the predecessor nodes.
67.420 +
67.421 +// ///Sets the map storing the predecessor nodes.
67.422 +// ///If you don't use this function before calling \ref run(),
67.423 +// ///it will allocate one. The destuctor deallocates this
67.424 +// ///automatically allocated map, of course.
67.425 +// ///\return <tt> (*this) </tt>
67.426 +// Dijkstra &predNodeMap(PredNodeMap &m)
67.427 +// {
67.428 +// if(local_predNode) {
67.429 +// delete _predNode;
67.430 +// local_predNode=false;
67.431 +// }
67.432 +// _predNode = &m;
67.433 +// return *this;
67.434 +// }
67.435 +
67.436 + ///Sets the map storing the distances calculated by the algorithm.
67.437 +
67.438 + ///Sets the map storing the distances calculated by the algorithm.
67.439 + ///If you don't use this function before calling \ref run(),
67.440 + ///it will allocate one. The destuctor deallocates this
67.441 + ///automatically allocated map, of course.
67.442 + ///\return <tt> (*this) </tt>
67.443 + Dijkstra &distMap(DistMap &m)
67.444 + {
67.445 + if(local_dist) {
67.446 + delete _dist;
67.447 + local_dist=false;
67.448 + }
67.449 + _dist = &m;
67.450 + return *this;
67.451 + }
67.452 +
67.453 + private:
67.454 + void finalizeNodeData(Node v,Value dst)
67.455 + {
67.456 + _processed->set(v,true);
67.457 + _dist->set(v, dst);
67.458 +// if((*_pred)[v]!=INVALID)
67.459 +// _predNode->set(v,G->source((*_pred)[v])); ///\todo What to do?
67.460 + }
67.461 +
67.462 + public:
67.463 + ///\name Execution control
67.464 + ///The simplest way to execute the algorithm is to use
67.465 + ///one of the member functions called \c run(...).
67.466 + ///\n
67.467 + ///If you need more control on the execution,
67.468 + ///first you must call \ref init(), then you can add several source nodes
67.469 + ///with \ref addSource().
67.470 + ///Finally \ref start() will perform the actual path
67.471 + ///computation.
67.472 +
67.473 + ///@{
67.474 +
67.475 + ///Initializes the internal data structures.
67.476 +
67.477 + ///Initializes the internal data structures.
67.478 + ///
67.479 + ///\todo _heap_map's type could also be in the traits class.
67.480 + ///\todo The heaps should be able to make themselves empty directly.
67.481 + void init()
67.482 + {
67.483 + create_maps();
67.484 + while(!_heap.empty()) _heap.pop();
67.485 + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
67.486 + _pred->set(u,INVALID);
67.487 +// _predNode->set(u,INVALID);
67.488 + _processed->set(u,false);
67.489 + _heap_map.set(u,Heap::PRE_HEAP);
67.490 + }
67.491 + }
67.492 +
67.493 + ///Adds a new source node.
67.494 +
67.495 + ///Adds a new source node to the priority heap.
67.496 + ///
67.497 + ///The optional second parameter is the initial distance of the node.
67.498 + ///
67.499 + ///It checks if the node has already been added to the heap and
67.500 + ///It is pushed to the heap only if either it was not in the heap
67.501 + ///or the shortest path found till then is longer then \c dst.
67.502 + void addSource(Node s,Value dst=0)
67.503 + {
67.504 +// source = s;
67.505 + if(_heap.state(s) != Heap::IN_HEAP) _heap.push(s,dst);
67.506 + else if(_heap[s]<dst) {
67.507 + _heap.push(s,dst);
67.508 + _pred->set(s,INVALID);
67.509 + }
67.510 + }
67.511 +
67.512 + ///Processes the next node in the priority heap
67.513 +
67.514 + ///Processes the next node in the priority heap.
67.515 + ///
67.516 + ///\warning The priority heap must not be empty!
67.517 + void processNextNode()
67.518 + {
67.519 + Node v=_heap.top();
67.520 + Value oldvalue=_heap[v];
67.521 + _heap.pop();
67.522 + finalizeNodeData(v,oldvalue);
67.523 +
67.524 + for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
67.525 + Node w=G->target(e);
67.526 + switch(_heap.state(w)) {
67.527 + case Heap::PRE_HEAP:
67.528 + _heap.push(w,oldvalue+(*length)[e]);
67.529 + _pred->set(w,e);
67.530 +// _predNode->set(w,v);
67.531 + break;
67.532 + case Heap::IN_HEAP:
67.533 + if ( oldvalue+(*length)[e] < _heap[w] ) {
67.534 + _heap.decrease(w, oldvalue+(*length)[e]);
67.535 + _pred->set(w,e);
67.536 +// _predNode->set(w,v);
67.537 + }
67.538 + break;
67.539 + case Heap::POST_HEAP:
67.540 + break;
67.541 + }
67.542 + }
67.543 + }
67.544 +
67.545 + ///\brief Returns \c false if there are nodes
67.546 + ///to be processed in the priority heap
67.547 + ///
67.548 + ///Returns \c false if there are nodes
67.549 + ///to be processed in the priority heap
67.550 + bool emptyQueue() { return _heap.empty(); }
67.551 + ///Returns the number of the nodes to be processed in the priority heap
67.552 +
67.553 + ///Returns the number of the nodes to be processed in the priority heap
67.554 + ///
67.555 + int queueSize() { return _heap.size(); }
67.556 +
67.557 + ///Executes the algorithm.
67.558 +
67.559 + ///Executes the algorithm.
67.560 + ///
67.561 + ///\pre init() must be called and at least one node should be added
67.562 + ///with addSource() before using this function.
67.563 + ///
67.564 + ///This method runs the %Dijkstra algorithm from the root node(s)
67.565 + ///in order to
67.566 + ///compute the
67.567 + ///shortest path to each node. The algorithm computes
67.568 + ///- The shortest path tree.
67.569 + ///- The distance of each node from the root(s).
67.570 + ///
67.571 + void start()
67.572 + {
67.573 + while ( !_heap.empty() ) processNextNode();
67.574 + }
67.575 +
67.576 + ///Executes the algorithm until \c dest is reached.
67.577 +
67.578 + ///Executes the algorithm until \c dest is reached.
67.579 + ///
67.580 + ///\pre init() must be called and at least one node should be added
67.581 + ///with addSource() before using this function.
67.582 + ///
67.583 + ///This method runs the %Dijkstra algorithm from the root node(s)
67.584 + ///in order to
67.585 + ///compute the
67.586 + ///shortest path to \c dest. The algorithm computes
67.587 + ///- The shortest path to \c dest.
67.588 + ///- The distance of \c dest from the root(s).
67.589 + ///
67.590 + void start(Node dest)
67.591 + {
67.592 + while ( !_heap.empty() && _heap.top()!=dest ) processNextNode();
67.593 + if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
67.594 + }
67.595 +
67.596 + ///Executes the algorithm until a condition is met.
67.597 +
67.598 + ///Executes the algorithm until a condition is met.
67.599 + ///
67.600 + ///\pre init() must be called and at least one node should be added
67.601 + ///with addSource() before using this function.
67.602 + ///
67.603 + ///\param nm must be a bool (or convertible) node map. The algorithm
67.604 + ///will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
67.605 + template<class NodeBoolMap>
67.606 + void start(const NodeBoolMap &nm)
67.607 + {
67.608 + while ( !_heap.empty() && !nm[_heap.top()] ) processNextNode();
67.609 + if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
67.610 + }
67.611 +
67.612 + ///Runs %Dijkstra algorithm from node \c s.
67.613 +
67.614 + ///This method runs the %Dijkstra algorithm from a root node \c s
67.615 + ///in order to
67.616 + ///compute the
67.617 + ///shortest path to each node. The algorithm computes
67.618 + ///- The shortest path tree.
67.619 + ///- The distance of each node from the root.
67.620 + ///
67.621 + ///\note d.run(s) is just a shortcut of the following code.
67.622 + ///\code
67.623 + /// d.init();
67.624 + /// d.addSource(s);
67.625 + /// d.start();
67.626 + ///\endcode
67.627 + void run(Node s) {
67.628 + init();
67.629 + addSource(s);
67.630 + start();
67.631 + }
67.632 +
67.633 + ///Finds the shortest path between \c s and \c t.
67.634 +
67.635 + ///Finds the shortest path between \c s and \c t.
67.636 + ///
67.637 + ///\return The length of the shortest s---t path if there exists one,
67.638 + ///0 otherwise.
67.639 + ///\note Apart from the return value, d.run(s) is
67.640 + ///just a shortcut of the following code.
67.641 + ///\code
67.642 + /// d.init();
67.643 + /// d.addSource(s);
67.644 + /// d.start(t);
67.645 + ///\endcode
67.646 + Value run(Node s,Node t) {
67.647 + init();
67.648 + addSource(s);
67.649 + start(t);
67.650 + return (*_pred)[t]==INVALID?0:(*_dist)[t];
67.651 + }
67.652 +
67.653 + ///@}
67.654 +
67.655 + ///\name Query Functions
67.656 + ///The result of the %Dijkstra algorithm can be obtained using these
67.657 + ///functions.\n
67.658 + ///Before the use of these functions,
67.659 + ///either run() or start() must be called.
67.660 +
67.661 + ///@{
67.662 +
67.663 + ///Copies the shortest path to \c t into \c p
67.664 +
67.665 + ///This function copies the shortest path to \c t into \c p.
67.666 + ///If it \c \t is a source itself or unreachable, then it does not
67.667 + ///alter \c p.
67.668 + ///\todo Is it the right way to handle unreachable nodes?
67.669 + ///\return Returns \c true if a path to \c t was actually copied to \c p,
67.670 + ///\c false otherwise.
67.671 + ///\sa DirPath
67.672 + template<class P>
67.673 + bool getPath(P &p,Node t)
67.674 + {
67.675 + if(reached(t)) {
67.676 + p.clear();
67.677 + typename P::Builder b(p);
67.678 + for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
67.679 + b.pushFront(pred(t));
67.680 + b.commit();
67.681 + return true;
67.682 + }
67.683 + return false;
67.684 + }
67.685 +
67.686 + ///The distance of a node from the root.
67.687 +
67.688 + ///Returns the distance of a node from the root.
67.689 + ///\pre \ref run() must be called before using this function.
67.690 + ///\warning If node \c v in unreachable from the root the return value
67.691 + ///of this funcion is undefined.
67.692 + Value dist(Node v) const { return (*_dist)[v]; }
67.693 +
67.694 + ///Returns the 'previous edge' of the shortest path tree.
67.695 +
67.696 + ///For a node \c v it returns the 'previous edge' of the shortest path tree,
67.697 + ///i.e. it returns the last edge of a shortest path from the root to \c
67.698 + ///v. It is \ref INVALID
67.699 + ///if \c v is unreachable from the root or if \c v=s. The
67.700 + ///shortest path tree used here is equal to the shortest path tree used in
67.701 + ///\ref predNode(Node v). \pre \ref run() must be called before using
67.702 + ///this function.
67.703 + ///\todo predEdge could be a better name.
67.704 + Edge pred(Node v) const { return (*_pred)[v]; }
67.705 +
67.706 + ///Returns the 'previous node' of the shortest path tree.
67.707 +
67.708 + ///For a node \c v it returns the 'previous node' of the shortest path tree,
67.709 + ///i.e. it returns the last but one node from a shortest path from the
67.710 + ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
67.711 + ///\c v=s. The shortest path tree used here is equal to the shortest path
67.712 + ///tree used in \ref pred(Node v). \pre \ref run() must be called before
67.713 + ///using this function.
67.714 + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
67.715 + G->source((*_pred)[v]); }
67.716 +
67.717 + ///Returns a reference to the NodeMap of distances.
67.718 +
67.719 + ///Returns a reference to the NodeMap of distances. \pre \ref run() must
67.720 + ///be called before using this function.
67.721 + const DistMap &distMap() const { return *_dist;}
67.722 +
67.723 + ///Returns a reference to the shortest path tree map.
67.724 +
67.725 + ///Returns a reference to the NodeMap of the edges of the
67.726 + ///shortest path tree.
67.727 + ///\pre \ref run() must be called before using this function.
67.728 + const PredMap &predMap() const { return *_pred;}
67.729 +
67.730 +// ///Returns a reference to the map of nodes of shortest paths.
67.731 +
67.732 +// ///Returns a reference to the NodeMap of the last but one nodes of the
67.733 +// ///shortest path tree.
67.734 +// ///\pre \ref run() must be called before using this function.
67.735 +// const PredNodeMap &predNodeMap() const { return *_predNode;}
67.736 +
67.737 + ///Checks if a node is reachable from the root.
67.738 +
67.739 + ///Returns \c true if \c v is reachable from the root.
67.740 + ///\warning The source nodes are inditated as unreached.
67.741 + ///\pre \ref run() must be called before using this function.
67.742 + ///
67.743 + bool reached(Node v) { return _heap_map[v]!=Heap::PRE_HEAP; }
67.744 +
67.745 + ///@}
67.746 + };
67.747 +
67.748 +
67.749 +
67.750 +
67.751 +
67.752 + ///Default traits class of Dijkstra function.
67.753 +
67.754 + ///Default traits class of Dijkstra function.
67.755 + ///\param GR Graph type.
67.756 + ///\param LM Type of length map.
67.757 + template<class GR, class LM>
67.758 + struct DijkstraWizardDefaultTraits
67.759 + {
67.760 + ///The graph type the algorithm runs on.
67.761 + typedef GR Graph;
67.762 + ///The type of the map that stores the edge lengths.
67.763 +
67.764 + ///The type of the map that stores the edge lengths.
67.765 + ///It must meet the \ref concept::ReadMap "ReadMap" concept.
67.766 + typedef LM LengthMap;
67.767 + //The type of the length of the edges.
67.768 + typedef typename LM::Value Value;
67.769 + ///The heap type used by Dijkstra algorithm.
67.770 +
67.771 + ///The heap type used by Dijkstra algorithm.
67.772 + ///
67.773 + ///\sa BinHeap
67.774 + ///\sa Dijkstra
67.775 + typedef BinHeap<typename Graph::Node,
67.776 + typename LM::Value,
67.777 + typename GR::template NodeMap<int>,
67.778 + std::less<Value> > Heap;
67.779 +
67.780 + ///\brief The type of the map that stores the last
67.781 + ///edges of the shortest paths.
67.782 + ///
67.783 + ///The type of the map that stores the last
67.784 + ///edges of the shortest paths.
67.785 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.786 + ///
67.787 + typedef NullMap <typename GR::Node,typename GR::Edge> PredMap;
67.788 + ///Instantiates a PredMap.
67.789 +
67.790 + ///This function instantiates a \ref PredMap.
67.791 + ///\param G is the graph, to which we would like to define the PredMap.
67.792 + ///\todo The graph alone may be insufficient for the initialization
67.793 + static PredMap *createPredMap(const GR &)
67.794 + {
67.795 + return new PredMap();
67.796 + }
67.797 + ///The type of the map that stores whether a nodes is processed.
67.798 +
67.799 + ///The type of the map that stores whether a nodes is processed.
67.800 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.801 + ///By default it is a NullMap.
67.802 + ///\todo If it is set to a real map,
67.803 + ///Dijkstra::processed() should read this.
67.804 + ///\todo named parameter to set this type, function to read and write.
67.805 + typedef NullMap<typename Graph::Node,bool> ProcessedMap;
67.806 + ///Instantiates a ProcessedMap.
67.807 +
67.808 + ///This function instantiates a \ref ProcessedMap.
67.809 + ///\param G is the graph, to which
67.810 + ///we would like to define the \ref ProcessedMap
67.811 + static ProcessedMap *createProcessedMap(const GR &)
67.812 + {
67.813 + return new ProcessedMap();
67.814 + }
67.815 + ///The type of the map that stores the dists of the nodes.
67.816 +
67.817 + ///The type of the map that stores the dists of the nodes.
67.818 + ///It must meet the \ref concept::WriteMap "WriteMap" concept.
67.819 + ///
67.820 + typedef NullMap<typename Graph::Node,typename LM::Value> DistMap;
67.821 + ///Instantiates a DistMap.
67.822 +
67.823 + ///This function instantiates a \ref DistMap.
67.824 + ///\param G is the graph, to which we would like to define the \ref DistMap
67.825 + static DistMap *createDistMap(const GR &)
67.826 + {
67.827 + return new DistMap();
67.828 + }
67.829 + };
67.830 +
67.831 + /// Default traits used by \ref DijkstraWizard
67.832 +
67.833 + /// To make it easier to use Dijkstra algorithm
67.834 + ///we have created a wizard class.
67.835 + /// This \ref DijkstraWizard class needs default traits,
67.836 + ///as well as the \ref Dijkstra class.
67.837 + /// The \ref DijkstraWizardBase is a class to be the default traits of the
67.838 + /// \ref DijkstraWizard class.
67.839 + /// \todo More named parameters are required...
67.840 + template<class GR,class LM>
67.841 + class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
67.842 + {
67.843 +
67.844 + typedef DijkstraWizardDefaultTraits<GR,LM> Base;
67.845 + protected:
67.846 + /// Type of the nodes in the graph.
67.847 + typedef typename Base::Graph::Node Node;
67.848 +
67.849 + /// Pointer to the underlying graph.
67.850 + void *_g;
67.851 + /// Pointer to the length map
67.852 + void *_length;
67.853 + ///Pointer to the map of predecessors edges.
67.854 + void *_pred;
67.855 +// ///Pointer to the map of predecessors nodes.
67.856 +// void *_predNode;
67.857 + ///Pointer to the map of distances.
67.858 + void *_dist;
67.859 + ///Pointer to the source node.
67.860 + Node _source;
67.861 +
67.862 + public:
67.863 + /// Constructor.
67.864 +
67.865 + /// This constructor does not require parameters, therefore it initiates
67.866 + /// all of the attributes to default values (0, INVALID).
67.867 + DijkstraWizardBase() : _g(0), _length(0), _pred(0),
67.868 +// _predNode(0),
67.869 + _dist(0), _source(INVALID) {}
67.870 +
67.871 + /// Constructor.
67.872 +
67.873 + /// This constructor requires some parameters,
67.874 + /// listed in the parameters list.
67.875 + /// Others are initiated to 0.
67.876 + /// \param g is the initial value of \ref _g
67.877 + /// \param l is the initial value of \ref _length
67.878 + /// \param s is the initial value of \ref _source
67.879 + DijkstraWizardBase(const GR &g,const LM &l, Node s=INVALID) :
67.880 + _g((void *)&g), _length((void *)&l), _pred(0),
67.881 +// _predNode(0),
67.882 + _dist(0), _source(s) {}
67.883 +
67.884 + };
67.885 +
67.886 + /// A class to make the usage of Dijkstra algorithm easier
67.887 +
67.888 + /// This class is created to make it easier to use Dijkstra algorithm.
67.889 + /// It uses the functions and features of the plain \ref Dijkstra,
67.890 + /// but it is much simpler to use it.
67.891 + ///
67.892 + /// Simplicity means that the way to change the types defined
67.893 + /// in the traits class is based on functions that returns the new class
67.894 + /// and not on templatable built-in classes.
67.895 + /// When using the plain \ref Dijkstra
67.896 + /// the new class with the modified type comes from
67.897 + /// the original class by using the ::
67.898 + /// operator. In the case of \ref DijkstraWizard only
67.899 + /// a function have to be called and it will
67.900 + /// return the needed class.
67.901 + ///
67.902 + /// It does not have own \ref run method. When its \ref run method is called
67.903 + /// it initiates a plain \ref Dijkstra class, and calls the \ref Dijkstra::run
67.904 + /// method of it.
67.905 + template<class TR>
67.906 + class DijkstraWizard : public TR
67.907 + {
67.908 + typedef TR Base;
67.909 +
67.910 + ///The type of the underlying graph.
67.911 + typedef typename TR::Graph Graph;
67.912 + //\e
67.913 + typedef typename Graph::Node Node;
67.914 + //\e
67.915 + typedef typename Graph::NodeIt NodeIt;
67.916 + //\e
67.917 + typedef typename Graph::Edge Edge;
67.918 + //\e
67.919 + typedef typename Graph::OutEdgeIt OutEdgeIt;
67.920 +
67.921 + ///The type of the map that stores the edge lengths.
67.922 + typedef typename TR::LengthMap LengthMap;
67.923 + ///The type of the length of the edges.
67.924 + typedef typename LengthMap::Value Value;
67.925 + ///\brief The type of the map that stores the last
67.926 + ///edges of the shortest paths.
67.927 + typedef typename TR::PredMap PredMap;
67.928 +// ///\brief The type of the map that stores the last but one
67.929 +// ///nodes of the shortest paths.
67.930 +// typedef typename TR::PredNodeMap PredNodeMap;
67.931 + ///The type of the map that stores the dists of the nodes.
67.932 + typedef typename TR::DistMap DistMap;
67.933 +
67.934 + ///The heap type used by the dijkstra algorithm.
67.935 + typedef typename TR::Heap Heap;
67.936 +public:
67.937 + /// Constructor.
67.938 + DijkstraWizard() : TR() {}
67.939 +
67.940 + /// Constructor that requires parameters.
67.941 +
67.942 + /// Constructor that requires parameters.
67.943 + /// These parameters will be the default values for the traits class.
67.944 + DijkstraWizard(const Graph &g,const LengthMap &l, Node s=INVALID) :
67.945 + TR(g,l,s) {}
67.946 +
67.947 + ///Copy constructor
67.948 + DijkstraWizard(const TR &b) : TR(b) {}
67.949 +
67.950 + ~DijkstraWizard() {}
67.951 +
67.952 + ///Runs Dijkstra algorithm from a given node.
67.953 +
67.954 + ///Runs Dijkstra algorithm from a given node.
67.955 + ///The node can be given by the \ref source function.
67.956 + void run()
67.957 + {
67.958 + if(Base::_source==INVALID) throw UninitializedParameter();
67.959 + Dijkstra<Graph,LengthMap,TR>
67.960 + dij(*(Graph*)Base::_g,*(LengthMap*)Base::_length);
67.961 + if(Base::_pred) dij.predMap(*(PredMap*)Base::_pred);
67.962 +// if(Base::_predNode) Dij.predNodeMap(*(PredNodeMap*)Base::_predNode);
67.963 + if(Base::_dist) dij.distMap(*(DistMap*)Base::_dist);
67.964 + dij.run(Base::_source);
67.965 + }
67.966 +
67.967 + ///Runs Dijkstra algorithm from the given node.
67.968 +
67.969 + ///Runs Dijkstra algorithm from the given node.
67.970 + ///\param s is the given source.
67.971 + void run(Node s)
67.972 + {
67.973 + Base::_source=s;
67.974 + run();
67.975 + }
67.976 +
67.977 + template<class T>
67.978 + struct DefPredMapBase : public Base {
67.979 + typedef T PredMap;
67.980 + static PredMap *createPredMap(const Graph &) { return 0; };
67.981 + DefPredMapBase(const TR &b) : TR(b) {}
67.982 + };
67.983 +
67.984 + ///\brief \ref named-templ-param "Named parameter"
67.985 + ///function for setting PredMap type
67.986 + ///
67.987 + /// \ref named-templ-param "Named parameter"
67.988 + ///function for setting PredMap type
67.989 + ///
67.990 + template<class T>
67.991 + DijkstraWizard<DefPredMapBase<T> > predMap(const T &t)
67.992 + {
67.993 + Base::_pred=(void *)&t;
67.994 + return DijkstraWizard<DefPredMapBase<T> >(*this);
67.995 + }
67.996 +
67.997 +
67.998 +// template<class T>
67.999 +// struct DefPredNodeMapBase : public Base {
67.1000 +// typedef T PredNodeMap;
67.1001 +// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
67.1002 +// DefPredNodeMapBase(const TR &b) : TR(b) {}
67.1003 +// };
67.1004 +
67.1005 +// ///\brief \ref named-templ-param "Named parameter"
67.1006 +// ///function for setting PredNodeMap type
67.1007 +// ///
67.1008 +// /// \ref named-templ-param "Named parameter"
67.1009 +// ///function for setting PredNodeMap type
67.1010 +// ///
67.1011 +// template<class T>
67.1012 +// DijkstraWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
67.1013 +// {
67.1014 +// Base::_predNode=(void *)&t;
67.1015 +// return DijkstraWizard<DefPredNodeMapBase<T> >(*this);
67.1016 +// }
67.1017 +
67.1018 + template<class T>
67.1019 + struct DefDistMapBase : public Base {
67.1020 + typedef T DistMap;
67.1021 + static DistMap *createDistMap(const Graph &) { return 0; };
67.1022 + DefDistMapBase(const TR &b) : TR(b) {}
67.1023 + };
67.1024 +
67.1025 + ///\brief \ref named-templ-param "Named parameter"
67.1026 + ///function for setting DistMap type
67.1027 + ///
67.1028 + /// \ref named-templ-param "Named parameter"
67.1029 + ///function for setting DistMap type
67.1030 + ///
67.1031 + template<class T>
67.1032 + DijkstraWizard<DefDistMapBase<T> > distMap(const T &t)
67.1033 + {
67.1034 + Base::_dist=(void *)&t;
67.1035 + return DijkstraWizard<DefDistMapBase<T> >(*this);
67.1036 + }
67.1037 +
67.1038 + /// Sets the source node, from which the Dijkstra algorithm runs.
67.1039 +
67.1040 + /// Sets the source node, from which the Dijkstra algorithm runs.
67.1041 + /// \param s is the source node.
67.1042 + DijkstraWizard<TR> &source(Node s)
67.1043 + {
67.1044 + Base::_source=s;
67.1045 + return *this;
67.1046 + }
67.1047 +
67.1048 + };
67.1049 +
67.1050 + ///Function type interface for Dijkstra algorithm.
67.1051 +
67.1052 + /// \ingroup flowalgs
67.1053 + ///Function type interface for Dijkstra algorithm.
67.1054 + ///
67.1055 + ///This function also has several
67.1056 + ///\ref named-templ-func-param "named parameters",
67.1057 + ///they are declared as the members of class \ref DijkstraWizard.
67.1058 + ///The following
67.1059 + ///example shows how to use these parameters.
67.1060 + ///\code
67.1061 + /// dijkstra(g,length,source).predMap(preds).run();
67.1062 + ///\endcode
67.1063 + ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
67.1064 + ///to the end of the parameter list.
67.1065 + ///\sa DijkstraWizard
67.1066 + ///\sa Dijkstra
67.1067 + template<class GR, class LM>
67.1068 + DijkstraWizard<DijkstraWizardBase<GR,LM> >
67.1069 + dijkstra(const GR &g,const LM &l,typename GR::Node s=INVALID)
67.1070 + {
67.1071 + return DijkstraWizard<DijkstraWizardBase<GR,LM> >(g,l,s);
67.1072 + }
67.1073 +
67.1074 +} //END OF NAMESPACE LEMON
67.1075 +
67.1076 +#endif
67.1077 +
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/lemon/dimacs.h Mon May 23 04:48:14 2005 +0000
68.3 @@ -0,0 +1,228 @@
68.4 +/* -*- C++ -*-
68.5 + * lemon/dimacs.h - Part of LEMON, a generic C++ optimization library
68.6 + *
68.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
68.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
68.9 + *
68.10 + * Permission to use, modify and distribute this software is granted
68.11 + * provided that this copyright notice appears in all copies. For
68.12 + * precise terms see the accompanying LICENSE file.
68.13 + *
68.14 + * This software is provided "AS IS" with no warranty of any kind,
68.15 + * express or implied, and with no claim as to its suitability for any
68.16 + * purpose.
68.17 + *
68.18 + */
68.19 +
68.20 +#ifndef LEMON_DIMACS_H
68.21 +#define LEMON_DIMACS_H
68.22 +
68.23 +#include <iostream>
68.24 +#include <string>
68.25 +#include <vector>
68.26 +#include <lemon/maps.h>
68.27 +#include <lemon/invalid.h>
68.28 +
68.29 +/// \ingroup dimacs_group
68.30 +/// \file
68.31 +/// \brief Dimacs file format reader.
68.32 +
68.33 +namespace lemon {
68.34 +
68.35 + ///
68.36 + ///@defgroup dimacs_group DIMACS format
68.37 + ///\brief Read and write files in DIMACS format
68.38 + ///
68.39 + ///Tools to read a graph from or write it to a file in DIMACS format
68.40 + ///data
68.41 + ///\ingroup io_group
68.42 +
68.43 + /// \addtogroup dimacs_group
68.44 + /// @{
68.45 +
68.46 + /// Dimacs min cost flow reader function.
68.47 +
68.48 + /// This function reads a min cost flow instance from dimacs format,
68.49 + /// i.e. from dimacs files having a line starting with
68.50 + /// \code
68.51 + /// p "min"
68.52 + /// \endcode
68.53 + /// At the beginning \c g is cleared by \c g.clear(). The edge
68.54 + /// capacities are written to \c capacity, \c s and \c t are set to
68.55 + /// the source and the target nodes resp. and the cost of the edges
68.56 + /// are written to \c cost.
68.57 + ///
68.58 + /// \author Marton Makai
68.59 + template<typename Graph, typename CapacityMap, typename CostMap>
68.60 + void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
68.61 + typename Graph::Node &s, typename Graph::Node &t,
68.62 + CostMap& cost) {
68.63 + g.clear();
68.64 + typename CapacityMap::Value _cap;
68.65 + typename CostMap::Value _cost;
68.66 + char d;
68.67 + std::string problem;
68.68 + char c;
68.69 + int i, j;
68.70 + std::string str;
68.71 + int n, m;
68.72 + typename Graph::Edge e;
68.73 + std::vector<typename Graph::Node> nodes;
68.74 + while (is>>c) {
68.75 + switch (c) {
68.76 + case 'c': //comment
68.77 + getline(is, str);
68.78 + break;
68.79 + case 'p': //problem definition
68.80 + is >> problem >> n >> m;
68.81 + getline(is, str);
68.82 + nodes.resize(n+1);
68.83 + for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
68.84 + break;
68.85 + case 'n': //node definition
68.86 + if (problem=="sp") { //shortest path problem
68.87 + is >> i;
68.88 + getline(is, str);
68.89 + s=nodes[i];
68.90 + }
68.91 + if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
68.92 + is >> i >> d;
68.93 + getline(is, str);
68.94 + if (d=='s') s=nodes[i];
68.95 + if (d=='t') t=nodes[i];
68.96 + }
68.97 + break;
68.98 + case 'a':
68.99 + if ( problem == "max" || problem == "sp") {
68.100 + is >> i >> j >> _cap;
68.101 + getline(is, str);
68.102 + e=g.addEdge(nodes[i], nodes[j]);
68.103 + //capacity.update();
68.104 + capacity.set(e, _cap);
68.105 + } else {
68.106 + if ( problem == "min" ) {
68.107 + is >> i >> j >> _cap >> _cost;
68.108 + getline(is, str);
68.109 + e=g.addEdge(nodes[i], nodes[j]);
68.110 + //capacity.update();
68.111 + capacity.set(e, _cap);
68.112 + //cost.update();
68.113 + cost.set(e, _cost);
68.114 + } else {
68.115 + is >> i >> j;
68.116 + getline(is, str);
68.117 + g.addEdge(nodes[i], nodes[j]);
68.118 + }
68.119 + }
68.120 + break;
68.121 + }
68.122 + }
68.123 + }
68.124 +
68.125 +
68.126 + /// Dimacs max flow reader function.
68.127 +
68.128 + /// This function reads a max flow instance from dimacs format,
68.129 + /// i.e. from dimacs files having a line starting with
68.130 + /// \code
68.131 + /// p "max"
68.132 + /// \endcode
68.133 + ///At the beginning \c g is cleared by \c g.clear(). The
68.134 + /// edge capacities are written to \c capacity and \c s and \c t are
68.135 + /// set to the source and the target nodes.
68.136 + ///
68.137 + /// \author Marton Makai
68.138 + template<typename Graph, typename CapacityMap>
68.139 + void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
68.140 + typename Graph::Node &s, typename Graph::Node &t) {
68.141 + NullMap<typename Graph::Edge, int> n;
68.142 + readDimacs(is, g, capacity, s, t, n);
68.143 + }
68.144 +
68.145 +
68.146 + /// Dimacs shortest path reader function.
68.147 +
68.148 + /// This function reads a shortest path instance from dimacs format,
68.149 + /// i.e. from dimacs files having a line starting with
68.150 + /// \code
68.151 + /// p "sp"
68.152 + /// \endcode
68.153 + /// At the beginning \c g is cleared by \c g.clear(). The edge
68.154 + /// capacities are written to \c capacity and \c s is set to the
68.155 + /// source node.
68.156 + ///
68.157 + /// \author Marton Makai
68.158 + template<typename Graph, typename CapacityMap>
68.159 + void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
68.160 + typename Graph::Node &s) {
68.161 + NullMap<typename Graph::Edge, int> n;
68.162 + readDimacs(is, g, capacity, s, s, n);
68.163 + }
68.164 +
68.165 +
68.166 + /// Dimacs capacitated graph reader function.
68.167 +
68.168 + /// This function reads an edge capacitated graph instance from
68.169 + /// dimacs format. At the beginning \c g is cleared by \c g.clear()
68.170 + /// and the edge capacities are written to \c capacity.
68.171 + ///
68.172 + /// \author Marton Makai
68.173 + template<typename Graph, typename CapacityMap>
68.174 + void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
68.175 + typename Graph::Node u;
68.176 + NullMap<typename Graph::Edge, int> n;
68.177 + readDimacs(is, g, capacity, u, u, n);
68.178 + }
68.179 +
68.180 +
68.181 + /// Dimacs plain graph reader function.
68.182 +
68.183 + /// This function reads a graph without any designated nodes and
68.184 + /// maps from dimacs format, i.e. from dimacs files having a line
68.185 + /// starting with
68.186 + /// \code
68.187 + /// p "mat"
68.188 + /// \endcode
68.189 + /// At the beginning \c g is cleared
68.190 + /// by \c g.clear().
68.191 + ///
68.192 + /// \author Marton Makai
68.193 + template<typename Graph>
68.194 + void readDimacs(std::istream& is, Graph &g) {
68.195 + typename Graph::Node u;
68.196 + NullMap<typename Graph::Edge, int> n;
68.197 + readDimacs(is, g, n, u, u, n);
68.198 + }
68.199 +
68.200 +
68.201 +
68.202 +
68.203 + /// write matching problem
68.204 + template<typename Graph>
68.205 + void writeDimacs(std::ostream& os, const Graph &g) {
68.206 + typedef typename Graph::NodeIt NodeIt;
68.207 + typedef typename Graph::EdgeIt EdgeIt;
68.208 +
68.209 + typename Graph::template NodeMap<int> nodes(g);
68.210 +
68.211 + os << "c matching problem" << std::endl;
68.212 +
68.213 + int i=1;
68.214 + for(NodeIt v(g); v!=INVALID; ++v) {
68.215 + nodes.set(v, i);
68.216 + ++i;
68.217 + }
68.218 +
68.219 + os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
68.220 +
68.221 + for(EdgeIt e(g); e!=INVALID; ++e) {
68.222 + os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)] << std::endl;
68.223 + }
68.224 +
68.225 + }
68.226 +
68.227 + /// @}
68.228 +
68.229 +} //namespace lemon
68.230 +
68.231 +#endif //LEMON_DIMACS_H
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/lemon/error.h Mon May 23 04:48:14 2005 +0000
69.3 @@ -0,0 +1,539 @@
69.4 +/* -*- C++ -*-
69.5 + * lemon/error.h - Part of LEMON, a generic C++ optimization library
69.6 + *
69.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
69.8 + * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
69.9 + * EGRES).
69.10 + *
69.11 + * Permission to use, modify and distribute this software is granted
69.12 + * provided that this copyright notice appears in all copies. For
69.13 + * precise terms see the accompanying LICENSE file.
69.14 + *
69.15 + * This software is provided "AS IS" with no warranty of any kind,
69.16 + * express or implied, and with no claim as to its suitability for any
69.17 + * purpose.
69.18 + *
69.19 + */
69.20 +
69.21 +#ifndef LEMON_ERROR_H
69.22 +#define LEMON_ERROR_H
69.23 +
69.24 +//! \ingroup exceptions
69.25 +//! \file
69.26 +//! \brief Basic exception classes and error handling.
69.27 +
69.28 +#include <exception>
69.29 +#include <string>
69.30 +#include <sstream>
69.31 +#include <iostream>
69.32 +#include <cstdlib>
69.33 +#include <memory>
69.34 +
69.35 +namespace lemon {
69.36 +
69.37 + /// \addtogroup exceptions
69.38 + /// @{
69.39 +
69.40 + /// \brief Exception safe wrapper class.
69.41 + ///
69.42 + /// Exception safe wrapper class to implement the members of exceptions.
69.43 + template <typename _Type>
69.44 + class ExceptionMember {
69.45 + public:
69.46 + typedef _Type Type;
69.47 +
69.48 + ExceptionMember() throw () {
69.49 + try {
69.50 + ptr.reset(new Type());
69.51 + } catch (...) {}
69.52 + }
69.53 +
69.54 + ExceptionMember(const Type& type) throw () {
69.55 + try {
69.56 + ptr.reset(new Type());
69.57 + if (ptr.get() == 0) return;
69.58 + *ptr = type;
69.59 + } catch (...) {}
69.60 + }
69.61 +
69.62 + ExceptionMember(const ExceptionMember& copy) throw() {
69.63 + try {
69.64 + if (!copy.valid()) return;
69.65 + ptr.reset(new Type());
69.66 + if (ptr.get() == 0) return;
69.67 + *ptr = copy.get();
69.68 + } catch (...) {}
69.69 + }
69.70 +
69.71 + ExceptionMember& operator=(const ExceptionMember& copy) {
69.72 + if (ptr.get() == 0) return;
69.73 + try {
69.74 + if (!copy.valid()) return;
69.75 + *ptr = copy.get();
69.76 + } catch (...) {}
69.77 + }
69.78 +
69.79 + void set(const Type& type) {
69.80 + if (ptr.get() == 0) return;
69.81 + try {
69.82 + *ptr = type;
69.83 + } catch (...) {}
69.84 + }
69.85 +
69.86 + const Type& get() const {
69.87 + return *ptr;
69.88 + }
69.89 +
69.90 + bool valid() const {
69.91 + return ptr.get() != 0;
69.92 + }
69.93 +
69.94 + private:
69.95 + std::auto_ptr<_Type> ptr;
69.96 + };
69.97 +
69.98 + /// Exception-safe convenient "error message" class.
69.99 +
69.100 + /// Helper class which provides a convenient ostream-like (operator <<
69.101 + /// based) interface to create a string message. Mostly useful in
69.102 + /// exception classes (therefore the name).
69.103 + class ErrorMessage {
69.104 + protected:
69.105 + ///\e
69.106 + ///\todo The good solution is boost:shared_ptr...
69.107 + mutable
69.108 + std::auto_ptr<std::ostringstream> buf;
69.109 +
69.110 + ///\e
69.111 + bool init() throw() {
69.112 + try {
69.113 + buf.reset(new std::ostringstream);
69.114 + }
69.115 + catch(...) {
69.116 + buf.reset();
69.117 + }
69.118 + return buf.get();
69.119 + }
69.120 +
69.121 + public:
69.122 +
69.123 + ///\e
69.124 + ErrorMessage() throw() { init(); }
69.125 +
69.126 + ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
69.127 +
69.128 + ///\e
69.129 + ErrorMessage(const char *message) throw() {
69.130 + init();
69.131 + *this << message;
69.132 + }
69.133 +
69.134 + ///\e
69.135 + ErrorMessage(const std::string &message) throw() {
69.136 + init();
69.137 + *this << message;
69.138 + }
69.139 +
69.140 + ///\e
69.141 + template <typename T>
69.142 + ErrorMessage& operator<<(const T &t) throw() {
69.143 + if( ! buf.get() ) return *this;
69.144 +
69.145 + try {
69.146 + *buf << t;
69.147 + }
69.148 + catch(...) {
69.149 + buf.reset();
69.150 + }
69.151 + return *this;
69.152 + }
69.153 +
69.154 + ///\e
69.155 + const char* message() throw() {
69.156 + if( ! buf.get() ) return 0;
69.157 +
69.158 + const char* mes = 0;
69.159 + try {
69.160 + mes = buf->str().c_str();
69.161 + }
69.162 + catch(...) {}
69.163 + return mes;
69.164 + }
69.165 +
69.166 + };
69.167 +
69.168 + /**
69.169 + * \brief Generic exception class.
69.170 + *
69.171 + * Base class for exceptions used in LEMON.
69.172 + */
69.173 + class Exception : public std::exception {
69.174 + public:
69.175 + ///\e
69.176 + Exception() {}
69.177 + ///\e
69.178 + virtual ~Exception() throw() {}
69.179 +
69.180 + ///\e
69.181 + virtual const char* exceptionName() const {
69.182 + return "lemon::Exception";
69.183 + }
69.184 +
69.185 + ///\e
69.186 + virtual const char* what() const throw() {
69.187 + return exceptionName();
69.188 + }
69.189 + };
69.190 +
69.191 + /**
69.192 + * \brief One of the two main subclasses of \ref Exception.
69.193 + *
69.194 + * Logic errors represent problems in the internal logic of a program;
69.195 + * in theory, these are preventable, and even detectable before the
69.196 + * program runs (e.g., violations of class invariants).
69.197 + *
69.198 + * A typical example for this is \ref UninitializedParameter.
69.199 + */
69.200 + class LogicError : public Exception {
69.201 + public:
69.202 + virtual const char* exceptionName() const {
69.203 + return "lemon::LogicError";
69.204 + }
69.205 + };
69.206 +
69.207 + /**
69.208 + * \brief \ref Exception for uninitialized parameters.
69.209 + *
69.210 + * This error represents problems in the initialization
69.211 + * of the parameters of the algorithms.
69.212 + */
69.213 + class UninitializedParameter : public LogicError {
69.214 + public:
69.215 + virtual const char* exceptionName() const {
69.216 + return "lemon::UninitializedParameter";
69.217 + }
69.218 + };
69.219 +
69.220 +
69.221 + /**
69.222 + * \brief One of the two main subclasses of \ref Exception.
69.223 + *
69.224 + * Runtime errors represent problems outside the scope of a program;
69.225 + * they cannot be easily predicted and can generally only be caught as
69.226 + * the program executes.
69.227 + */
69.228 + class RuntimeError : public Exception {
69.229 + public:
69.230 + virtual const char* exceptionName() const {
69.231 + return "lemon::RuntimeError";
69.232 + }
69.233 + };
69.234 +
69.235 + ///\e
69.236 + class RangeError : public RuntimeError {
69.237 + public:
69.238 + virtual const char* exceptionName() const {
69.239 + return "lemon::RangeError";
69.240 + }
69.241 + };
69.242 +
69.243 + ///\e
69.244 + class IOError : public RuntimeError {
69.245 + public:
69.246 + virtual const char* exceptionName() const {
69.247 + return "lemon::IOError";
69.248 + }
69.249 + };
69.250 +
69.251 + ///\e
69.252 + class DataFormatError : public IOError {
69.253 + protected:
69.254 + ExceptionMember<std::string> _message;
69.255 + ExceptionMember<std::string> _file;
69.256 + int _line;
69.257 +
69.258 + mutable ExceptionMember<std::string> _message_holder;
69.259 + public:
69.260 +
69.261 + DataFormatError(const DataFormatError &dfe) :
69.262 + IOError(dfe), _message(dfe._message), _file(dfe._file),
69.263 + _line(dfe._line) {}
69.264 +
69.265 + ///\e
69.266 + explicit DataFormatError(const char *the_message)
69.267 + : _message(the_message), _line(0) {}
69.268 +
69.269 + ///\e
69.270 + DataFormatError(const std::string &file_name, int line_num,
69.271 + const char *the_message)
69.272 + : _message(the_message), _line(line_num) { file(file_name); }
69.273 +
69.274 + ///\e
69.275 + void line(int line) { _line = line; }
69.276 + ///\e
69.277 + void message(const std::string& message) { _message.set(message); }
69.278 + ///\e
69.279 + void file(const std::string &file) { _file.set(file); }
69.280 +
69.281 + ///\e
69.282 + int line() const { return _line; }
69.283 + ///\e
69.284 + const char* message() const {
69.285 + if (_message.valid() && !_message.get().empty()) {
69.286 + return _message.get().c_str();
69.287 + } else {
69.288 + return 0;
69.289 + }
69.290 + }
69.291 +
69.292 + /// \brief Returns the filename.
69.293 + ///
69.294 + /// Returns \e null if the filename was not specified.
69.295 + const char* file() const {
69.296 + if (_file.valid() && !_file.get().empty()) {
69.297 + return _file.get().c_str();
69.298 + } else {
69.299 + return 0;
69.300 + }
69.301 + }
69.302 +
69.303 + ///\e
69.304 + virtual const char* what() const throw() {
69.305 + try {
69.306 + std::ostringstream ostr;
69.307 + ostr << exceptionName() << ": ";
69.308 + if (message()) ostr << message();
69.309 + if( file() || line() != 0 ) {
69.310 + ostr << " (";
69.311 + if( file() ) ostr << "in file '" << file() << "'";
69.312 + if( file() && line() != 0 ) ostr << " ";
69.313 + if( line() != 0 ) ostr << "at line " << line();
69.314 + ostr << ")";
69.315 + }
69.316 + _message_holder.set(ostr.str());
69.317 + }
69.318 + catch (...) {}
69.319 + if( _message_holder.valid()) return _message_holder.get().c_str();
69.320 + return exceptionName();
69.321 + }
69.322 +
69.323 + virtual const char* exceptionName() const {
69.324 + return "lemon::DataFormatError";
69.325 + }
69.326 +
69.327 + virtual ~DataFormatError() throw() {}
69.328 + };
69.329 +
69.330 + class IOParameterError : public LogicError {
69.331 + protected:
69.332 + ExceptionMember<std::string> _message;
69.333 + ExceptionMember<std::string> _file;
69.334 +
69.335 + mutable ExceptionMember<std::string> _message_holder;
69.336 + public:
69.337 +
69.338 + IOParameterError(const IOParameterError &ile) :
69.339 + LogicError(ile), _message(ile._message), _file(ile._file) {}
69.340 +
69.341 + ///\e
69.342 + explicit IOParameterError(const char *the_message)
69.343 + : _message(the_message) {}
69.344 +
69.345 + ///\e
69.346 + IOParameterError(const char *file_name, const char *the_message)
69.347 + : _message(the_message), _file(file_name) {}
69.348 +
69.349 + ///\e
69.350 + void message(const std::string& message) { _message.set(message); }
69.351 + ///\e
69.352 + void file(const std::string &file) { _file.set(file); }
69.353 +
69.354 + ///\e
69.355 + const char* message() const {
69.356 + if (_message.valid()) {
69.357 + return _message.get().c_str();
69.358 + } else {
69.359 + return 0;
69.360 + }
69.361 + }
69.362 +
69.363 + /// \brief Returns the filename.
69.364 + ///
69.365 + /// Returns \e null if the filename was not specified.
69.366 + const char* file() const {
69.367 + if (_file.valid()) {
69.368 + return _file.get().c_str();
69.369 + } else {
69.370 + return 0;
69.371 + }
69.372 + }
69.373 +
69.374 + ///\e
69.375 + virtual const char* what() const throw() {
69.376 + try {
69.377 + std::ostringstream ostr;
69.378 + if (message()) ostr << message();
69.379 + if (file()) ostr << "(when reading file '" << file() << "')";
69.380 + _message_holder.set(ostr.str());
69.381 + }
69.382 + catch (...) {}
69.383 + if( _message_holder.valid() ) return _message_holder.get().c_str();
69.384 + return exceptionName();
69.385 + }
69.386 +
69.387 + virtual const char* exceptionName() const {
69.388 + return "lemon::IOParameterError";
69.389 + }
69.390 +
69.391 + virtual ~IOParameterError() throw() {}
69.392 + };
69.393 +
69.394 +
69.395 + ///\e
69.396 + class AssertionFailedError : public LogicError {
69.397 + protected:
69.398 + const char *assertion;
69.399 + const char *file;
69.400 + int line;
69.401 + const char *function;
69.402 + const char *message;
69.403 +
69.404 + mutable ExceptionMember<std::string> _message_holder;
69.405 + public:
69.406 + ///\e
69.407 + AssertionFailedError(const char *_file, int _line, const char *func,
69.408 + const char *msg, const char *_assertion = 0) :
69.409 + assertion(_assertion), file(_file), line(_line), function(func),
69.410 + message(msg) {}
69.411 +
69.412 + ///\e
69.413 + const char* get_assertion() const { return assertion; }
69.414 + ///\e
69.415 + const char* get_message() const { return message; }
69.416 + ///\e
69.417 + const char* get_file() const { return file; }
69.418 + ///\e
69.419 + const char* get_function() const { return function; }
69.420 + ///\e
69.421 + int get_line() const { return line; }
69.422 +
69.423 +
69.424 + virtual const char* what() const throw() {
69.425 + try {
69.426 + std::ostringstream ostr;
69.427 + ostr << file << ":" << line << ": ";
69.428 + if( function )
69.429 + ostr << function << ": ";
69.430 + ostr << message;
69.431 + if( assertion )
69.432 + ostr << " (assertion '" << assertion << "' failed)";
69.433 + _message_holder.set(ostr.str());
69.434 + return ostr.str().c_str();
69.435 + }
69.436 + catch(...) {}
69.437 + if( _message_holder.valid() ) return _message_holder.get().c_str();
69.438 + return exceptionName();
69.439 + }
69.440 +
69.441 + virtual const char* exceptionName() const {
69.442 + return "lemon::AssertionFailedError";
69.443 + }
69.444 +
69.445 + virtual ~AssertionFailedError() throw() {}
69.446 + };
69.447 +
69.448 +
69.449 + /**************** Macros ****************/
69.450 +
69.451 +
69.452 + inline
69.453 + void assert_fail(const char *file, int line, const char *func,
69.454 + const char *message, const char *assertion = 0,
69.455 + bool do_abort=true)
69.456 + {
69.457 + using namespace std;
69.458 + cerr << file << ":" << line << ": ";
69.459 + if( func )
69.460 + cerr << func << ": ";
69.461 + cerr << message;
69.462 + if( assertion )
69.463 + cerr << " (assertion '" << assertion << "' failed)";
69.464 + cerr << endl;
69.465 + if(do_abort)
69.466 + abort();
69.467 + }
69.468 +
69.469 + inline
69.470 + void assert_fail_throw(const char *file, int line, const char *func,
69.471 + const char *message, const char *assertion = 0,
69.472 + bool = true)
69.473 + {
69.474 + throw AssertionFailedError(file, line, func, message, assertion);
69.475 + }
69.476 +
69.477 +/// @}
69.478 +
69.479 +}
69.480 +#endif // LEMON_ERROR_H
69.481 +
69.482 +#undef LEMON_ASSERT
69.483 +#undef LEMON_FIXME
69.484 +
69.485 +#ifndef LEMON_ASSERT_ABORT
69.486 +# define LEMON_ASSERT_ABORT 1
69.487 +#endif
69.488 +
69.489 +#ifndef LEMON_ASSERT_HANDLER
69.490 +# ifdef LEMON_ASSERT_EXCEPTION
69.491 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
69.492 +# else
69.493 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
69.494 +# endif
69.495 +#endif
69.496 +
69.497 +#if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
69.498 +
69.499 +# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
69.500 +
69.501 +#else
69.502 +
69.503 +/**
69.504 + * \brief Macro for assertions with customizable message
69.505 + *
69.506 + * Macro for assertions with customizable message.
69.507 + *
69.508 + * The behaviour can be customized with LEMON_ASSERT_HANDLER,
69.509 + * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
69.510 + * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
69.511 + *
69.512 + * \todo We should provide some way to reset to the default behaviour,
69.513 + * shouldn't we?
69.514 + *
69.515 + * \todo This whole 'assert' business should be placed in a separate
69.516 + * include file.
69.517 + *
69.518 + * \todo __PRETTY_FUNCTION__ should be replaced by something
69.519 + * compiler-independent, like BOOST_CURRENT_FUNCTION
69.520 + */
69.521 +
69.522 +# define LEMON_ASSERT(exp, msg) \
69.523 + (static_cast<void> (!!(exp) ? 0 : ( \
69.524 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
69.525 + __PRETTY_FUNCTION__, \
69.526 + (msg), #exp, LEMON_ASSERT_ABORT), 0)))
69.527 +
69.528 +#endif // NDEBUG || LEMON_DISABLE_ASSERTS
69.529 +
69.530 +/**
69.531 + * \brief Macro for mark not yet implemented features.
69.532 + *
69.533 + * \todo Is this the right place for this? It should be used only in
69.534 + * modules under development.
69.535 + *
69.536 + * \todo __PRETTY_FUNCTION__ should be replaced by something
69.537 + * compiler-independent, like BOOST_CURRENT_FUNCTION
69.538 + */
69.539 +
69.540 +# define LEMON_FIXME(msg) \
69.541 + (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
69.542 + "FIXME: " msg))
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/lemon/fib_heap.h Mon May 23 04:48:14 2005 +0000
70.3 @@ -0,0 +1,531 @@
70.4 +/* -*- C++ -*-
70.5 + * lemon/fib_heap.h - Part of LEMON, a generic C++ optimization library
70.6 + *
70.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
70.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
70.9 + *
70.10 + * Permission to use, modify and distribute this software is granted
70.11 + * provided that this copyright notice appears in all copies. For
70.12 + * precise terms see the accompanying LICENSE file.
70.13 + *
70.14 + * This software is provided "AS IS" with no warranty of any kind,
70.15 + * express or implied, and with no claim as to its suitability for any
70.16 + * purpose.
70.17 + *
70.18 + */
70.19 +
70.20 +#ifndef LEMON_FIB_HEAP_H
70.21 +#define LEMON_FIB_HEAP_H
70.22 +
70.23 +///\file
70.24 +///\ingroup auxdat
70.25 +///\brief Fibonacci Heap implementation.
70.26 +
70.27 +#include <vector>
70.28 +#include <functional>
70.29 +#include <cmath>
70.30 +
70.31 +namespace lemon {
70.32 +
70.33 + /// \addtogroup auxdat
70.34 + /// @{
70.35 +
70.36 + /// Fibonacci Heap.
70.37 +
70.38 + ///This class implements the \e Fibonacci \e heap data structure. A \e heap
70.39 + ///is a data structure for storing items with specified values called \e
70.40 + ///priorities in such a way that finding the item with minimum priority is
70.41 + ///efficient. \c Compare specifies the ordering of the priorities. In a heap
70.42 + ///one can change the priority of an item, add or erase an item, etc.
70.43 + ///
70.44 + ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
70.45 + ///heap. In case of many calls to these operations, it is better to use a
70.46 + ///\e binary \e heap.
70.47 + ///
70.48 + ///\param Item Type of the items to be stored.
70.49 + ///\param Prio Type of the priority of the items.
70.50 + ///\param ItemIntMap A read and writable Item int map, used internally
70.51 + ///to handle the cross references.
70.52 + ///\param Compare A class for the ordering of the priorities. The
70.53 + ///default is \c std::less<Prio>.
70.54 + ///
70.55 + ///\sa BinHeap
70.56 + ///\sa Dijkstra
70.57 + ///\author Jacint Szabo
70.58 +
70.59 +#ifdef DOXYGEN
70.60 + template <typename Item,
70.61 + typename Prio,
70.62 + typename ItemIntMap,
70.63 + typename Compare>
70.64 +#else
70.65 + template <typename Item,
70.66 + typename Prio,
70.67 + typename ItemIntMap,
70.68 + typename Compare = std::less<Prio> >
70.69 +#endif
70.70 + class FibHeap {
70.71 + public:
70.72 + typedef Prio PrioType;
70.73 +
70.74 + private:
70.75 + class store;
70.76 +
70.77 + std::vector<store> container;
70.78 + int minimum;
70.79 + ItemIntMap &iimap;
70.80 + Compare comp;
70.81 + int num_items;
70.82 +
70.83 + public:
70.84 + ///Status of the nodes
70.85 + enum state_enum {
70.86 + ///The node is in the heap
70.87 + IN_HEAP = 0,
70.88 + ///The node has never been in the heap
70.89 + PRE_HEAP = -1,
70.90 + ///The node was in the heap but it got out of it
70.91 + POST_HEAP = -2
70.92 + };
70.93 +
70.94 + ///The constructor
70.95 +
70.96 + /**
70.97 + \c _iimap should be given to the constructor, since it is
70.98 + used internally to handle the cross references.
70.99 + */
70.100 + explicit FibHeap(ItemIntMap &_iimap)
70.101 + : minimum(0), iimap(_iimap), num_items() {}
70.102 +
70.103 + ///The constructor
70.104 +
70.105 + /**
70.106 + \c _iimap should be given to the constructor, since it is used
70.107 + internally to handle the cross references. \c _comp is an
70.108 + object for ordering of the priorities.
70.109 + */
70.110 + FibHeap(ItemIntMap &_iimap, const Compare &_comp) : minimum(0),
70.111 + iimap(_iimap), comp(_comp), num_items() {}
70.112 +
70.113 + ///The number of items stored in the heap.
70.114 +
70.115 + /**
70.116 + Returns the number of items stored in the heap.
70.117 + */
70.118 + int size() const { return num_items; }
70.119 +
70.120 + ///Checks if the heap stores no items.
70.121 +
70.122 + /**
70.123 + Returns \c true if and only if the heap stores no items.
70.124 + */
70.125 + bool empty() const { return num_items==0; }
70.126 +
70.127 + ///\c item gets to the heap with priority \c value independently if \c item was already there.
70.128 +
70.129 + /**
70.130 + This method calls \ref push(\c item, \c value) if \c item is not
70.131 + stored in the heap and it calls \ref decrease(\c item, \c value) or
70.132 + \ref increase(\c item, \c value) otherwise.
70.133 + */
70.134 + void set (Item const item, PrioType const value);
70.135 +
70.136 + ///Adds \c item to the heap with priority \c value.
70.137 +
70.138 + /**
70.139 + Adds \c item to the heap with priority \c value.
70.140 + \pre \c item must not be stored in the heap.
70.141 + */
70.142 + void push (Item const item, PrioType const value);
70.143 +
70.144 + ///Returns the item with minimum priority relative to \c Compare.
70.145 +
70.146 + /**
70.147 + This method returns the item with minimum priority relative to \c
70.148 + Compare.
70.149 + \pre The heap must be nonempty.
70.150 + */
70.151 + Item top() const { return container[minimum].name; }
70.152 +
70.153 + ///Returns the minimum priority relative to \c Compare.
70.154 +
70.155 + /**
70.156 + It returns the minimum priority relative to \c Compare.
70.157 + \pre The heap must be nonempty.
70.158 + */
70.159 + PrioType prio() const { return container[minimum].prio; }
70.160 +
70.161 + ///Returns the priority of \c item.
70.162 +
70.163 + /**
70.164 + This function returns the priority of \c item.
70.165 + \pre \c item must be in the heap.
70.166 + */
70.167 + PrioType& operator[](const Item& item) {
70.168 + return container[iimap[item]].prio;
70.169 + }
70.170 +
70.171 + ///Returns the priority of \c item.
70.172 +
70.173 + /**
70.174 + It returns the priority of \c item.
70.175 + \pre \c item must be in the heap.
70.176 + */
70.177 + const PrioType& operator[](const Item& item) const {
70.178 + return container[iimap[item]].prio;
70.179 + }
70.180 +
70.181 +
70.182 + ///Deletes the item with minimum priority relative to \c Compare.
70.183 +
70.184 + /**
70.185 + This method deletes the item with minimum priority relative to \c
70.186 + Compare from the heap.
70.187 + \pre The heap must be non-empty.
70.188 + */
70.189 + void pop();
70.190 +
70.191 + ///Deletes \c item from the heap.
70.192 +
70.193 + /**
70.194 + This method deletes \c item from the heap, if \c item was already
70.195 + stored in the heap. It is quite inefficient in Fibonacci heaps.
70.196 + */
70.197 + void erase (const Item& item);
70.198 +
70.199 + ///Decreases the priority of \c item to \c value.
70.200 +
70.201 + /**
70.202 + This method decreases the priority of \c item to \c value.
70.203 + \pre \c item must be stored in the heap with priority at least \c
70.204 + value relative to \c Compare.
70.205 + */
70.206 + void decrease (Item item, PrioType const value);
70.207 +
70.208 + ///Increases the priority of \c item to \c value.
70.209 +
70.210 + /**
70.211 + This method sets the priority of \c item to \c value. Though
70.212 + there is no precondition on the priority of \c item, this
70.213 + method should be used only if it is indeed necessary to increase
70.214 + (relative to \c Compare) the priority of \c item, because this
70.215 + method is inefficient.
70.216 + */
70.217 + void increase (Item item, PrioType const value) {
70.218 + erase(item);
70.219 + push(item, value);
70.220 + }
70.221 +
70.222 +
70.223 + ///Returns if \c item is in, has already been in, or has never been in the heap.
70.224 +
70.225 + /**
70.226 + This method returns PRE_HEAP if \c item has never been in the
70.227 + heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
70.228 + otherwise. In the latter case it is possible that \c item will
70.229 + get back to the heap again.
70.230 + */
70.231 + state_enum state(const Item &item) const {
70.232 + int i=iimap[item];
70.233 + if( i>=0 ) {
70.234 + if ( container[i].in ) i=0;
70.235 + else i=-2;
70.236 + }
70.237 + return state_enum(i);
70.238 + }
70.239 +
70.240 + private:
70.241 +
70.242 + void balance();
70.243 + void makeroot(int c);
70.244 + void cut(int a, int b);
70.245 + void cascade(int a);
70.246 + void fuse(int a, int b);
70.247 + void unlace(int a);
70.248 +
70.249 +
70.250 + class store {
70.251 + friend class FibHeap;
70.252 +
70.253 + Item name;
70.254 + int parent;
70.255 + int left_neighbor;
70.256 + int right_neighbor;
70.257 + int child;
70.258 + int degree;
70.259 + bool marked;
70.260 + bool in;
70.261 + PrioType prio;
70.262 +
70.263 + store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
70.264 + };
70.265 + };
70.266 +
70.267 +
70.268 +
70.269 + // **********************************************************************
70.270 + // IMPLEMENTATIONS
70.271 + // **********************************************************************
70.272 +
70.273 + template <typename Item, typename Prio, typename ItemIntMap,
70.274 + typename Compare>
70.275 + void FibHeap<Item, Prio, ItemIntMap, Compare>::set
70.276 + (Item const item, PrioType const value)
70.277 + {
70.278 + int i=iimap[item];
70.279 + if ( i >= 0 && container[i].in ) {
70.280 + if ( comp(value, container[i].prio) ) decrease(item, value);
70.281 + if ( comp(container[i].prio, value) ) increase(item, value);
70.282 + } else push(item, value);
70.283 + }
70.284 +
70.285 + template <typename Item, typename Prio, typename ItemIntMap,
70.286 + typename Compare>
70.287 + void FibHeap<Item, Prio, ItemIntMap, Compare>::push
70.288 + (Item const item, PrioType const value) {
70.289 + int i=iimap[item];
70.290 + if ( i < 0 ) {
70.291 + int s=container.size();
70.292 + iimap.set( item, s );
70.293 + store st;
70.294 + st.name=item;
70.295 + container.push_back(st);
70.296 + i=s;
70.297 + } else {
70.298 + container[i].parent=container[i].child=-1;
70.299 + container[i].degree=0;
70.300 + container[i].in=true;
70.301 + container[i].marked=false;
70.302 + }
70.303 +
70.304 + if ( num_items ) {
70.305 + container[container[minimum].right_neighbor].left_neighbor=i;
70.306 + container[i].right_neighbor=container[minimum].right_neighbor;
70.307 + container[minimum].right_neighbor=i;
70.308 + container[i].left_neighbor=minimum;
70.309 + if ( comp( value, container[minimum].prio) ) minimum=i;
70.310 + } else {
70.311 + container[i].right_neighbor=container[i].left_neighbor=i;
70.312 + minimum=i;
70.313 + }
70.314 + container[i].prio=value;
70.315 + ++num_items;
70.316 + }
70.317 +
70.318 + template <typename Item, typename Prio, typename ItemIntMap,
70.319 + typename Compare>
70.320 + void FibHeap<Item, Prio, ItemIntMap, Compare>::pop() {
70.321 + /*The first case is that there are only one root.*/
70.322 + if ( container[minimum].left_neighbor==minimum ) {
70.323 + container[minimum].in=false;
70.324 + if ( container[minimum].degree!=0 ) {
70.325 + makeroot(container[minimum].child);
70.326 + minimum=container[minimum].child;
70.327 + balance();
70.328 + }
70.329 + } else {
70.330 + int right=container[minimum].right_neighbor;
70.331 + unlace(minimum);
70.332 + container[minimum].in=false;
70.333 + if ( container[minimum].degree > 0 ) {
70.334 + int left=container[minimum].left_neighbor;
70.335 + int child=container[minimum].child;
70.336 + int last_child=container[child].left_neighbor;
70.337 +
70.338 + makeroot(child);
70.339 +
70.340 + container[left].right_neighbor=child;
70.341 + container[child].left_neighbor=left;
70.342 + container[right].left_neighbor=last_child;
70.343 + container[last_child].right_neighbor=right;
70.344 + }
70.345 + minimum=right;
70.346 + balance();
70.347 + } // the case where there are more roots
70.348 + --num_items;
70.349 + }
70.350 +
70.351 +
70.352 + template <typename Item, typename Prio, typename ItemIntMap,
70.353 + typename Compare>
70.354 + void FibHeap<Item, Prio, ItemIntMap, Compare>::erase
70.355 + (const Item& item) {
70.356 + int i=iimap[item];
70.357 +
70.358 + if ( i >= 0 && container[i].in ) {
70.359 + if ( container[i].parent!=-1 ) {
70.360 + int p=container[i].parent;
70.361 + cut(i,p);
70.362 + cascade(p);
70.363 + }
70.364 + minimum=i; //As if its prio would be -infinity
70.365 + pop();
70.366 + }
70.367 + }
70.368 +
70.369 + template <typename Item, typename Prio, typename ItemIntMap,
70.370 + typename Compare>
70.371 + void FibHeap<Item, Prio, ItemIntMap, Compare>::decrease
70.372 + (Item item, PrioType const value) {
70.373 + int i=iimap[item];
70.374 + container[i].prio=value;
70.375 + int p=container[i].parent;
70.376 +
70.377 + if ( p!=-1 && comp(value, container[p].prio) ) {
70.378 + cut(i,p);
70.379 + cascade(p);
70.380 + }
70.381 + if ( comp(value, container[minimum].prio) ) minimum=i;
70.382 + }
70.383 +
70.384 +
70.385 + template <typename Item, typename Prio, typename ItemIntMap,
70.386 + typename Compare>
70.387 + void FibHeap<Item, Prio, ItemIntMap, Compare>::balance() {
70.388 +
70.389 + int maxdeg=int( std::floor( 2.08*log(double(container.size()))))+1;
70.390 +
70.391 + std::vector<int> A(maxdeg,-1);
70.392 +
70.393 + /*
70.394 + *Recall that now minimum does not point to the minimum prio element.
70.395 + *We set minimum to this during balance().
70.396 + */
70.397 + int anchor=container[minimum].left_neighbor;
70.398 + int next=minimum;
70.399 + bool end=false;
70.400 +
70.401 + do {
70.402 + int active=next;
70.403 + if ( anchor==active ) end=true;
70.404 + int d=container[active].degree;
70.405 + next=container[active].right_neighbor;
70.406 +
70.407 + while (A[d]!=-1) {
70.408 + if( comp(container[active].prio, container[A[d]].prio) ) {
70.409 + fuse(active,A[d]);
70.410 + } else {
70.411 + fuse(A[d],active);
70.412 + active=A[d];
70.413 + }
70.414 + A[d]=-1;
70.415 + ++d;
70.416 + }
70.417 + A[d]=active;
70.418 + } while ( !end );
70.419 +
70.420 +
70.421 + while ( container[minimum].parent >=0 ) minimum=container[minimum].parent;
70.422 + int s=minimum;
70.423 + int m=minimum;
70.424 + do {
70.425 + if ( comp(container[s].prio, container[minimum].prio) ) minimum=s;
70.426 + s=container[s].right_neighbor;
70.427 + } while ( s != m );
70.428 + }
70.429 +
70.430 + template <typename Item, typename Prio, typename ItemIntMap,
70.431 + typename Compare>
70.432 + void FibHeap<Item, Prio, ItemIntMap, Compare>::makeroot
70.433 + (int c) {
70.434 + int s=c;
70.435 + do {
70.436 + container[s].parent=-1;
70.437 + s=container[s].right_neighbor;
70.438 + } while ( s != c );
70.439 + }
70.440 +
70.441 +
70.442 + template <typename Item, typename Prio, typename ItemIntMap,
70.443 + typename Compare>
70.444 + void FibHeap<Item, Prio, ItemIntMap, Compare>::cut
70.445 + (int a, int b) {
70.446 + /*
70.447 + *Replacing a from the children of b.
70.448 + */
70.449 + --container[b].degree;
70.450 +
70.451 + if ( container[b].degree !=0 ) {
70.452 + int child=container[b].child;
70.453 + if ( child==a )
70.454 + container[b].child=container[child].right_neighbor;
70.455 + unlace(a);
70.456 + }
70.457 +
70.458 +
70.459 + /*Lacing a to the roots.*/
70.460 + int right=container[minimum].right_neighbor;
70.461 + container[minimum].right_neighbor=a;
70.462 + container[a].left_neighbor=minimum;
70.463 + container[a].right_neighbor=right;
70.464 + container[right].left_neighbor=a;
70.465 +
70.466 + container[a].parent=-1;
70.467 + container[a].marked=false;
70.468 + }
70.469 +
70.470 +
70.471 + template <typename Item, typename Prio, typename ItemIntMap,
70.472 + typename Compare>
70.473 + void FibHeap<Item, Prio, ItemIntMap, Compare>::cascade
70.474 + (int a)
70.475 + {
70.476 + if ( container[a].parent!=-1 ) {
70.477 + int p=container[a].parent;
70.478 +
70.479 + if ( container[a].marked==false ) container[a].marked=true;
70.480 + else {
70.481 + cut(a,p);
70.482 + cascade(p);
70.483 + }
70.484 + }
70.485 + }
70.486 +
70.487 +
70.488 + template <typename Item, typename Prio, typename ItemIntMap,
70.489 + typename Compare>
70.490 + void FibHeap<Item, Prio, ItemIntMap, Compare>::fuse
70.491 + (int a, int b) {
70.492 + unlace(b);
70.493 +
70.494 + /*Lacing b under a.*/
70.495 + container[b].parent=a;
70.496 +
70.497 + if (container[a].degree==0) {
70.498 + container[b].left_neighbor=b;
70.499 + container[b].right_neighbor=b;
70.500 + container[a].child=b;
70.501 + } else {
70.502 + int child=container[a].child;
70.503 + int last_child=container[child].left_neighbor;
70.504 + container[child].left_neighbor=b;
70.505 + container[b].right_neighbor=child;
70.506 + container[last_child].right_neighbor=b;
70.507 + container[b].left_neighbor=last_child;
70.508 + }
70.509 +
70.510 + ++container[a].degree;
70.511 +
70.512 + container[b].marked=false;
70.513 + }
70.514 +
70.515 +
70.516 + /*
70.517 + *It is invoked only if a has siblings.
70.518 + */
70.519 + template <typename Item, typename Prio, typename ItemIntMap,
70.520 + typename Compare>
70.521 + void FibHeap<Item, Prio, ItemIntMap, Compare>::unlace
70.522 + (int a) {
70.523 + int leftn=container[a].left_neighbor;
70.524 + int rightn=container[a].right_neighbor;
70.525 + container[leftn].right_neighbor=rightn;
70.526 + container[rightn].left_neighbor=leftn;
70.527 + }
70.528 +
70.529 + ///@}
70.530 +
70.531 +} //namespace lemon
70.532 +
70.533 +#endif //LEMON_FIB_HEAP_H
70.534 +
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/lemon/full_graph.h Mon May 23 04:48:14 2005 +0000
71.3 @@ -0,0 +1,385 @@
71.4 +/* -*- C++ -*-
71.5 + * lemon/full_graph.h - Part of LEMON, a generic C++ optimization library
71.6 + *
71.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
71.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
71.9 + *
71.10 + * Permission to use, modify and distribute this software is granted
71.11 + * provided that this copyright notice appears in all copies. For
71.12 + * precise terms see the accompanying LICENSE file.
71.13 + *
71.14 + * This software is provided "AS IS" with no warranty of any kind,
71.15 + * express or implied, and with no claim as to its suitability for any
71.16 + * purpose.
71.17 + *
71.18 + */
71.19 +
71.20 +#ifndef LEMON_FULL_GRAPH_H
71.21 +#define LEMON_FULL_GRAPH_H
71.22 +
71.23 +#include <cmath>
71.24 +
71.25 +
71.26 +#include <lemon/bits/iterable_graph_extender.h>
71.27 +#include <lemon/bits/alteration_notifier.h>
71.28 +#include <lemon/bits/default_map.h>
71.29 +
71.30 +#include <lemon/invalid.h>
71.31 +#include <lemon/utility.h>
71.32 +
71.33 +
71.34 +///\ingroup graphs
71.35 +///\file
71.36 +///\brief FullGraph and SymFullGraph classes.
71.37 +
71.38 +
71.39 +namespace lemon {
71.40 +
71.41 +/// \addtogroup graphs
71.42 +/// @{
71.43 +
71.44 + class FullGraphBase {
71.45 + int NodeNum;
71.46 + int EdgeNum;
71.47 + public:
71.48 +
71.49 + typedef FullGraphBase Graph;
71.50 +
71.51 + class Node;
71.52 + class Edge;
71.53 +
71.54 + public:
71.55 +
71.56 + FullGraphBase() {}
71.57 +
71.58 +
71.59 + ///Creates a full graph with \c n nodes.
71.60 + void construct(int n) { NodeNum = n; EdgeNum = n * n; }
71.61 + ///
71.62 + // FullGraphBase(const FullGraphBase &_g)
71.63 + // : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
71.64 +
71.65 + typedef True NodeNumTag;
71.66 + typedef True EdgeNumTag;
71.67 +
71.68 + ///Number of nodes.
71.69 + int nodeNum() const { return NodeNum; }
71.70 + ///Number of edges.
71.71 + int edgeNum() const { return EdgeNum; }
71.72 +
71.73 + /// Maximum node ID.
71.74 +
71.75 + /// Maximum node ID.
71.76 + ///\sa id(Node)
71.77 + int maxId(Node = INVALID) const { return NodeNum-1; }
71.78 + /// Maximum edge ID.
71.79 +
71.80 + /// Maximum edge ID.
71.81 + ///\sa id(Edge)
71.82 + int maxId(Edge = INVALID) const { return EdgeNum-1; }
71.83 +
71.84 + Node source(Edge e) const { return e.id % NodeNum; }
71.85 + Node target(Edge e) const { return e.id / NodeNum; }
71.86 +
71.87 +
71.88 + /// Node ID.
71.89 +
71.90 + /// The ID of a valid Node is a nonnegative integer not greater than
71.91 + /// \ref maxNodeId(). The range of the ID's is not surely continuous
71.92 + /// and the greatest node ID can be actually less then \ref maxNodeId().
71.93 + ///
71.94 + /// The ID of the \ref INVALID node is -1.
71.95 + ///\return The ID of the node \c v.
71.96 +
71.97 + static int id(Node v) { return v.id; }
71.98 + /// Edge ID.
71.99 +
71.100 + /// The ID of a valid Edge is a nonnegative integer not greater than
71.101 + /// \ref maxEdgeId(). The range of the ID's is not surely continuous
71.102 + /// and the greatest edge ID can be actually less then \ref maxEdgeId().
71.103 + ///
71.104 + /// The ID of the \ref INVALID edge is -1.
71.105 + ///\return The ID of the edge \c e.
71.106 + static int id(Edge e) { return e.id; }
71.107 +
71.108 + static Node fromId(int id, Node) { return Node(id);}
71.109 +
71.110 + static Edge fromId(int id, Edge) { return Edge(id);}
71.111 +
71.112 + /// Finds an edge between two nodes.
71.113 +
71.114 + /// Finds an edge from node \c u to node \c v.
71.115 + ///
71.116 + /// If \c prev is \ref INVALID (this is the default value), then
71.117 + /// It finds the first edge from \c u to \c v. Otherwise it looks for
71.118 + /// the next edge from \c u to \c v after \c prev.
71.119 + /// \return The found edge or INVALID if there is no such an edge.
71.120 + Edge findEdge(Node u,Node v, Edge prev = INVALID)
71.121 + {
71.122 + return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
71.123 + }
71.124 +
71.125 +
71.126 + class Node {
71.127 + friend class FullGraphBase;
71.128 +
71.129 + protected:
71.130 + int id;
71.131 + Node(int _id) { id = _id;}
71.132 + public:
71.133 + Node() {}
71.134 + Node (Invalid) { id = -1; }
71.135 + bool operator==(const Node node) const {return id == node.id;}
71.136 + bool operator!=(const Node node) const {return id != node.id;}
71.137 + bool operator<(const Node node) const {return id < node.id;}
71.138 + };
71.139 +
71.140 +
71.141 +
71.142 + class Edge {
71.143 + friend class FullGraphBase;
71.144 +
71.145 + protected:
71.146 + int id; // NodeNum * target + source;
71.147 +
71.148 + Edge(int _id) : id(_id) {}
71.149 +
71.150 + Edge(const FullGraphBase& _graph, int source, int target)
71.151 + : id(_graph.NodeNum * target+source) {}
71.152 + public:
71.153 + Edge() { }
71.154 + Edge (Invalid) { id = -1; }
71.155 + bool operator==(const Edge edge) const {return id == edge.id;}
71.156 + bool operator!=(const Edge edge) const {return id != edge.id;}
71.157 + bool operator<(const Edge edge) const {return id < edge.id;}
71.158 + };
71.159 +
71.160 + void first(Node& node) const {
71.161 + node.id = NodeNum-1;
71.162 + }
71.163 +
71.164 + static void next(Node& node) {
71.165 + --node.id;
71.166 + }
71.167 +
71.168 + void first(Edge& edge) const {
71.169 + edge.id = EdgeNum-1;
71.170 + }
71.171 +
71.172 + static void next(Edge& edge) {
71.173 + --edge.id;
71.174 + }
71.175 +
71.176 + void firstOut(Edge& edge, const Node& node) const {
71.177 + edge.id = EdgeNum + node.id - NodeNum;
71.178 + }
71.179 +
71.180 + void nextOut(Edge& edge) const {
71.181 + edge.id -= NodeNum;
71.182 + if (edge.id < 0) edge.id = -1;
71.183 + }
71.184 +
71.185 + void firstIn(Edge& edge, const Node& node) const {
71.186 + edge.id = node.id * NodeNum;
71.187 + }
71.188 +
71.189 + void nextIn(Edge& edge) const {
71.190 + ++edge.id;
71.191 + if (edge.id % NodeNum == 0) edge.id = -1;
71.192 + }
71.193 +
71.194 + };
71.195 +
71.196 +
71.197 + typedef AlterableGraphExtender<FullGraphBase> AlterableFullGraphBase;
71.198 + typedef IterableGraphExtender<AlterableFullGraphBase> IterableFullGraphBase;
71.199 + typedef DefaultMappableGraphExtender<IterableFullGraphBase> MappableFullGraphBase;
71.200 +
71.201 + ///A full graph class.
71.202 +
71.203 + ///This is a simple and fast directed full graph implementation.
71.204 + ///It is completely static, so you can neither add nor delete either
71.205 + ///edges or nodes.
71.206 + ///Thus it conforms to
71.207 + ///the \ref concept::StaticGraph "StaticGraph" concept
71.208 + ///\sa concept::StaticGraph.
71.209 + ///
71.210 + ///\author Alpar Juttner
71.211 + class FullGraph : public MappableFullGraphBase {
71.212 + public:
71.213 +
71.214 + FullGraph(int n) { construct(n); }
71.215 + };
71.216 +
71.217 +
71.218 + // Base graph class for UndirFullGraph.
71.219 + class UndirFullGraphBase {
71.220 + int NodeNum;
71.221 + int EdgeNum;
71.222 + public:
71.223 +
71.224 + typedef UndirFullGraphBase Graph;
71.225 +
71.226 + class Node;
71.227 + class Edge;
71.228 +
71.229 + public:
71.230 +
71.231 + UndirFullGraphBase() {}
71.232 +
71.233 +
71.234 + ///Creates a full graph with \c n nodes.
71.235 + void construct(int n) { NodeNum = n; EdgeNum = n * (n - 1) / 2; }
71.236 + ///
71.237 + // FullGraphBase(const FullGraphBase &_g)
71.238 + // : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
71.239 +
71.240 + typedef True NodeNumTag;
71.241 + typedef True EdgeNumTag;
71.242 +
71.243 + ///Number of nodes.
71.244 + int nodeNum() const { return NodeNum; }
71.245 + ///Number of edges.
71.246 + int edgeNum() const { return EdgeNum; }
71.247 +
71.248 + /// Maximum node ID.
71.249 +
71.250 + /// Maximum node ID.
71.251 + ///\sa id(Node)
71.252 + int maxId(Node = INVALID) const { return NodeNum-1; }
71.253 + /// Maximum edge ID.
71.254 +
71.255 + /// Maximum edge ID.
71.256 + ///\sa id(Edge)
71.257 + int maxId(Edge = INVALID) const { return EdgeNum-1; }
71.258 +
71.259 + Node source(Edge e) const {
71.260 + /// \todo we may do it faster
71.261 + return ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;
71.262 + }
71.263 +
71.264 + Node target(Edge e) const {
71.265 + int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
71.266 + return e.id - (source) * (source - 1) / 2;
71.267 + }
71.268 +
71.269 +
71.270 + /// Node ID.
71.271 +
71.272 + /// The ID of a valid Node is a nonnegative integer not greater than
71.273 + /// \ref maxNodeId(). The range of the ID's is not surely continuous
71.274 + /// and the greatest node ID can be actually less then \ref maxNodeId().
71.275 + ///
71.276 + /// The ID of the \ref INVALID node is -1.
71.277 + ///\return The ID of the node \c v.
71.278 +
71.279 + static int id(Node v) { return v.id; }
71.280 + /// Edge ID.
71.281 +
71.282 + /// The ID of a valid Edge is a nonnegative integer not greater than
71.283 + /// \ref maxEdgeId(). The range of the ID's is not surely continuous
71.284 + /// and the greatest edge ID can be actually less then \ref maxEdgeId().
71.285 + ///
71.286 + /// The ID of the \ref INVALID edge is -1.
71.287 + ///\return The ID of the edge \c e.
71.288 + static int id(Edge e) { return e.id; }
71.289 +
71.290 + /// Finds an edge between two nodes.
71.291 +
71.292 + /// Finds an edge from node \c u to node \c v.
71.293 + ///
71.294 + /// If \c prev is \ref INVALID (this is the default value), then
71.295 + /// It finds the first edge from \c u to \c v. Otherwise it looks for
71.296 + /// the next edge from \c u to \c v after \c prev.
71.297 + /// \return The found edge or INVALID if there is no such an edge.
71.298 + Edge findEdge(Node u,Node v, Edge prev = INVALID)
71.299 + {
71.300 + return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
71.301 + }
71.302 +
71.303 +
71.304 + class Node {
71.305 + friend class UndirFullGraphBase;
71.306 +
71.307 + protected:
71.308 + int id;
71.309 + Node(int _id) { id = _id;}
71.310 + public:
71.311 + Node() {}
71.312 + Node (Invalid) { id = -1; }
71.313 + bool operator==(const Node node) const {return id == node.id;}
71.314 + bool operator!=(const Node node) const {return id != node.id;}
71.315 + bool operator<(const Node node) const {return id < node.id;}
71.316 + };
71.317 +
71.318 +
71.319 +
71.320 + class Edge {
71.321 + friend class UndirFullGraphBase;
71.322 +
71.323 + protected:
71.324 + int id; // NodeNum * target + source;
71.325 +
71.326 + Edge(int _id) : id(_id) {}
71.327 +
71.328 + Edge(const UndirFullGraphBase& _graph, int source, int target)
71.329 + : id(_graph.NodeNum * target+source) {}
71.330 + public:
71.331 + Edge() { }
71.332 + Edge (Invalid) { id = -1; }
71.333 + bool operator==(const Edge edge) const {return id == edge.id;}
71.334 + bool operator!=(const Edge edge) const {return id != edge.id;}
71.335 + bool operator<(const Edge edge) const {return id < edge.id;}
71.336 + };
71.337 +
71.338 + void first(Node& node) const {
71.339 + node.id = NodeNum-1;
71.340 + }
71.341 +
71.342 + static void next(Node& node) {
71.343 + --node.id;
71.344 + }
71.345 +
71.346 + void first(Edge& edge) const {
71.347 + edge.id = EdgeNum-1;
71.348 + }
71.349 +
71.350 + static void next(Edge& edge) {
71.351 + --edge.id;
71.352 + }
71.353 +
71.354 + void firstOut(Edge& edge, const Node& node) const {
71.355 + edge.id = node.id != 0 ? node.id * (node.id - 1) / 2 : -1;
71.356 + }
71.357 +
71.358 + /// \todo with specialized iterators we can make faster iterating
71.359 + void nextOut(Edge& e) const {
71.360 + int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
71.361 + int target = e.id - (source) * (source - 1) / 2;
71.362 + ++target;
71.363 + e.id = target < source ? source * (source - 1) / 2 + target : -1;
71.364 + }
71.365 +
71.366 + void firstIn(Edge& edge, const Node& node) const {
71.367 + edge.id = node.id * (node.id + 1) / 2 - 1;
71.368 + }
71.369 +
71.370 + void nextIn(Edge& e) const {
71.371 + int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
71.372 + int target = e.id - (source) * (source - 1) / 2; ++target;
71.373 + ++source;
71.374 + e.id = source < NodeNum ? source * (source - 1) / 2 + target : -1;
71.375 + }
71.376 +
71.377 + };
71.378 +
71.379 + /// \todo UndirFullGraph from the UndirFullGraphBase
71.380 +
71.381 +
71.382 +
71.383 + /// @}
71.384 +
71.385 +} //namespace lemon
71.386 +
71.387 +
71.388 +#endif //LEMON_FULL_GRAPH_H
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
72.2 +++ b/lemon/graph_adaptor.h Mon May 23 04:48:14 2005 +0000
72.3 @@ -0,0 +1,1218 @@
72.4 +/* -*- C++ -*-
72.5 + * lemon/graph_adaptor.h - Part of LEMON, a generic C++ optimization library
72.6 + *
72.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
72.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
72.9 + *
72.10 + * Permission to use, modify and distribute this software is granted
72.11 + * provided that this copyright notice appears in all copies. For
72.12 + * precise terms see the accompanying LICENSE file.
72.13 + *
72.14 + * This software is provided "AS IS" with no warranty of any kind,
72.15 + * express or implied, and with no claim as to its suitability for any
72.16 + * purpose.
72.17 + *
72.18 + */
72.19 +
72.20 +#ifndef LEMON_GRAPH_ADAPTOR_H
72.21 +#define LEMON_GRAPH_ADAPTOR_H
72.22 +
72.23 +///\ingroup graph_adaptors
72.24 +///\file
72.25 +///\brief Several graph adaptors.
72.26 +///
72.27 +///This file contains several useful graph adaptor functions.
72.28 +///
72.29 +///\author Marton Makai
72.30 +
72.31 +#include <lemon/invalid.h>
72.32 +#include <lemon/maps.h>
72.33 +#include <lemon/bits/iterable_graph_extender.h>
72.34 +#include <lemon/bits/undir_graph_extender.h>
72.35 +#include <iostream>
72.36 +
72.37 +namespace lemon {
72.38 +
72.39 + // Graph adaptors
72.40 +
72.41 + /*!
72.42 + \addtogroup graph_adaptors
72.43 + @{
72.44 + */
72.45 +
72.46 + /*!
72.47 + Base type for the Graph Adaptors
72.48 +
72.49 + \warning Graph adaptors are in even more experimental state than the other
72.50 + parts of the lib. Use them at you own risk.
72.51 +
72.52 + This is the base type for most of LEMON graph adaptors.
72.53 + This class implements a trivial graph adaptor i.e. it only wraps the
72.54 + functions and types of the graph. The purpose of this class is to
72.55 + make easier implementing graph adaptors. E.g. if an adaptor is
72.56 + considered which differs from the wrapped graph only in some of its
72.57 + functions or types, then it can be derived from GraphAdaptor, and only the
72.58 + differences should be implemented.
72.59 +
72.60 + \author Marton Makai
72.61 + */
72.62 + template<typename _Graph>
72.63 + class GraphAdaptorBase {
72.64 + public:
72.65 + typedef _Graph Graph;
72.66 + /// \todo Is it needed?
72.67 + typedef Graph BaseGraph;
72.68 + typedef Graph ParentGraph;
72.69 +
72.70 + protected:
72.71 + Graph* graph;
72.72 + GraphAdaptorBase() : graph(0) { }
72.73 + void setGraph(Graph& _graph) { graph=&_graph; }
72.74 +
72.75 + public:
72.76 + GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
72.77 +
72.78 + typedef typename Graph::Node Node;
72.79 + typedef typename Graph::Edge Edge;
72.80 +
72.81 + void first(Node& i) const { graph->first(i); }
72.82 + void first(Edge& i) const { graph->first(i); }
72.83 + void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
72.84 + void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
72.85 +
72.86 + void next(Node& i) const { graph->next(i); }
72.87 + void next(Edge& i) const { graph->next(i); }
72.88 + void nextIn(Edge& i) const { graph->nextIn(i); }
72.89 + void nextOut(Edge& i) const { graph->nextOut(i); }
72.90 +
72.91 + Node source(const Edge& e) const { return graph->source(e); }
72.92 + Node target(const Edge& e) const { return graph->target(e); }
72.93 +
72.94 + int nodeNum() const { return graph->nodeNum(); }
72.95 + int edgeNum() const { return graph->edgeNum(); }
72.96 +
72.97 + Node addNode() const { return Node(graph->addNode()); }
72.98 + Edge addEdge(const Node& source, const Node& target) const {
72.99 + return Edge(graph->addEdge(source, target)); }
72.100 +
72.101 + void erase(const Node& i) const { graph->erase(i); }
72.102 + void erase(const Edge& i) const { graph->erase(i); }
72.103 +
72.104 + void clear() const { graph->clear(); }
72.105 +
72.106 + bool forward(const Edge& e) const { return graph->forward(e); }
72.107 + bool backward(const Edge& e) const { return graph->backward(e); }
72.108 +
72.109 + int id(const Node& v) const { return graph->id(v); }
72.110 + int id(const Edge& e) const { return graph->id(e); }
72.111 +
72.112 + Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
72.113 +
72.114 + template <typename _Value>
72.115 + class NodeMap : public _Graph::template NodeMap<_Value> {
72.116 + public:
72.117 + typedef typename _Graph::template NodeMap<_Value> Parent;
72.118 + NodeMap(const GraphAdaptorBase<_Graph>& gw) : Parent(*gw.graph) { }
72.119 + NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
72.120 + : Parent(*gw.graph, value) { }
72.121 + };
72.122 +
72.123 + template <typename _Value>
72.124 + class EdgeMap : public _Graph::template EdgeMap<_Value> {
72.125 + public:
72.126 + typedef typename _Graph::template EdgeMap<_Value> Parent;
72.127 + EdgeMap(const GraphAdaptorBase<_Graph>& gw) : Parent(*gw.graph) { }
72.128 + EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
72.129 + : Parent(*gw.graph, value) { }
72.130 + };
72.131 +
72.132 + };
72.133 +
72.134 + template <typename _Graph>
72.135 + class GraphAdaptor :
72.136 + public IterableGraphExtender<GraphAdaptorBase<_Graph> > {
72.137 + public:
72.138 + typedef _Graph Graph;
72.139 + typedef IterableGraphExtender<GraphAdaptorBase<_Graph> > Parent;
72.140 + protected:
72.141 + GraphAdaptor() : Parent() { }
72.142 +
72.143 + public:
72.144 + GraphAdaptor(Graph& _graph) { setGraph(_graph); }
72.145 + };
72.146 +
72.147 + template <typename _Graph>
72.148 + class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
72.149 + public:
72.150 + typedef _Graph Graph;
72.151 + typedef GraphAdaptorBase<_Graph> Parent;
72.152 + protected:
72.153 + RevGraphAdaptorBase() : Parent() { }
72.154 + public:
72.155 + typedef typename Parent::Node Node;
72.156 + typedef typename Parent::Edge Edge;
72.157 +
72.158 + // using Parent::first;
72.159 + void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
72.160 + void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
72.161 +
72.162 + // using Parent::next;
72.163 + void nextIn(Edge& i) const { Parent::nextOut(i); }
72.164 + void nextOut(Edge& i) const { Parent::nextIn(i); }
72.165 +
72.166 + Node source(const Edge& e) const { return Parent::target(e); }
72.167 + Node target(const Edge& e) const { return Parent::source(e); }
72.168 + };
72.169 +
72.170 +
72.171 + /// A graph adaptor which reverses the orientation of the edges.
72.172 +
72.173 + ///\warning Graph adaptors are in even more experimental state than the other
72.174 + ///parts of the lib. Use them at you own risk.
72.175 + ///
72.176 + /// Let \f$G=(V, A)\f$ be a directed graph and
72.177 + /// suppose that a graph instange \c g of type
72.178 + /// \c ListGraph implements \f$G\f$.
72.179 + /// \code
72.180 + /// ListGraph g;
72.181 + /// \endcode
72.182 + /// For each directed edge
72.183 + /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
72.184 + /// reversing its orientation.
72.185 + /// Then RevGraphAdaptor implements the graph structure with node-set
72.186 + /// \f$V\f$ and edge-set
72.187 + /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be
72.188 + /// reversing the orientation of its edges. The following code shows how
72.189 + /// such an instance can be constructed.
72.190 + /// \code
72.191 + /// RevGraphAdaptor<ListGraph> gw(g);
72.192 + /// \endcode
72.193 + ///\author Marton Makai
72.194 + template<typename _Graph>
72.195 + class RevGraphAdaptor :
72.196 + public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
72.197 + public:
72.198 + typedef _Graph Graph;
72.199 + typedef IterableGraphExtender<
72.200 + RevGraphAdaptorBase<_Graph> > Parent;
72.201 + protected:
72.202 + RevGraphAdaptor() { }
72.203 + public:
72.204 + RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
72.205 + };
72.206 +
72.207 +
72.208 + template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
72.209 + class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
72.210 + public:
72.211 + typedef _Graph Graph;
72.212 + typedef GraphAdaptorBase<_Graph> Parent;
72.213 + protected:
72.214 + NodeFilterMap* node_filter_map;
72.215 + EdgeFilterMap* edge_filter_map;
72.216 + SubGraphAdaptorBase() : Parent(),
72.217 + node_filter_map(0), edge_filter_map(0) { }
72.218 +
72.219 + void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
72.220 + node_filter_map=&_node_filter_map;
72.221 + }
72.222 + void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
72.223 + edge_filter_map=&_edge_filter_map;
72.224 + }
72.225 +
72.226 + public:
72.227 +// SubGraphAdaptorBase(Graph& _graph,
72.228 +// NodeFilterMap& _node_filter_map,
72.229 +// EdgeFilterMap& _edge_filter_map) :
72.230 +// Parent(&_graph),
72.231 +// node_filter_map(&node_filter_map),
72.232 +// edge_filter_map(&edge_filter_map) { }
72.233 +
72.234 + typedef typename Parent::Node Node;
72.235 + typedef typename Parent::Edge Edge;
72.236 +
72.237 + void first(Node& i) const {
72.238 + Parent::first(i);
72.239 + while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
72.240 + }
72.241 + void first(Edge& i) const {
72.242 + Parent::first(i);
72.243 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
72.244 + }
72.245 + void firstIn(Edge& i, const Node& n) const {
72.246 + Parent::firstIn(i, n);
72.247 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
72.248 + }
72.249 + void firstOut(Edge& i, const Node& n) const {
72.250 + Parent::firstOut(i, n);
72.251 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
72.252 + }
72.253 +
72.254 + void next(Node& i) const {
72.255 + Parent::next(i);
72.256 + while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
72.257 + }
72.258 + void next(Edge& i) const {
72.259 + Parent::next(i);
72.260 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
72.261 + }
72.262 + void nextIn(Edge& i) const {
72.263 + Parent::nextIn(i);
72.264 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
72.265 + }
72.266 + void nextOut(Edge& i) const {
72.267 + Parent::nextOut(i);
72.268 + while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
72.269 + }
72.270 +
72.271 + /// This function hides \c n in the graph, i.e. the iteration
72.272 + /// jumps over it. This is done by simply setting the value of \c n
72.273 + /// to be false in the corresponding node-map.
72.274 + void hide(const Node& n) const { node_filter_map->set(n, false); }
72.275 +
72.276 + /// This function hides \c e in the graph, i.e. the iteration
72.277 + /// jumps over it. This is done by simply setting the value of \c e
72.278 + /// to be false in the corresponding edge-map.
72.279 + void hide(const Edge& e) const { edge_filter_map->set(e, false); }
72.280 +
72.281 + /// The value of \c n is set to be true in the node-map which stores
72.282 + /// hide information. If \c n was hidden previuosly, then it is shown
72.283 + /// again
72.284 + void unHide(const Node& n) const { node_filter_map->set(n, true); }
72.285 +
72.286 + /// The value of \c e is set to be true in the edge-map which stores
72.287 + /// hide information. If \c e was hidden previuosly, then it is shown
72.288 + /// again
72.289 + void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
72.290 +
72.291 + /// Returns true if \c n is hidden.
72.292 + bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
72.293 +
72.294 + /// Returns true if \c n is hidden.
72.295 + bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
72.296 +
72.297 + /// \warning This is a linear time operation and works only if s
72.298 + /// \c Graph::NodeIt is defined.
72.299 + /// \todo assign tags.
72.300 + int nodeNum() const {
72.301 + int i=0;
72.302 + Node n;
72.303 + for (first(n); n!=INVALID; next(n)) ++i;
72.304 + return i;
72.305 + }
72.306 +
72.307 + /// \warning This is a linear time operation and works only if
72.308 + /// \c Graph::EdgeIt is defined.
72.309 + /// \todo assign tags.
72.310 + int edgeNum() const {
72.311 + int i=0;
72.312 + Edge e;
72.313 + for (first(e); e!=INVALID; next(e)) ++i;
72.314 + return i;
72.315 + }
72.316 +
72.317 +
72.318 + };
72.319 +
72.320 + /*! \brief A graph adaptor for hiding nodes and edges from a graph.
72.321 +
72.322 + \warning Graph adaptors are in even more experimental state than the other
72.323 + parts of the lib. Use them at you own risk.
72.324 +
72.325 + SubGraphAdaptor shows the graph with filtered node-set and
72.326 + edge-set.
72.327 + Let \f$G=(V, A)\f$ be a directed graph
72.328 + and suppose that the graph instance \c g of type ListGraph implements
72.329 + \f$G\f$.
72.330 + Let moreover \f$b_V\f$ and
72.331 + \f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set.
72.332 + SubGraphAdaptor<...>::NodeIt iterates
72.333 + on the node-set \f$\{v\in V : b_V(v)=true\}\f$ and
72.334 + SubGraphAdaptor<...>::EdgeIt iterates
72.335 + on the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly,
72.336 + SubGraphAdaptor<...>::OutEdgeIt and SubGraphAdaptor<...>::InEdgeIt iterates
72.337 + only on edges leaving and entering a specific node which have true value.
72.338 +
72.339 + We have to note that this does not mean that an
72.340 + induced subgraph is obtained, the node-iterator cares only the filter
72.341 + on the node-set, and the edge-iterators care only the filter on the
72.342 + edge-set.
72.343 + \code
72.344 + typedef ListGraph Graph;
72.345 + Graph g;
72.346 + typedef Graph::Node Node;
72.347 + typedef Graph::Edge Edge;
72.348 + Node u=g.addNode(); //node of id 0
72.349 + Node v=g.addNode(); //node of id 1
72.350 + Node e=g.addEdge(u, v); //edge of id 0
72.351 + Node f=g.addEdge(v, u); //edge of id 1
72.352 + Graph::NodeMap<bool> nm(g, true);
72.353 + nm.set(u, false);
72.354 + Graph::EdgeMap<bool> em(g, true);
72.355 + em.set(e, false);
72.356 + typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
72.357 + SubGW gw(g, nm, em);
72.358 + for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
72.359 + std::cout << ":-)" << std::endl;
72.360 + for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
72.361 + \endcode
72.362 + The output of the above code is the following.
72.363 + \code
72.364 + 1
72.365 + :-)
72.366 + 1
72.367 + \endcode
72.368 + Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
72.369 + \c Graph::Node that is why \c g.id(n) can be applied.
72.370 +
72.371 + For other examples see also the documentation of NodeSubGraphAdaptor and
72.372 + EdgeSubGraphAdaptor.
72.373 +
72.374 + \author Marton Makai
72.375 + */
72.376 + template<typename _Graph, typename NodeFilterMap,
72.377 + typename EdgeFilterMap>
72.378 + class SubGraphAdaptor :
72.379 + public IterableGraphExtender<
72.380 + SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > {
72.381 + public:
72.382 + typedef _Graph Graph;
72.383 + typedef IterableGraphExtender<
72.384 + SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
72.385 + protected:
72.386 + SubGraphAdaptor() { }
72.387 + public:
72.388 + SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
72.389 + EdgeFilterMap& _edge_filter_map) {
72.390 + setGraph(_graph);
72.391 + setNodeFilterMap(_node_filter_map);
72.392 + setEdgeFilterMap(_edge_filter_map);
72.393 + }
72.394 + };
72.395 +
72.396 +
72.397 +
72.398 + /*! \brief An adaptor for hiding nodes from a graph.
72.399 +
72.400 + \warning Graph adaptors are in even more experimental state than the other
72.401 + parts of the lib. Use them at you own risk.
72.402 +
72.403 + An adaptor for hiding nodes from a graph.
72.404 + This adaptor specializes SubGraphAdaptor in the way that only the node-set
72.405 + can be filtered. Note that this does not mean of considering induced
72.406 + subgraph, the edge-iterators consider the original edge-set.
72.407 + \author Marton Makai
72.408 + */
72.409 + template<typename Graph, typename NodeFilterMap>
72.410 + class NodeSubGraphAdaptor :
72.411 + public SubGraphAdaptor<Graph, NodeFilterMap,
72.412 + ConstMap<typename Graph::Edge,bool> > {
72.413 + public:
72.414 + typedef SubGraphAdaptor<Graph, NodeFilterMap,
72.415 + ConstMap<typename Graph::Edge,bool> > Parent;
72.416 + protected:
72.417 + ConstMap<typename Graph::Edge, bool> const_true_map;
72.418 + public:
72.419 + NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
72.420 + Parent(), const_true_map(true) {
72.421 + Parent::setGraph(_graph);
72.422 + Parent::setNodeFilterMap(_node_filter_map);
72.423 + Parent::setEdgeFilterMap(const_true_map);
72.424 + }
72.425 + };
72.426 +
72.427 +
72.428 + /*! \brief An adaptor for hiding edges from a graph.
72.429 +
72.430 + \warning Graph adaptors are in even more experimental state than the other
72.431 + parts of the lib. Use them at you own risk.
72.432 +
72.433 + An adaptor for hiding edges from a graph.
72.434 + This adaptor specializes SubGraphAdaptor in the way that only the edge-set
72.435 + can be filtered. The usefulness of this adaptor is demonstrated in the
72.436 + problem of searching a maximum number of edge-disjoint shortest paths
72.437 + between
72.438 + two nodes \c s and \c t. Shortest here means being shortest w.r.t.
72.439 + non-negative edge-lengths. Note that
72.440 + the comprehension of the presented solution
72.441 + need's some elementary knowledge from combinatorial optimization.
72.442 +
72.443 + If a single shortest path is to be
72.444 + searched between \c s and \c t, then this can be done easily by
72.445 + applying the Dijkstra algorithm. What happens, if a maximum number of
72.446 + edge-disjoint shortest paths is to be computed. It can be proved that an
72.447 + edge can be in a shortest path if and only if it is tight with respect to
72.448 + the potential function computed by Dijkstra. Moreover, any path containing
72.449 + only such edges is a shortest one. Thus we have to compute a maximum number
72.450 + of edge-disjoint paths between \c s and \c t in the graph which has edge-set
72.451 + all the tight edges. The computation will be demonstrated on the following
72.452 + graph, which is read from the dimacs file \ref sub_graph_adaptor_demo.dim.
72.453 + The full source code is available in \ref sub_graph_adaptor_demo.cc.
72.454 + If you are interested in more demo programs, you can use
72.455 + \ref dim_to_dot.cc to generate .dot files from dimacs files.
72.456 + The .dot file of the following figure of was generated generated by
72.457 + the demo program \ref dim_to_dot.cc.
72.458 +
72.459 + \dot
72.460 + digraph lemon_dot_example {
72.461 + node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
72.462 + n0 [ label="0 (s)" ];
72.463 + n1 [ label="1" ];
72.464 + n2 [ label="2" ];
72.465 + n3 [ label="3" ];
72.466 + n4 [ label="4" ];
72.467 + n5 [ label="5" ];
72.468 + n6 [ label="6 (t)" ];
72.469 + edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
72.470 + n5 -> n6 [ label="9, length:4" ];
72.471 + n4 -> n6 [ label="8, length:2" ];
72.472 + n3 -> n5 [ label="7, length:1" ];
72.473 + n2 -> n5 [ label="6, length:3" ];
72.474 + n2 -> n6 [ label="5, length:5" ];
72.475 + n2 -> n4 [ label="4, length:2" ];
72.476 + n1 -> n4 [ label="3, length:3" ];
72.477 + n0 -> n3 [ label="2, length:1" ];
72.478 + n0 -> n2 [ label="1, length:2" ];
72.479 + n0 -> n1 [ label="0, length:3" ];
72.480 + }
72.481 + \enddot
72.482 +
72.483 + \code
72.484 + Graph g;
72.485 + Node s, t;
72.486 + LengthMap length(g);
72.487 +
72.488 + readDimacs(std::cin, g, length, s, t);
72.489 +
72.490 + cout << "edges with lengths (of form id, source--length->target): " << endl;
72.491 + for(EdgeIt e(g); e!=INVALID; ++e)
72.492 + cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
72.493 + << length[e] << "->" << g.id(g.target(e)) << endl;
72.494 +
72.495 + cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
72.496 + \endcode
72.497 + Next, the potential function is computed with Dijkstra.
72.498 + \code
72.499 + typedef Dijkstra<Graph, LengthMap> Dijkstra;
72.500 + Dijkstra dijkstra(g, length);
72.501 + dijkstra.run(s);
72.502 + \endcode
72.503 + Next, we consrtruct a map which filters the edge-set to the tight edges.
72.504 + \code
72.505 + typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
72.506 + TightEdgeFilter;
72.507 + TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
72.508 +
72.509 + typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
72.510 + SubGW gw(g, tight_edge_filter);
72.511 + \endcode
72.512 + Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
72.513 + with a max flow algorithm Preflow.
72.514 + \code
72.515 + ConstMap<Edge, int> const_1_map(1);
72.516 + Graph::EdgeMap<int> flow(g, 0);
72.517 +
72.518 + Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
72.519 + preflow(gw, s, t, const_1_map, flow);
72.520 + preflow.run();
72.521 + \endcode
72.522 + Last, the output is:
72.523 + \code
72.524 + cout << "maximum number of edge-disjoint shortest path: "
72.525 + << preflow.flowValue() << endl;
72.526 + cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
72.527 + << endl;
72.528 + for(EdgeIt e(g); e!=INVALID; ++e)
72.529 + if (flow[e])
72.530 + cout << " " << g.id(g.source(e)) << "--"
72.531 + << length[e] << "->" << g.id(g.target(e)) << endl;
72.532 + \endcode
72.533 + The program has the following (expected :-)) output:
72.534 + \code
72.535 + edges with lengths (of form id, source--length->target):
72.536 + 9, 5--4->6
72.537 + 8, 4--2->6
72.538 + 7, 3--1->5
72.539 + 6, 2--3->5
72.540 + 5, 2--5->6
72.541 + 4, 2--2->4
72.542 + 3, 1--3->4
72.543 + 2, 0--1->3
72.544 + 1, 0--2->2
72.545 + 0, 0--3->1
72.546 + s: 0 t: 6
72.547 + maximum number of edge-disjoint shortest path: 2
72.548 + edges of the maximum number of edge-disjoint shortest s-t paths:
72.549 + 9, 5--4->6
72.550 + 8, 4--2->6
72.551 + 7, 3--1->5
72.552 + 4, 2--2->4
72.553 + 2, 0--1->3
72.554 + 1, 0--2->2
72.555 + \endcode
72.556 +
72.557 + \author Marton Makai
72.558 + */
72.559 + template<typename Graph, typename EdgeFilterMap>
72.560 + class EdgeSubGraphAdaptor :
72.561 + public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
72.562 + EdgeFilterMap> {
72.563 + public:
72.564 + typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
72.565 + EdgeFilterMap> Parent;
72.566 + protected:
72.567 + ConstMap<typename Graph::Node, bool> const_true_map;
72.568 + public:
72.569 + EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
72.570 + Parent(), const_true_map(true) {
72.571 + Parent::setGraph(_graph);
72.572 + Parent::setNodeFilterMap(const_true_map);
72.573 + Parent::setEdgeFilterMap(_edge_filter_map);
72.574 + }
72.575 + };
72.576 +
72.577 + template <typename _Graph>
72.578 + class UndirGraphAdaptorBase :
72.579 + public UndirGraphExtender<GraphAdaptorBase<_Graph> > {
72.580 + public:
72.581 + typedef _Graph Graph;
72.582 + typedef UndirGraphExtender<GraphAdaptorBase<_Graph> > Parent;
72.583 + protected:
72.584 + UndirGraphAdaptorBase() : Parent() { }
72.585 + public:
72.586 + typedef typename Parent::UndirEdge UndirEdge;
72.587 + typedef typename Parent::Edge Edge;
72.588 +
72.589 + /// \bug Why cant an edge say that it is forward or not???
72.590 + /// By this, a pointer to the graph have to be stored
72.591 + /// The implementation
72.592 + template <typename T>
72.593 + class EdgeMap {
72.594 + protected:
72.595 + const UndirGraphAdaptorBase<_Graph>* g;
72.596 + template <typename TT> friend class EdgeMap;
72.597 + typename _Graph::template EdgeMap<T> forward_map, backward_map;
72.598 + public:
72.599 + typedef T Value;
72.600 + typedef Edge Key;
72.601 +
72.602 + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : g(&_g),
72.603 + forward_map(*(g->graph)), backward_map(*(g->graph)) { }
72.604 +
72.605 + EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, T a) : g(&_g),
72.606 + forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
72.607 +
72.608 + void set(Edge e, T a) {
72.609 + if (g->forward(e))
72.610 + forward_map.set(e, a);
72.611 + else
72.612 + backward_map.set(e, a);
72.613 + }
72.614 +
72.615 + T operator[](Edge e) const {
72.616 + if (g->forward(e))
72.617 + return forward_map[e];
72.618 + else
72.619 + return backward_map[e];
72.620 + }
72.621 + };
72.622 +
72.623 + template <typename T>
72.624 + class UndirEdgeMap {
72.625 + template <typename TT> friend class UndirEdgeMap;
72.626 + typename _Graph::template EdgeMap<T> map;
72.627 + public:
72.628 + typedef T Value;
72.629 + typedef UndirEdge Key;
72.630 +
72.631 + UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) :
72.632 + map(*(g.graph)) { }
72.633 +
72.634 + UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, T a) :
72.635 + map(*(g.graph), a) { }
72.636 +
72.637 + void set(UndirEdge e, T a) {
72.638 + map.set(e, a);
72.639 + }
72.640 +
72.641 + T operator[](UndirEdge e) const {
72.642 + return map[e];
72.643 + }
72.644 + };
72.645 +
72.646 + };
72.647 +
72.648 + /// \brief An undirected graph is made from a directed graph by an adaptor
72.649 + ///
72.650 + /// Undocumented, untested!!!
72.651 + /// If somebody knows nice demo application, let's polulate it.
72.652 + ///
72.653 + /// \author Marton Makai
72.654 + template<typename _Graph>
72.655 + class UndirGraphAdaptor :
72.656 + public IterableUndirGraphExtender<
72.657 + UndirGraphAdaptorBase<_Graph> > {
72.658 + public:
72.659 + typedef _Graph Graph;
72.660 + typedef IterableUndirGraphExtender<
72.661 + UndirGraphAdaptorBase<_Graph> > Parent;
72.662 + protected:
72.663 + UndirGraphAdaptor() { }
72.664 + public:
72.665 + UndirGraphAdaptor(_Graph& _graph) {
72.666 + setGraph(_graph);
72.667 + }
72.668 + };
72.669 +
72.670 +
72.671 + template <typename _Graph,
72.672 + typename ForwardFilterMap, typename BackwardFilterMap>
72.673 + class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
72.674 + public:
72.675 + typedef _Graph Graph;
72.676 + typedef GraphAdaptorBase<_Graph> Parent;
72.677 + protected:
72.678 + ForwardFilterMap* forward_filter;
72.679 + BackwardFilterMap* backward_filter;
72.680 + SubBidirGraphAdaptorBase() : Parent(),
72.681 + forward_filter(0), backward_filter(0) { }
72.682 +
72.683 + void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
72.684 + forward_filter=&_forward_filter;
72.685 + }
72.686 + void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
72.687 + backward_filter=&_backward_filter;
72.688 + }
72.689 +
72.690 + public:
72.691 +// SubGraphAdaptorBase(Graph& _graph,
72.692 +// NodeFilterMap& _node_filter_map,
72.693 +// EdgeFilterMap& _edge_filter_map) :
72.694 +// Parent(&_graph),
72.695 +// node_filter_map(&node_filter_map),
72.696 +// edge_filter_map(&edge_filter_map) { }
72.697 +
72.698 + typedef typename Parent::Node Node;
72.699 + typedef typename _Graph::Edge GraphEdge;
72.700 + template <typename T> class EdgeMap;
72.701 + /// SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from
72.702 + /// _Graph::Edge. It contains an extra bool flag which is true
72.703 + /// if and only if the
72.704 + /// edge is the backward version of the original edge.
72.705 + class Edge : public _Graph::Edge {
72.706 + friend class SubBidirGraphAdaptorBase<
72.707 + Graph, ForwardFilterMap, BackwardFilterMap>;
72.708 + template<typename T> friend class EdgeMap;
72.709 + protected:
72.710 + bool backward; //true, iff backward
72.711 + public:
72.712 + Edge() { }
72.713 + /// \todo =false is needed, or causes problems?
72.714 + /// If \c _backward is false, then we get an edge corresponding to the
72.715 + /// original one, otherwise its oppositely directed pair is obtained.
72.716 + Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) :
72.717 + _Graph::Edge(e), backward(_backward) { }
72.718 + Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
72.719 + bool operator==(const Edge& v) const {
72.720 + return (this->backward==v.backward &&
72.721 + static_cast<typename _Graph::Edge>(*this)==
72.722 + static_cast<typename _Graph::Edge>(v));
72.723 + }
72.724 + bool operator!=(const Edge& v) const {
72.725 + return (this->backward!=v.backward ||
72.726 + static_cast<typename _Graph::Edge>(*this)!=
72.727 + static_cast<typename _Graph::Edge>(v));
72.728 + }
72.729 + };
72.730 +
72.731 + void first(Node& i) const {
72.732 + Parent::first(i);
72.733 + }
72.734 +
72.735 + void first(Edge& i) const {
72.736 + Parent::first(i);
72.737 + i.backward=false;
72.738 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.739 + !(*forward_filter)[i]) Parent::next(i);
72.740 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.741 + Parent::first(i);
72.742 + i.backward=true;
72.743 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.744 + !(*backward_filter)[i]) Parent::next(i);
72.745 + }
72.746 + }
72.747 +
72.748 + void firstIn(Edge& i, const Node& n) const {
72.749 + Parent::firstIn(i, n);
72.750 + i.backward=false;
72.751 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.752 + !(*forward_filter)[i]) Parent::nextIn(i);
72.753 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.754 + Parent::firstOut(i, n);
72.755 + i.backward=true;
72.756 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.757 + !(*backward_filter)[i]) Parent::nextOut(i);
72.758 + }
72.759 + }
72.760 +
72.761 + void firstOut(Edge& i, const Node& n) const {
72.762 + Parent::firstOut(i, n);
72.763 + i.backward=false;
72.764 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.765 + !(*forward_filter)[i]) Parent::nextOut(i);
72.766 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.767 + Parent::firstIn(i, n);
72.768 + i.backward=true;
72.769 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.770 + !(*backward_filter)[i]) Parent::nextIn(i);
72.771 + }
72.772 + }
72.773 +
72.774 + void next(Node& i) const {
72.775 + Parent::next(i);
72.776 + }
72.777 +
72.778 + void next(Edge& i) const {
72.779 + if (!(i.backward)) {
72.780 + Parent::next(i);
72.781 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.782 + !(*forward_filter)[i]) Parent::next(i);
72.783 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.784 + Parent::first(i);
72.785 + i.backward=true;
72.786 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.787 + !(*backward_filter)[i]) Parent::next(i);
72.788 + }
72.789 + } else {
72.790 + Parent::next(i);
72.791 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.792 + !(*backward_filter)[i]) Parent::next(i);
72.793 + }
72.794 + }
72.795 +
72.796 + void nextIn(Edge& i) const {
72.797 + if (!(i.backward)) {
72.798 + Node n=Parent::target(i);
72.799 + Parent::nextIn(i);
72.800 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.801 + !(*forward_filter)[i]) Parent::nextIn(i);
72.802 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.803 + Parent::firstOut(i, n);
72.804 + i.backward=true;
72.805 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.806 + !(*backward_filter)[i]) Parent::nextOut(i);
72.807 + }
72.808 + } else {
72.809 + Parent::nextOut(i);
72.810 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.811 + !(*backward_filter)[i]) Parent::nextOut(i);
72.812 + }
72.813 + }
72.814 +
72.815 + void nextOut(Edge& i) const {
72.816 + if (!(i.backward)) {
72.817 + Node n=Parent::source(i);
72.818 + Parent::nextOut(i);
72.819 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.820 + !(*forward_filter)[i]) Parent::nextOut(i);
72.821 + if (*static_cast<GraphEdge*>(&i)==INVALID) {
72.822 + Parent::firstIn(i, n);
72.823 + i.backward=true;
72.824 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.825 + !(*backward_filter)[i]) Parent::nextIn(i);
72.826 + }
72.827 + } else {
72.828 + Parent::nextIn(i);
72.829 + while (*static_cast<GraphEdge*>(&i)!=INVALID &&
72.830 + !(*backward_filter)[i]) Parent::nextIn(i);
72.831 + }
72.832 + }
72.833 +
72.834 + Node source(Edge e) const {
72.835 + return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
72.836 + Node target(Edge e) const {
72.837 + return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
72.838 +
72.839 + /// Gives back the opposite edge.
72.840 + Edge opposite(const Edge& e) const {
72.841 + Edge f=e;
72.842 + f.backward=!f.backward;
72.843 + return f;
72.844 + }
72.845 +
72.846 + /// \warning This is a linear time operation and works only if
72.847 + /// \c Graph::EdgeIt is defined.
72.848 + /// \todo hmm
72.849 + int edgeNum() const {
72.850 + int i=0;
72.851 + Edge e;
72.852 + for (first(e); e!=INVALID; next(e)) ++i;
72.853 + return i;
72.854 + }
72.855 +
72.856 + bool forward(const Edge& e) const { return !e.backward; }
72.857 + bool backward(const Edge& e) const { return e.backward; }
72.858 +
72.859 + template <typename T>
72.860 + /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two
72.861 + /// _Graph::EdgeMap one for the forward edges and
72.862 + /// one for the backward edges.
72.863 + class EdgeMap {
72.864 + template <typename TT> friend class EdgeMap;
72.865 + typename _Graph::template EdgeMap<T> forward_map, backward_map;
72.866 + public:
72.867 + typedef T Value;
72.868 + typedef Edge Key;
72.869 +
72.870 + EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
72.871 + ForwardFilterMap, BackwardFilterMap>& g) :
72.872 + forward_map(*(g.graph)), backward_map(*(g.graph)) { }
72.873 +
72.874 + EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
72.875 + ForwardFilterMap, BackwardFilterMap>& g, T a) :
72.876 + forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
72.877 +
72.878 + void set(Edge e, T a) {
72.879 + if (!e.backward)
72.880 + forward_map.set(e, a);
72.881 + else
72.882 + backward_map.set(e, a);
72.883 + }
72.884 +
72.885 +// typename _Graph::template EdgeMap<T>::ConstReference
72.886 +// operator[](Edge e) const {
72.887 +// if (!e.backward)
72.888 +// return forward_map[e];
72.889 +// else
72.890 +// return backward_map[e];
72.891 +// }
72.892 +
72.893 +// typename _Graph::template EdgeMap<T>::Reference
72.894 + T operator[](Edge e) const {
72.895 + if (!e.backward)
72.896 + return forward_map[e];
72.897 + else
72.898 + return backward_map[e];
72.899 + }
72.900 +
72.901 + void update() {
72.902 + forward_map.update();
72.903 + backward_map.update();
72.904 + }
72.905 + };
72.906 +
72.907 + };
72.908 +
72.909 +
72.910 + ///\brief An adaptor for composing a subgraph of a
72.911 + /// bidirected graph made from a directed one.
72.912 + ///
72.913 + /// An adaptor for composing a subgraph of a
72.914 + /// bidirected graph made from a directed one.
72.915 + ///
72.916 + ///\warning Graph adaptors are in even more experimental state than the other
72.917 + ///parts of the lib. Use them at you own risk.
72.918 + ///
72.919 + /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge
72.920 + /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
72.921 + /// reversing its orientation. We are given moreover two bool valued
72.922 + /// maps on the edge-set,
72.923 + /// \f$forward\_filter\f$, and \f$backward\_filter\f$.
72.924 + /// SubBidirGraphAdaptor implements the graph structure with node-set
72.925 + /// \f$V\f$ and edge-set
72.926 + /// \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$.
72.927 + /// The purpose of writing + instead of union is because parallel
72.928 + /// edges can arise. (Similarly, antiparallel edges also can arise).
72.929 + /// In other words, a subgraph of the bidirected graph obtained, which
72.930 + /// is given by orienting the edges of the original graph in both directions.
72.931 + /// As the oppositely directed edges are logically different,
72.932 + /// the maps are able to attach different values for them.
72.933 + ///
72.934 + /// An example for such a construction is \c RevGraphAdaptor where the
72.935 + /// forward_filter is everywhere false and the backward_filter is
72.936 + /// everywhere true. We note that for sake of efficiency,
72.937 + /// \c RevGraphAdaptor is implemented in a different way.
72.938 + /// But BidirGraphAdaptor is obtained from
72.939 + /// SubBidirGraphAdaptor by considering everywhere true
72.940 + /// valued maps both for forward_filter and backward_filter.
72.941 + ///
72.942 + /// The most important application of SubBidirGraphAdaptor
72.943 + /// is ResGraphAdaptor, which stands for the residual graph in directed
72.944 + /// flow and circulation problems.
72.945 + /// As adaptors usually, the SubBidirGraphAdaptor implements the
72.946 + /// above mentioned graph structure without its physical storage,
72.947 + /// that is the whole stuff is stored in constant memory.
72.948 + template<typename _Graph,
72.949 + typename ForwardFilterMap, typename BackwardFilterMap>
72.950 + class SubBidirGraphAdaptor :
72.951 + public IterableGraphExtender<
72.952 + SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
72.953 + public:
72.954 + typedef _Graph Graph;
72.955 + typedef IterableGraphExtender<
72.956 + SubBidirGraphAdaptorBase<
72.957 + _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
72.958 + protected:
72.959 + SubBidirGraphAdaptor() { }
72.960 + public:
72.961 + SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter,
72.962 + BackwardFilterMap& _backward_filter) {
72.963 + setGraph(_graph);
72.964 + setForwardFilterMap(_forward_filter);
72.965 + setBackwardFilterMap(_backward_filter);
72.966 + }
72.967 + };
72.968 +
72.969 +
72.970 +
72.971 + ///\brief An adaptor for composing bidirected graph from a directed one.
72.972 + ///
72.973 + ///\warning Graph adaptors are in even more experimental state than the other
72.974 + ///parts of the lib. Use them at you own risk.
72.975 + ///
72.976 + /// An adaptor for composing bidirected graph from a directed one.
72.977 + /// A bidirected graph is composed over the directed one without physical
72.978 + /// storage. As the oppositely directed edges are logically different ones
72.979 + /// the maps are able to attach different values for them.
72.980 + template<typename Graph>
72.981 + class BidirGraphAdaptor :
72.982 + public SubBidirGraphAdaptor<
72.983 + Graph,
72.984 + ConstMap<typename Graph::Edge, bool>,
72.985 + ConstMap<typename Graph::Edge, bool> > {
72.986 + public:
72.987 + typedef SubBidirGraphAdaptor<
72.988 + Graph,
72.989 + ConstMap<typename Graph::Edge, bool>,
72.990 + ConstMap<typename Graph::Edge, bool> > Parent;
72.991 + protected:
72.992 + ConstMap<typename Graph::Edge, bool> cm;
72.993 +
72.994 + BidirGraphAdaptor() : Parent(), cm(true) {
72.995 + Parent::setForwardFilterMap(cm);
72.996 + Parent::setBackwardFilterMap(cm);
72.997 + }
72.998 + public:
72.999 + BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) {
72.1000 + Parent::setGraph(_graph);
72.1001 + Parent::setForwardFilterMap(cm);
72.1002 + Parent::setBackwardFilterMap(cm);
72.1003 + }
72.1004 +
72.1005 + int edgeNum() const {
72.1006 + return 2*this->graph->edgeNum();
72.1007 + }
72.1008 + // KEEP_MAPS(Parent, BidirGraphAdaptor);
72.1009 + };
72.1010 +
72.1011 +
72.1012 + template<typename Graph, typename Number,
72.1013 + typename CapacityMap, typename FlowMap>
72.1014 + class ResForwardFilter {
72.1015 + // const Graph* graph;
72.1016 + const CapacityMap* capacity;
72.1017 + const FlowMap* flow;
72.1018 + public:
72.1019 + ResForwardFilter(/*const Graph& _graph, */
72.1020 + const CapacityMap& _capacity, const FlowMap& _flow) :
72.1021 + /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
72.1022 + ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
72.1023 + void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
72.1024 + void setFlow(const FlowMap& _flow) { flow=&_flow; }
72.1025 + bool operator[](const typename Graph::Edge& e) const {
72.1026 + return (Number((*flow)[e]) < Number((*capacity)[e]));
72.1027 + }
72.1028 + };
72.1029 +
72.1030 + template<typename Graph, typename Number,
72.1031 + typename CapacityMap, typename FlowMap>
72.1032 + class ResBackwardFilter {
72.1033 + const CapacityMap* capacity;
72.1034 + const FlowMap* flow;
72.1035 + public:
72.1036 + ResBackwardFilter(/*const Graph& _graph,*/
72.1037 + const CapacityMap& _capacity, const FlowMap& _flow) :
72.1038 + /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
72.1039 + ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
72.1040 + void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
72.1041 + void setFlow(const FlowMap& _flow) { flow=&_flow; }
72.1042 + bool operator[](const typename Graph::Edge& e) const {
72.1043 + return (Number(0) < Number((*flow)[e]));
72.1044 + }
72.1045 + };
72.1046 +
72.1047 +
72.1048 + /*! \brief An adaptor for composing the residual graph for directed flow and circulation problems.
72.1049 +
72.1050 + An adaptor for composing the residual graph for directed flow and circulation problems.
72.1051 + Let \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a
72.1052 + number type. Let moreover
72.1053 + \f$f,c:A\to F\f$, be functions on the edge-set.
72.1054 + In the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow
72.1055 + and \f$c\f$ for a capacity function.
72.1056 + Suppose that a graph instange \c g of type
72.1057 + \c ListGraph implements \f$G\f$.
72.1058 + \code
72.1059 + ListGraph g;
72.1060 + \endcode
72.1061 + Then RevGraphAdaptor implements the graph structure with node-set
72.1062 + \f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where
72.1063 + \f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and
72.1064 + \f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$,
72.1065 + i.e. the so called residual graph.
72.1066 + When we take the union \f$A_{forward}\cup A_{backward}\f$,
72.1067 + multilicities are counted, i.e. if an edge is in both
72.1068 + \f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it
72.1069 + appears twice.
72.1070 + The following code shows how
72.1071 + such an instance can be constructed.
72.1072 + \code
72.1073 + typedef ListGraph Graph;
72.1074 + Graph::EdgeMap<int> f(g);
72.1075 + Graph::EdgeMap<int> c(g);
72.1076 + ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
72.1077 + \endcode
72.1078 + \author Marton Makai
72.1079 + */
72.1080 + template<typename Graph, typename Number,
72.1081 + typename CapacityMap, typename FlowMap>
72.1082 + class ResGraphAdaptor :
72.1083 + public SubBidirGraphAdaptor<
72.1084 + Graph,
72.1085 + ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
72.1086 + ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
72.1087 + public:
72.1088 + typedef SubBidirGraphAdaptor<
72.1089 + Graph,
72.1090 + ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
72.1091 + ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
72.1092 + protected:
72.1093 + const CapacityMap* capacity;
72.1094 + FlowMap* flow;
72.1095 + ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
72.1096 + ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
72.1097 + ResGraphAdaptor() : Parent(),
72.1098 + capacity(0), flow(0) { }
72.1099 + void setCapacityMap(const CapacityMap& _capacity) {
72.1100 + capacity=&_capacity;
72.1101 + forward_filter.setCapacity(_capacity);
72.1102 + backward_filter.setCapacity(_capacity);
72.1103 + }
72.1104 + void setFlowMap(FlowMap& _flow) {
72.1105 + flow=&_flow;
72.1106 + forward_filter.setFlow(_flow);
72.1107 + backward_filter.setFlow(_flow);
72.1108 + }
72.1109 + public:
72.1110 + ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity,
72.1111 + FlowMap& _flow) :
72.1112 + Parent(), capacity(&_capacity), flow(&_flow),
72.1113 + forward_filter(/*_graph,*/ _capacity, _flow),
72.1114 + backward_filter(/*_graph,*/ _capacity, _flow) {
72.1115 + Parent::setGraph(_graph);
72.1116 + Parent::setForwardFilterMap(forward_filter);
72.1117 + Parent::setBackwardFilterMap(backward_filter);
72.1118 + }
72.1119 +
72.1120 + typedef typename Parent::Edge Edge;
72.1121 +
72.1122 + void augment(const Edge& e, Number a) const {
72.1123 + if (Parent::forward(e))
72.1124 + flow->set(e, (*flow)[e]+a);
72.1125 + else
72.1126 + flow->set(e, (*flow)[e]-a);
72.1127 + }
72.1128 +
72.1129 + /// \brief Residual capacity map.
72.1130 + ///
72.1131 + /// In generic residual graphs the residual capacity can be obtained
72.1132 + /// as a map.
72.1133 + class ResCap {
72.1134 + protected:
72.1135 + const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
72.1136 + public:
72.1137 + typedef Number Value;
72.1138 + typedef Edge Key;
72.1139 + ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>&
72.1140 + _res_graph) : res_graph(&_res_graph) { }
72.1141 + Number operator[](const Edge& e) const {
72.1142 + if (res_graph->forward(e))
72.1143 + return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];
72.1144 + else
72.1145 + return (*(res_graph->flow))[e];
72.1146 + }
72.1147 + };
72.1148 +
72.1149 + // KEEP_MAPS(Parent, ResGraphAdaptor);
72.1150 + };
72.1151 +
72.1152 +
72.1153 +
72.1154 + template <typename _Graph, typename FirstOutEdgesMap>
72.1155 + class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
72.1156 + public:
72.1157 + typedef _Graph Graph;
72.1158 + typedef GraphAdaptorBase<_Graph> Parent;
72.1159 + protected:
72.1160 + FirstOutEdgesMap* first_out_edges;
72.1161 + ErasingFirstGraphAdaptorBase() : Parent(),
72.1162 + first_out_edges(0) { }
72.1163 +
72.1164 + void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
72.1165 + first_out_edges=&_first_out_edges;
72.1166 + }
72.1167 +
72.1168 + public:
72.1169 +
72.1170 + typedef typename Parent::Node Node;
72.1171 + typedef typename Parent::Edge Edge;
72.1172 +
72.1173 + void firstOut(Edge& i, const Node& n) const {
72.1174 + i=(*first_out_edges)[n];
72.1175 + }
72.1176 +
72.1177 + void erase(const Edge& e) const {
72.1178 + Node n=source(e);
72.1179 + Edge f=e;
72.1180 + Parent::nextOut(f);
72.1181 + first_out_edges->set(n, f);
72.1182 + }
72.1183 + };
72.1184 +
72.1185 +
72.1186 + /// For blocking flows.
72.1187 +
72.1188 + ///\warning Graph adaptors are in even more experimental state than the other
72.1189 + ///parts of the lib. Use them at you own risk.
72.1190 + ///
72.1191 + /// This graph adaptor is used for on-the-fly
72.1192 + /// Dinits blocking flow computations.
72.1193 + /// For each node, an out-edge is stored which is used when the
72.1194 + /// \code
72.1195 + /// OutEdgeIt& first(OutEdgeIt&, const Node&)
72.1196 + /// \endcode
72.1197 + /// is called.
72.1198 + ///
72.1199 + /// \author Marton Makai
72.1200 + template <typename _Graph, typename FirstOutEdgesMap>
72.1201 + class ErasingFirstGraphAdaptor :
72.1202 + public IterableGraphExtender<
72.1203 + ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
72.1204 + public:
72.1205 + typedef _Graph Graph;
72.1206 + typedef IterableGraphExtender<
72.1207 + ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
72.1208 + ErasingFirstGraphAdaptor(Graph& _graph,
72.1209 + FirstOutEdgesMap& _first_out_edges) {
72.1210 + setGraph(_graph);
72.1211 + setFirstOutEdgesMap(_first_out_edges);
72.1212 + }
72.1213 +
72.1214 + };
72.1215 +
72.1216 + ///@}
72.1217 +
72.1218 +} //namespace lemon
72.1219 +
72.1220 +#endif //LEMON_GRAPH_ADAPTOR_H
72.1221 +
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
73.2 +++ b/lemon/graph_reader.h Mon May 23 04:48:14 2005 +0000
73.3 @@ -0,0 +1,808 @@
73.4 +/* -*- C++ -*-
73.5 + * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
73.6 + *
73.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
73.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
73.9 + *
73.10 + * Permission to use, modify and distribute this software is granted
73.11 + * provided that this copyright notice appears in all copies. For
73.12 + * precise terms see the accompanying LICENSE file.
73.13 + *
73.14 + * This software is provided "AS IS" with no warranty of any kind,
73.15 + * express or implied, and with no claim as to its suitability for any
73.16 + * purpose.
73.17 + *
73.18 + */
73.19 +
73.20 +///\ingroup io_group
73.21 +///\file
73.22 +///\brief Lemon Graph Format reader.
73.23 +
73.24 +#ifndef LEMON_GRAPH_READER_H
73.25 +#define LEMON_GRAPH_READER_H
73.26 +
73.27 +#include <iostream>
73.28 +
73.29 +#include <lemon/error.h>
73.30 +#include <lemon/lemon_reader.h>
73.31 +
73.32 +namespace lemon {
73.33 +
73.34 + /// \addtogroup io_group
73.35 + /// @{
73.36 +
73.37 + /// \brief The graph reader class.
73.38 + ///
73.39 + /// The given file format may contain several maps and labeled nodes or
73.40 + /// edges.
73.41 + ///
73.42 + /// If you read a graph you need not read all the maps and items just those
73.43 + /// that you need. The interface of the \c GraphReader is very similar to
73.44 + /// the GraphWriter but the reading method does not depend on the order the
73.45 + /// given commands.
73.46 + ///
73.47 + /// The reader object suppose that each not readed value does not contain
73.48 + /// whitespaces, therefore it has some extra possibilities to control how
73.49 + /// it should skip the values when the string representation contains spaces.
73.50 + ///
73.51 + /// \code
73.52 + /// GraphReader<ListGraph> reader(std::cin, graph);
73.53 + /// \endcode
73.54 + ///
73.55 + /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
73.56 + /// If there is a map that you do not want to read from the file and there is
73.57 + /// whitespace in the string represenation of the values then you should
73.58 + /// call the \c skipNodeMap() template member function with proper
73.59 + /// parameters.
73.60 + ///
73.61 + /// \code
73.62 + /// reader.readNodeMap("coords", coords);
73.63 + ///
73.64 + /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
73.65 + /// reader.skipNodeMap<QuotedStringReader>("description");
73.66 + ///
73.67 + /// reader.readNodeMap("color", colorMap);
73.68 + /// \endcode
73.69 + ///
73.70 + /// With the \c readEdgeMap() member function you can give an edge map
73.71 + /// reading command similar to the NodeMaps.
73.72 + ///
73.73 + /// \code
73.74 + /// reader.readEdgeMap("weight", weightMap);
73.75 + /// reader.readEdgeMap("label", labelMap);
73.76 + /// \endcode
73.77 + ///
73.78 + /// With \c readNode() and \c readEdge() functions you can read
73.79 + /// labeled Nodes and Edges.
73.80 + ///
73.81 + /// \code
73.82 + /// reader.readNode("source", sourceNode);
73.83 + /// reader.readNode("target", targetNode);
73.84 + ///
73.85 + /// reader.readEdge("observed", edge);
73.86 + /// \endcode
73.87 + ///
73.88 + /// With the \c readAttribute() functions you can read an attribute
73.89 + /// in a variable. You can specify the reader for the attribute as
73.90 + /// the nodemaps.
73.91 + ///
73.92 + /// After you give all read commands you must call the \c run() member
73.93 + /// function, which execute all the commands.
73.94 + ///
73.95 + /// \code
73.96 + /// reader.run();
73.97 + /// \endcode
73.98 + ///
73.99 + /// \see DefaultReaderTraits
73.100 + /// \see QuotedStringReader
73.101 + /// \see \ref GraphWriter
73.102 + /// \see \ref graph-io-page
73.103 + /// \author Balazs Dezso
73.104 + template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
73.105 + class GraphReader {
73.106 + public:
73.107 +
73.108 + typedef _Graph Graph;
73.109 + typedef typename Graph::Node Node;
73.110 + typedef typename Graph::Edge Edge;
73.111 +
73.112 + typedef _ReaderTraits ReaderTraits;
73.113 + typedef typename ReaderTraits::Skipper DefaultSkipper;
73.114 +
73.115 + /// \brief Construct a new GraphReader.
73.116 + ///
73.117 + /// Construct a new GraphReader. It reads into the given graph
73.118 + /// and it use the given reader as the default skipper.
73.119 + GraphReader(std::istream& _is,
73.120 + typename SmartParameter<Graph>::Type _graph,
73.121 + const DefaultSkipper& _skipper = DefaultSkipper())
73.122 + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
73.123 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.124 + edgeset_reader(*reader, _graph, nodeset_reader,
73.125 + std::string(), skipper),
73.126 + node_reader(*reader, nodeset_reader, std::string()),
73.127 + edge_reader(*reader, edgeset_reader, std::string()),
73.128 + attribute_reader(*reader, std::string()) {}
73.129 +
73.130 + /// \brief Construct a new GraphReader.
73.131 + ///
73.132 + /// Construct a new GraphReader. It reads into the given graph
73.133 + /// and it use the given reader as the default skipper.
73.134 + GraphReader(const std::string& _filename,
73.135 + typename SmartParameter<Graph>::Type _graph,
73.136 + const DefaultSkipper& _skipper = DefaultSkipper())
73.137 + : reader(new LemonReader(_filename)), own_reader(true),
73.138 + skipper(_skipper),
73.139 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.140 + edgeset_reader(*reader, _graph, nodeset_reader,
73.141 + std::string(), skipper),
73.142 + node_reader(*reader, nodeset_reader, std::string()),
73.143 + edge_reader(*reader, edgeset_reader, std::string()),
73.144 + attribute_reader(*reader, std::string()) {}
73.145 +
73.146 + /// \brief Construct a new GraphReader.
73.147 + ///
73.148 + /// Construct a new GraphReader. It reads into the given graph
73.149 + /// and it use the given reader as the default skipper.
73.150 + GraphReader(LemonReader& _reader,
73.151 + typename SmartParameter<Graph>::Type _graph,
73.152 + const DefaultSkipper& _skipper = DefaultSkipper())
73.153 + : reader(_reader), own_reader(false), skipper(_skipper),
73.154 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.155 + edgeset_reader(*reader, _graph, nodeset_reader,
73.156 + std::string(), skipper),
73.157 + node_reader(*reader, nodeset_reader, std::string()),
73.158 + edge_reader(*reader, edgeset_reader, std::string()),
73.159 + attribute_reader(*reader, std::string()) {}
73.160 +
73.161 + /// \brief Destruct the graph reader.
73.162 + ///
73.163 + /// Destruct the graph reader.
73.164 + ~GraphReader() {
73.165 + if (own_reader)
73.166 + delete reader;
73.167 + }
73.168 +
73.169 + /// \brief Add a new node map reader command for the reader.
73.170 + ///
73.171 + /// Add a new node map reader command for the reader.
73.172 + template <typename Map>
73.173 + GraphReader& readNodeMap(std::string name, Map& map) {
73.174 + nodeset_reader.readNodeMap(name, map);
73.175 + return *this;
73.176 + }
73.177 +
73.178 + template <typename Map>
73.179 + GraphReader& readNodeMap(std::string name, const Map& map) {
73.180 + nodeset_reader.readNodeMap(name, map);
73.181 + return *this;
73.182 + }
73.183 +
73.184 + /// \brief Add a new node map reader command for the reader.
73.185 + ///
73.186 + /// Add a new node map reader command for the reader.
73.187 + template <typename Reader, typename Map>
73.188 + GraphReader& readNodeMap(std::string name, Map& map,
73.189 + const Reader& reader = Reader()) {
73.190 + nodeset_reader.readNodeMap(name, map, reader);
73.191 + return *this;
73.192 + }
73.193 +
73.194 + template <typename Reader, typename Map>
73.195 + GraphReader& readNodeMap(std::string name, const Map& map,
73.196 + const Reader& reader = Reader()) {
73.197 + nodeset_reader.readNodeMap(name, map, reader);
73.198 + return *this;
73.199 + }
73.200 +
73.201 + /// \brief Add a new node map skipper command for the reader.
73.202 + ///
73.203 + /// Add a new node map skipper command for the reader.
73.204 + template <typename Reader>
73.205 + GraphReader& skipNodeMap(std::string name,
73.206 + const Reader& reader = Reader()) {
73.207 + nodeset_reader.skipNodeMap(name, reader);
73.208 + return *this;
73.209 + }
73.210 +
73.211 + /// \brief Add a new edge map reader command for the reader.
73.212 + ///
73.213 + /// Add a new edge map reader command for the reader.
73.214 + template <typename Map>
73.215 + GraphReader& readEdgeMap(std::string name, Map& map) {
73.216 + edgeset_reader.readEdgeMap(name, map);
73.217 + return *this;
73.218 + }
73.219 +
73.220 + template <typename Map>
73.221 + GraphReader& readEdgeMap(std::string name, const Map& map) {
73.222 + edgeset_reader.readEdgeMap(name, map);
73.223 + return *this;
73.224 + }
73.225 +
73.226 +
73.227 + /// \brief Add a new edge map reader command for the reader.
73.228 + ///
73.229 + /// Add a new edge map reader command for the reader.
73.230 + template <typename Reader, typename Map>
73.231 + GraphReader& readEdgeMap(std::string name, Map& map,
73.232 + const Reader& reader = Reader()) {
73.233 + edgeset_reader.readEdgeMap(name, map, reader);
73.234 + return *this;
73.235 + }
73.236 +
73.237 + template <typename Reader, typename Map>
73.238 + GraphReader& readEdgeMap(std::string name, const Map& map,
73.239 + const Reader& reader = Reader()) {
73.240 + edgeset_reader.readEdgeMap(name, map, reader);
73.241 + return *this;
73.242 + }
73.243 +
73.244 + /// \brief Add a new edge map skipper command for the reader.
73.245 + ///
73.246 + /// Add a new edge map skipper command for the reader.
73.247 + template <typename Reader>
73.248 + GraphReader& skipEdgeMap(std::string name,
73.249 + const Reader& reader = Reader()) {
73.250 + edgeset_reader.skipEdgeMap(name, reader);
73.251 + return *this;
73.252 + }
73.253 +
73.254 + /// \brief Add a new labeled node reader for the reader.
73.255 + ///
73.256 + /// Add a new labeled node reader for the reader.
73.257 + GraphReader& readNode(std::string name, Node& node) {
73.258 + node_reader.readNode(name, node);
73.259 + return *this;
73.260 + }
73.261 +
73.262 + /// \brief Add a new labeled edge reader for the reader.
73.263 + ///
73.264 + /// Add a new labeled edge reader for the reader.
73.265 + GraphReader& readEdge(std::string name, Edge& edge) {
73.266 + edge_reader.readEdge(name, edge);
73.267 + }
73.268 +
73.269 + /// \brief Add a new attribute reader command.
73.270 + ///
73.271 + /// Add a new attribute reader command.
73.272 + template <typename Value>
73.273 + GraphReader& readAttribute(std::string name, Value& value) {
73.274 + attribute_reader.readAttribute(name, value);
73.275 + return *this;
73.276 + }
73.277 +
73.278 + /// \brief Add a new attribute reader command.
73.279 + ///
73.280 + /// Add a new attribute reader command.
73.281 + template <typename Reader, typename Value>
73.282 + GraphReader& readAttribute(std::string name, Value& value,
73.283 + const Reader& reader) {
73.284 + attribute_reader.readAttribute<Reader>(name, value, reader);
73.285 + return *this;
73.286 + }
73.287 +
73.288 + /// \brief Conversion operator to LemonReader.
73.289 + ///
73.290 + /// Conversion operator to LemonReader. It make possible
73.291 + /// to access the encapsulated \e LemonReader, this way
73.292 + /// you can attach to this reader new instances of
73.293 + /// \e LemonReader::SectionReader.
73.294 + operator LemonReader&() {
73.295 + return *reader;
73.296 + }
73.297 +
73.298 + /// \brief Executes the reader commands.
73.299 + ///
73.300 + /// Executes the reader commands.
73.301 + void run() {
73.302 + reader->run();
73.303 + }
73.304 +
73.305 + /// \brief Gives back the node by its id.
73.306 + ///
73.307 + /// It reads an id from the stream and gives back which node belongs to
73.308 + /// it. It is possible only if there was read an "id" named node map.
73.309 + Node readId(std::istream& is, Node) const {
73.310 + return nodeset_reader.readId(is, Node());
73.311 + }
73.312 +
73.313 + /// \brief Gives back the edge by its id.
73.314 + ///
73.315 + /// It reads an id from the stream and gives back which edge belongs to
73.316 + /// it. It is possible only if there was read an "id" named edge map.
73.317 + Edge readId(std::istream& is, Edge) const {
73.318 + return edgeset_reader.readId(is, Edge());
73.319 + }
73.320 +
73.321 + private:
73.322 +
73.323 + LemonReader* reader;
73.324 + bool own_reader;
73.325 +
73.326 + DefaultSkipper skipper;
73.327 +
73.328 + NodeSetReader<Graph, ReaderTraits> nodeset_reader;
73.329 + EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
73.330 +
73.331 + NodeReader<Graph> node_reader;
73.332 + EdgeReader<Graph> edge_reader;
73.333 +
73.334 + AttributeReader<ReaderTraits> attribute_reader;
73.335 + };
73.336 +
73.337 + /// \brief Read a graph from the input.
73.338 + ///
73.339 + /// Read a graph from the input.
73.340 + /// \param is The input stream.
73.341 + /// \param g The graph.
73.342 + /// \param capacity The capacity map.
73.343 + /// \param s The source node.
73.344 + /// \param t The target node.
73.345 + /// \param cost The cost map.
73.346 + template<typename Graph, typename CapacityMap, typename CostMap>
73.347 + void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
73.348 + typename Graph::Node &s, typename Graph::Node &t,
73.349 + CostMap& cost) {
73.350 + GraphReader<Graph> reader(is, g);
73.351 + reader.readEdgeMap("capacity", capacity);
73.352 + reader.readEdgeMap("cost", cost);
73.353 + reader.readNode("source", s);
73.354 + reader.readNode("target", t);
73.355 + reader.run();
73.356 + }
73.357 +
73.358 + /// \brief Read a graph from the input.
73.359 + ///
73.360 + /// Read a graph from the input.
73.361 + /// \param is The input stream.
73.362 + /// \param g The graph.
73.363 + /// \param capacity The capacity map.
73.364 + /// \param s The source node.
73.365 + /// \param t The target node.
73.366 + template<typename Graph, typename CapacityMap>
73.367 + void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
73.368 + typename Graph::Node &s, typename Graph::Node &t) {
73.369 + GraphReader<Graph> reader(is, g);
73.370 + reader.readEdgeMap("capacity", capacity);
73.371 + reader.readNode("source", s);
73.372 + reader.readNode("target", t);
73.373 + reader.run();
73.374 + }
73.375 +
73.376 + /// \brief Read a graph from the input.
73.377 + ///
73.378 + /// Read a graph from the input.
73.379 + /// \param is The input stream.
73.380 + /// \param g The graph.
73.381 + /// \param capacity The capacity map.
73.382 + /// \param s The source node.
73.383 + template<typename Graph, typename CapacityMap>
73.384 + void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
73.385 + typename Graph::Node &s) {
73.386 + GraphReader<Graph> reader(is, g);
73.387 + reader.readEdgeMap("capacity", capacity);
73.388 + reader.readNode("source", s);
73.389 + reader.run();
73.390 + }
73.391 +
73.392 + /// \brief Read a graph from the input.
73.393 + ///
73.394 + /// Read a graph from the input.
73.395 + /// \param is The input stream.
73.396 + /// \param g The graph.
73.397 + /// \param capacity The capacity map.
73.398 + template<typename Graph, typename CapacityMap>
73.399 + void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
73.400 + GraphReader<Graph> reader(is, g);
73.401 + reader.readEdgeMap("capacity", capacity);
73.402 + reader.run();
73.403 + }
73.404 +
73.405 + /// \brief Read a graph from the input.
73.406 + ///
73.407 + /// Read a graph from the input.
73.408 + /// \param is The input stream.
73.409 + /// \param g The graph.
73.410 + template<typename Graph>
73.411 + void readGraph(std::istream& is, Graph &g) {
73.412 + GraphReader<Graph> reader(is, g);
73.413 + reader.run();
73.414 + }
73.415 +
73.416 + /// \brief The undir graph reader class.
73.417 + ///
73.418 + /// The given file format may contain several maps and labeled nodes or
73.419 + /// edges.
73.420 + ///
73.421 + /// If you read a graph you need not read all the maps and items just those
73.422 + /// that you need. The interface of the \c GraphReader is very similar to
73.423 + /// the GraphWriter but the reading method does not depend on the order the
73.424 + /// given commands.
73.425 + ///
73.426 + /// The reader object suppose that each not readed value does not contain
73.427 + /// whitespaces, therefore it has some extra possibilities to control how
73.428 + /// it should skip the values when the string representation contains spaces.
73.429 + ///
73.430 + /// \code
73.431 + /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
73.432 + /// \endcode
73.433 + ///
73.434 + /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
73.435 + /// If there is a map that you do not want to read from the file and there is
73.436 + /// whitespace in the string represenation of the values then you should
73.437 + /// call the \c skipNodeMap() template member function with proper
73.438 + /// parameters.
73.439 + ///
73.440 + /// \code
73.441 + /// reader.readNodeMap("coords", coords);
73.442 + ///
73.443 + /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
73.444 + /// reader.skipNodeMap<QuotedStringReader>("description");
73.445 + ///
73.446 + /// reader.readNodeMap("color", colorMap);
73.447 + /// \endcode
73.448 + ///
73.449 + /// With the \c readUndirEdgeMap() member function you can give an
73.450 + /// undir edge map reading command similar to the NodeMaps.
73.451 + ///
73.452 + /// \code
73.453 + /// reader.readUndirEdgeMap("capacity", capacityMap);
73.454 + /// \endcode
73.455 + ///
73.456 + /// The reading of the directed edge maps is just a syntactical sugar.
73.457 + /// It reads two undirected edgemaps into a directed edge map. The
73.458 + /// undirected edge maps' name should be start with the \c '+' and the
73.459 + /// \c '-' character and the same.
73.460 + ///
73.461 + /// \code
73.462 + /// reader.readEdgeMap("flow", flowMap);
73.463 + /// \endcode
73.464 + ///
73.465 + /// With \c readNode() and \c readUndirEdge() functions you can read
73.466 + /// labeled Nodes and UndirEdges.
73.467 + ///
73.468 + /// \code
73.469 + /// reader.readNode("source", sourceNode);
73.470 + /// reader.readNode("target", targetNode);
73.471 + ///
73.472 + /// reader.readUndirEdge("observed", undirEdge);
73.473 + /// \endcode
73.474 + ///
73.475 + /// With the \c readAttribute() functions you can read an attribute
73.476 + /// in a variable. You can specify the reader for the attribute as
73.477 + /// the nodemaps.
73.478 + ///
73.479 + /// After you give all read commands you must call the \c run() member
73.480 + /// function, which execute all the commands.
73.481 + ///
73.482 + /// \code
73.483 + /// reader.run();
73.484 + /// \endcode
73.485 + ///
73.486 + /// \see GraphReader
73.487 + /// \see DefaultReaderTraits
73.488 + /// \see \ref UndirGraphWriter
73.489 + /// \see \ref graph-io-page
73.490 + ///
73.491 + /// \author Balazs Dezso
73.492 + template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
73.493 + class UndirGraphReader {
73.494 + public:
73.495 +
73.496 + typedef _Graph Graph;
73.497 + typedef typename Graph::Node Node;
73.498 + typedef typename Graph::Edge Edge;
73.499 + typedef typename Graph::UndirEdge UndirEdge;
73.500 +
73.501 + typedef _ReaderTraits ReaderTraits;
73.502 + typedef typename ReaderTraits::Skipper DefaultSkipper;
73.503 +
73.504 + /// \brief Construct a new UndirGraphReader.
73.505 + ///
73.506 + /// Construct a new UndirGraphReader. It reads into the given graph
73.507 + /// and it use the given reader as the default skipper.
73.508 + UndirGraphReader(std::istream& _is, Graph& _graph,
73.509 + const DefaultSkipper& _skipper = DefaultSkipper())
73.510 + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
73.511 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.512 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
73.513 + std::string(), skipper),
73.514 + node_reader(*reader, nodeset_reader, std::string()),
73.515 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
73.516 + attribute_reader(*reader, std::string()) {}
73.517 +
73.518 + /// \brief Construct a new UndirGraphReader.
73.519 + ///
73.520 + /// Construct a new UndirGraphReader. It reads into the given graph
73.521 + /// and it use the given reader as the default skipper.
73.522 + UndirGraphReader(const std::string& _filename, Graph& _graph,
73.523 + const DefaultSkipper& _skipper = DefaultSkipper())
73.524 + : reader(new LemonReader(_filename)), own_reader(true),
73.525 + skipper(_skipper),
73.526 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.527 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
73.528 + std::string(), skipper),
73.529 + node_reader(*reader, nodeset_reader, std::string()),
73.530 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
73.531 + attribute_reader(*reader, std::string()) {}
73.532 +
73.533 + /// \brief Construct a new UndirGraphReader.
73.534 + ///
73.535 + /// Construct a new UndirGraphReader. It reads into the given graph
73.536 + /// and it use the given reader as the default skipper.
73.537 + UndirGraphReader(LemonReader& _reader, Graph& _graph,
73.538 + const DefaultSkipper& _skipper = DefaultSkipper())
73.539 + : reader(_reader), own_reader(false), skipper(_skipper),
73.540 + nodeset_reader(*reader, _graph, std::string(), skipper),
73.541 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
73.542 + std::string(), skipper),
73.543 + node_reader(*reader, nodeset_reader, std::string()),
73.544 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
73.545 + attribute_reader(*reader, std::string()) {}
73.546 +
73.547 + /// \brief Destruct the graph reader.
73.548 + ///
73.549 + /// Destruct the graph reader.
73.550 + ~UndirGraphReader() {
73.551 + if (own_reader)
73.552 + delete reader;
73.553 + }
73.554 +
73.555 + /// \brief Add a new node map reader command for the reader.
73.556 + ///
73.557 + /// Add a new node map reader command for the reader.
73.558 + template <typename Map>
73.559 + UndirGraphReader& readNodeMap(std::string name, Map& map) {
73.560 + nodeset_reader.readNodeMap(name, map);
73.561 + return *this;
73.562 + }
73.563 +
73.564 + template <typename Map>
73.565 + UndirGraphReader& readNodeMap(std::string name, const Map& map) {
73.566 + nodeset_reader.readNodeMap(name, map);
73.567 + return *this;
73.568 + }
73.569 +
73.570 + /// \brief Add a new node map reader command for the reader.
73.571 + ///
73.572 + /// Add a new node map reader command for the reader.
73.573 + template <typename Reader, typename Map>
73.574 + UndirGraphReader& readNodeMap(std::string name, Map& map,
73.575 + const Reader& reader = Reader()) {
73.576 + nodeset_reader.readNodeMap(name, map, reader);
73.577 + return *this;
73.578 + }
73.579 +
73.580 + template <typename Reader, typename Map>
73.581 + UndirGraphReader& readNodeMap(std::string name, const Map& map,
73.582 + const Reader& reader = Reader()) {
73.583 + nodeset_reader.readNodeMap(name, map, reader);
73.584 + return *this;
73.585 + }
73.586 +
73.587 + /// \brief Add a new node map skipper command for the reader.
73.588 + ///
73.589 + /// Add a new node map skipper command for the reader.
73.590 + template <typename Reader>
73.591 + UndirGraphReader& skipNodeMap(std::string name,
73.592 + const Reader& reader = Reader()) {
73.593 + nodeset_reader.skipNodeMap(name, reader);
73.594 + return *this;
73.595 + }
73.596 +
73.597 + /// \brief Add a new undirected edge map reader command for the reader.
73.598 + ///
73.599 + /// Add a new undirected edge map reader command for the reader.
73.600 + template <typename Map>
73.601 + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
73.602 + undir_edgeset_reader.readUndirEdgeMap(name, map);
73.603 + return *this;
73.604 + }
73.605 +
73.606 + template <typename Map>
73.607 + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
73.608 + undir_edgeset_reader.readUndirEdgeMap(name, map);
73.609 + return *this;
73.610 + }
73.611 +
73.612 +
73.613 + /// \brief Add a new undirected edge map reader command for the reader.
73.614 + ///
73.615 + /// Add a new undirected edge map reader command for the reader.
73.616 + template <typename Reader, typename Map>
73.617 + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
73.618 + const Reader& reader = Reader()) {
73.619 + undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
73.620 + return *this;
73.621 + }
73.622 +
73.623 + template <typename Reader, typename Map>
73.624 + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
73.625 + const Reader& reader = Reader()) {
73.626 + undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
73.627 + return *this;
73.628 + }
73.629 +
73.630 + /// \brief Add a new undirected edge map skipper command for the reader.
73.631 + ///
73.632 + /// Add a new undirected edge map skipper command for the reader.
73.633 + template <typename Reader>
73.634 + UndirGraphReader& skipUndirEdgeMap(std::string name,
73.635 + const Reader& reader = Reader()) {
73.636 + undir_edgeset_reader.skipUndirMap(name, reader);
73.637 + return *this;
73.638 + }
73.639 +
73.640 +
73.641 + /// \brief Add a new edge map reader command for the reader.
73.642 + ///
73.643 + /// Add a new edge map reader command for the reader.
73.644 + template <typename Map>
73.645 + UndirGraphReader& readEdgeMap(std::string name, Map& map) {
73.646 + undir_edgeset_reader.readEdgeMap(name, map);
73.647 + return *this;
73.648 + }
73.649 +
73.650 + template <typename Map>
73.651 + UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
73.652 + undir_edgeset_reader.readEdgeMap(name, map);
73.653 + return *this;
73.654 + }
73.655 +
73.656 +
73.657 + /// \brief Add a new edge map reader command for the reader.
73.658 + ///
73.659 + /// Add a new edge map reader command for the reader.
73.660 + template <typename Reader, typename Map>
73.661 + UndirGraphReader& readEdgeMap(std::string name, Map& map,
73.662 + const Reader& reader = Reader()) {
73.663 + undir_edgeset_reader.readEdgeMap(name, map, reader);
73.664 + return *this;
73.665 + }
73.666 +
73.667 + template <typename Reader, typename Map>
73.668 + UndirGraphReader& readEdgeMap(std::string name, const Map& map,
73.669 + const Reader& reader = Reader()) {
73.670 + undir_edgeset_reader.readEdgeMap(name, map, reader);
73.671 + return *this;
73.672 + }
73.673 +
73.674 + /// \brief Add a new edge map skipper command for the reader.
73.675 + ///
73.676 + /// Add a new edge map skipper command for the reader.
73.677 + template <typename Reader>
73.678 + UndirGraphReader& skipEdgeMap(std::string name,
73.679 + const Reader& reader = Reader()) {
73.680 + undir_edgeset_reader.skipEdgeMap(name, reader);
73.681 + return *this;
73.682 + }
73.683 +
73.684 + /// \brief Add a new labeled node reader for the reader.
73.685 + ///
73.686 + /// Add a new labeled node reader for the reader.
73.687 + UndirGraphReader& readNode(std::string name, Node& node) {
73.688 + node_reader.readNode(name, node);
73.689 + return *this;
73.690 + }
73.691 +
73.692 + /// \brief Add a new labeled edge reader for the reader.
73.693 + ///
73.694 + /// Add a new labeled edge reader for the reader.
73.695 + UndirGraphReader& readEdge(std::string name, Edge& edge) {
73.696 + undir_edge_reader.readEdge(name, edge);
73.697 + }
73.698 +
73.699 + /// \brief Add a new labeled undirected edge reader for the reader.
73.700 + ///
73.701 + /// Add a new labeled undirected edge reader for the reader.
73.702 + UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
73.703 + undir_edge_reader.readUndirEdge(name, edge);
73.704 + }
73.705 +
73.706 + /// \brief Add a new attribute reader command.
73.707 + ///
73.708 + /// Add a new attribute reader command.
73.709 + template <typename Value>
73.710 + UndirGraphReader& readAttribute(std::string name, Value& value) {
73.711 + attribute_reader.readAttribute(name, value);
73.712 + return *this;
73.713 + }
73.714 +
73.715 + /// \brief Add a new attribute reader command.
73.716 + ///
73.717 + /// Add a new attribute reader command.
73.718 + template <typename Reader, typename Value>
73.719 + UndirGraphReader& readAttribute(std::string name, Value& value,
73.720 + const Reader& reader) {
73.721 + attribute_reader.readAttribute<Reader>(name, value, reader);
73.722 + return *this;
73.723 + }
73.724 +
73.725 + /// \brief Conversion operator to LemonReader.
73.726 + ///
73.727 + /// Conversion operator to LemonReader. It make possible
73.728 + /// to access the encapsulated \e LemonReader, this way
73.729 + /// you can attach to this reader new instances of
73.730 + /// \e LemonReader::SectionReader.
73.731 + operator LemonReader&() {
73.732 + return *reader;
73.733 + }
73.734 +
73.735 + /// \brief Executes the reader commands.
73.736 + ///
73.737 + /// Executes the reader commands.
73.738 + void run() {
73.739 + reader->run();
73.740 + }
73.741 +
73.742 + /// \brief Gives back the node by its id.
73.743 + ///
73.744 + /// It reads an id from the stream and gives back which node belongs to
73.745 + /// it. It is possible only if there was read an "id" named node map.
73.746 + Node readId(std::istream& is, Node) const {
73.747 + return nodeset_reader.readId(is, Node());
73.748 + }
73.749 +
73.750 + /// \brief Gives back the edge by its id.
73.751 + ///
73.752 + /// It reads an id from the stream and gives back which edge belongs to
73.753 + /// it. It is possible only if there was read an "id" named edge map.
73.754 + Edge readId(std::istream& is, Edge) const {
73.755 + return undir_edgeset_reader.readId(is, Edge());
73.756 + }
73.757 +
73.758 + /// \brief Gives back the undirected edge by its id.
73.759 + ///
73.760 + /// It reads an id from the stream and gives back which undirected edge
73.761 + /// belongs to it. It is possible only if there was read an "id" named
73.762 + /// edge map.
73.763 + UndirEdge readId(std::istream& is, UndirEdge) const {
73.764 + return undir_edgeset_reader.readId(is, UndirEdge());
73.765 + }
73.766 +
73.767 +
73.768 + private:
73.769 +
73.770 + LemonReader* reader;
73.771 + bool own_reader;
73.772 +
73.773 + DefaultSkipper skipper;
73.774 +
73.775 + NodeSetReader<Graph, ReaderTraits> nodeset_reader;
73.776 + UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
73.777 +
73.778 + NodeReader<Graph> node_reader;
73.779 + UndirEdgeReader<Graph> undir_edge_reader;
73.780 +
73.781 + AttributeReader<ReaderTraits> attribute_reader;
73.782 + };
73.783 +
73.784 + /// \brief Read an undir graph from the input.
73.785 + ///
73.786 + /// Read an undir graph from the input.
73.787 + /// \param is The input stream.
73.788 + /// \param g The graph.
73.789 + /// \param capacity The capacity map.
73.790 + template<typename Graph, typename CapacityMap>
73.791 + void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
73.792 + UndirGraphReader<Graph> reader(is, g);
73.793 + reader.readUndirEdgeMap("capacity", capacity);
73.794 + reader.run();
73.795 + }
73.796 +
73.797 + /// \brief Read an undir graph from the input.
73.798 + ///
73.799 + /// Read an undir graph from the input.
73.800 + /// \param is The input stream.
73.801 + /// \param g The graph.
73.802 + template<typename Graph>
73.803 + void readUndirGraph(std::istream& is, Graph &g) {
73.804 + UndirGraphReader<Graph> reader(is, g);
73.805 + reader.run();
73.806 + }
73.807 +
73.808 + /// @}
73.809 +}
73.810 +
73.811 +#endif
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
74.2 +++ b/lemon/graph_to_eps.h Mon May 23 04:48:14 2005 +0000
74.3 @@ -0,0 +1,1026 @@
74.4 +/* -*- C++ -*-
74.5 + * lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
74.6 + *
74.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
74.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
74.9 + *
74.10 + * Permission to use, modify and distribute this software is granted
74.11 + * provided that this copyright notice appears in all copies. For
74.12 + * precise terms see the accompanying LICENSE file.
74.13 + *
74.14 + * This software is provided "AS IS" with no warranty of any kind,
74.15 + * express or implied, and with no claim as to its suitability for any
74.16 + * purpose.
74.17 + *
74.18 + */
74.19 +
74.20 +#ifndef LEMON_GRAPH_TO_EPS_H
74.21 +#define LEMON_GRAPH_TO_EPS_H
74.22 +
74.23 +#include <sys/time.h>
74.24 +
74.25 +#include<iostream>
74.26 +#include<fstream>
74.27 +#include<sstream>
74.28 +#include<algorithm>
74.29 +#include<vector>
74.30 +
74.31 +#include <ctime>
74.32 +#include <cmath>
74.33 +
74.34 +#include<lemon/invalid.h>
74.35 +#include<lemon/xy.h>
74.36 +#include<lemon/maps.h>
74.37 +#include<lemon/bezier.h>
74.38 +
74.39 +
74.40 +///\ingroup io_group
74.41 +///\file
74.42 +///\brief Simple graph drawer
74.43 +///
74.44 +///\author Alpar Juttner
74.45 +
74.46 +namespace lemon {
74.47 +
74.48 +///Data structure representing RGB colors.
74.49 +
74.50 +///Data structure representing RGB colors.
74.51 +///\ingroup misc
74.52 +class Color
74.53 +{
74.54 + double _r,_g,_b;
74.55 +public:
74.56 + ///Default constructor
74.57 + Color() {}
74.58 + ///Constructor
74.59 + Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
74.60 + ///Returns the red component
74.61 +
74.62 + ///\todo \c red() could be a better name...
74.63 + double getR() const {return _r;}
74.64 + ///Returns the green component
74.65 + double getG() const {return _g;}
74.66 + ///Returns the blue component
74.67 + double getB() const {return _b;}
74.68 + ///Set the color components
74.69 + void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
74.70 +};
74.71 +
74.72 +///Maps <tt>int</tt>s to different \ref Color "Color"s
74.73 +
74.74 +///This map assing one of the predefined \ref Color "Color"s
74.75 +///to each <tt>int</tt>. It is possible to change the colors as well as their
74.76 +///number. The integer range is cyclically mapped to the provided set of colors.
74.77 +///
74.78 +///This is a true \ref concept::ReferenceMap "reference map", so you can also
74.79 +///change the actual colors.
74.80 +
74.81 +class ColorSet : public MapBase<int,Color>
74.82 +{
74.83 + std::vector<Color> colors;
74.84 +public:
74.85 + ///Constructor
74.86 +
74.87 + ///Constructor
74.88 + ///\param have_white indicates wheter white is
74.89 + ///amongst the provided color (\c true) or not (\c false). If it is true,
74.90 + ///white will be assigned to \c 0.
74.91 + ///\param num the number of the allocated colors. If it is \c 0
74.92 + ///the default color configuration is set up (26 color plus the while).
74.93 + ///If \c num is less then 26/27 then the default color list is cut. Otherwise
74.94 + ///the color list is filled repeatedly with the default color list.
74.95 + ColorSet(bool have_white=false,int num=0)
74.96 + {
74.97 + do {
74.98 + if(have_white) colors.push_back(Color(1,1,1));
74.99 +
74.100 + colors.push_back(Color(0,0,0));
74.101 + colors.push_back(Color(1,0,0));
74.102 + colors.push_back(Color(0,1,0));
74.103 + colors.push_back(Color(0,0,1));
74.104 + colors.push_back(Color(1,1,0));
74.105 + colors.push_back(Color(1,0,1));
74.106 + colors.push_back(Color(0,1,1));
74.107 +
74.108 + colors.push_back(Color(.5,0,0));
74.109 + colors.push_back(Color(0,.5,0));
74.110 + colors.push_back(Color(0,0,.5));
74.111 + colors.push_back(Color(.5,.5,0));
74.112 + colors.push_back(Color(.5,0,.5));
74.113 + colors.push_back(Color(0,.5,.5));
74.114 +
74.115 + colors.push_back(Color(.5,.5,.5));
74.116 + colors.push_back(Color(1,.5,.5));
74.117 + colors.push_back(Color(.5,1,.5));
74.118 + colors.push_back(Color(.5,.5,1));
74.119 + colors.push_back(Color(1,1,.5));
74.120 + colors.push_back(Color(1,.5,1));
74.121 + colors.push_back(Color(.5,1,1));
74.122 +
74.123 + colors.push_back(Color(1,.5,0));
74.124 + colors.push_back(Color(.5,1,0));
74.125 + colors.push_back(Color(1,0,.5));
74.126 + colors.push_back(Color(0,1,.5));
74.127 + colors.push_back(Color(0,.5,1));
74.128 + colors.push_back(Color(.5,0,1));
74.129 + } while(int(colors.size())<num);
74.130 + // colors.push_back(Color(1,1,1));
74.131 + if(num>0) colors.resize(num);
74.132 + }
74.133 + ///\e
74.134 + Color &operator[](int i)
74.135 + {
74.136 + return colors[i%colors.size()];
74.137 + }
74.138 + ///\e
74.139 + const Color &operator[](int i) const
74.140 + {
74.141 + return colors[i%colors.size()];
74.142 + }
74.143 + ///\e
74.144 + void set(int i,const Color &c)
74.145 + {
74.146 + colors[i%colors.size()]=c;
74.147 + }
74.148 + ///Sets the number of the exiting colors.
74.149 + void resize(int s) { colors.resize(s);}
74.150 + ///Returns the munber of the existing colors.
74.151 + std::size_t size() { return colors.size();}
74.152 +};
74.153 +
74.154 +///Returns a visible distinct \ref Color
74.155 +
74.156 +///Returns a \ref Color which is as different from the given parameter
74.157 +///as it is possible.
74.158 +inline Color distantColor(const Color &c)
74.159 +{
74.160 + return Color(c.getR()<.5?1:0,c.getG()<.5?1:0,c.getB()<.5?1:0);
74.161 +}
74.162 +///Returns black for light colors and white for the dark ones.
74.163 +
74.164 +///Returns black for light colors and white for the dark ones.
74.165 +///\todo weighted average would be better
74.166 +inline Color distantBW(const Color &c){
74.167 + double v=(.2125*c.getR()+.7154*c.getG()+.0721*c.getB())<.5?1:0;
74.168 + return Color(v,v,v);
74.169 +}
74.170 +
74.171 +///Default traits class of \ref GraphToEps
74.172 +
74.173 +///Default traits class of \ref GraphToEps
74.174 +///
74.175 +///\c G is the type of the underlying graph.
74.176 +template<class G>
74.177 +struct DefaultGraphToEpsTraits
74.178 +{
74.179 + typedef G Graph;
74.180 + typedef typename Graph::Node Node;
74.181 + typedef typename Graph::NodeIt NodeIt;
74.182 + typedef typename Graph::Edge Edge;
74.183 + typedef typename Graph::EdgeIt EdgeIt;
74.184 + typedef typename Graph::InEdgeIt InEdgeIt;
74.185 + typedef typename Graph::OutEdgeIt OutEdgeIt;
74.186 +
74.187 +
74.188 + const Graph &g;
74.189 +
74.190 + std::ostream& os;
74.191 +
74.192 + ConstMap<typename Graph::Node,xy<double> > _coords;
74.193 + ConstMap<typename Graph::Node,double > _nodeSizes;
74.194 + ConstMap<typename Graph::Node,int > _nodeShapes;
74.195 +
74.196 + ConstMap<typename Graph::Node,Color > _nodeColors;
74.197 + ConstMap<typename Graph::Edge,Color > _edgeColors;
74.198 +
74.199 + ConstMap<typename Graph::Edge,double > _edgeWidths;
74.200 +
74.201 + double _edgeWidthScale;
74.202 +
74.203 + double _nodeScale;
74.204 + double _xBorder, _yBorder;
74.205 + double _scale;
74.206 + double _nodeBorderQuotient;
74.207 +
74.208 + bool _drawArrows;
74.209 + double _arrowLength, _arrowWidth;
74.210 +
74.211 + bool _showNodes, _showEdges;
74.212 +
74.213 + bool _enableParallel;
74.214 + double _parEdgeDist;
74.215 +
74.216 + bool _showNodeText;
74.217 + ConstMap<typename Graph::Node,bool > _nodeTexts;
74.218 + double _nodeTextSize;
74.219 +
74.220 + bool _showNodePsText;
74.221 + ConstMap<typename Graph::Node,bool > _nodePsTexts;
74.222 + char *_nodePsTextsPreamble;
74.223 +
74.224 + bool _undir;
74.225 + bool _pleaseRemoveOsStream;
74.226 +
74.227 + bool _scaleToA4;
74.228 +
74.229 + std::string _title;
74.230 + std::string _copyright;
74.231 +
74.232 + enum NodeTextColorType
74.233 + { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
74.234 + ConstMap<typename Graph::Node,Color > _nodeTextColors;
74.235 +
74.236 + ///Constructor
74.237 +
74.238 + ///Constructor
74.239 + ///\param _g is a reference to the graph to be printed
74.240 + ///\param _os is a reference to the output stream.
74.241 + ///\param _os is a reference to the output stream.
74.242 + ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
74.243 + ///will be explicitly deallocated by the destructor.
74.244 + ///By default it is <tt>std::cout</tt>
74.245 + DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
74.246 + bool _pros=false) :
74.247 + g(_g), os(_os),
74.248 + _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
74.249 + _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
74.250 + _edgeWidths(1), _edgeWidthScale(0.3),
74.251 + _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
74.252 + _nodeBorderQuotient(.1),
74.253 + _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
74.254 + _showNodes(true), _showEdges(true),
74.255 + _enableParallel(false), _parEdgeDist(1),
74.256 + _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
74.257 + _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
74.258 + _undir(false),
74.259 + _pleaseRemoveOsStream(_pros), _scaleToA4(false),
74.260 + _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0))
74.261 + {}
74.262 +};
74.263 +
74.264 +///Helper class to implement the named parameters of \ref graphToEps()
74.265 +
74.266 +///Helper class to implement the named parameters of \ref graphToEps()
74.267 +///\todo Is 'helper class' a good name for this?
74.268 +///
74.269 +///\todo Follow PostScript's DSC.
74.270 +/// Use own dictionary.
74.271 +///\todo Useful new features.
74.272 +/// - Linestyles: dotted, dashed etc.
74.273 +/// - A second color and percent value for the lines.
74.274 +template<class T> class GraphToEps : public T
74.275 +{
74.276 + // Can't believe it is required by the C++ standard
74.277 + using T::g;
74.278 + using T::os;
74.279 +
74.280 + using T::_coords;
74.281 + using T::_nodeSizes;
74.282 + using T::_nodeShapes;
74.283 + using T::_nodeColors;
74.284 + using T::_edgeColors;
74.285 + using T::_edgeWidths;
74.286 +
74.287 + using T::_edgeWidthScale;
74.288 + using T::_nodeScale;
74.289 + using T::_xBorder;
74.290 + using T::_yBorder;
74.291 + using T::_scale;
74.292 + using T::_nodeBorderQuotient;
74.293 +
74.294 + using T::_drawArrows;
74.295 + using T::_arrowLength;
74.296 + using T::_arrowWidth;
74.297 +
74.298 + using T::_showNodes;
74.299 + using T::_showEdges;
74.300 +
74.301 + using T::_enableParallel;
74.302 + using T::_parEdgeDist;
74.303 +
74.304 + using T::_showNodeText;
74.305 + using T::_nodeTexts;
74.306 + using T::_nodeTextSize;
74.307 +
74.308 + using T::_showNodePsText;
74.309 + using T::_nodePsTexts;
74.310 + using T::_nodePsTextsPreamble;
74.311 +
74.312 + using T::_undir;
74.313 + using T::_pleaseRemoveOsStream;
74.314 +
74.315 + using T::_scaleToA4;
74.316 +
74.317 + using T::_title;
74.318 + using T::_copyright;
74.319 +
74.320 + using T::NodeTextColorType;
74.321 + using T::CUST_COL;
74.322 + using T::DIST_COL;
74.323 + using T::DIST_BW;
74.324 + using T::_nodeTextColorType;
74.325 + using T::_nodeTextColors;
74.326 + // dradnats ++C eht yb deriuqer si ti eveileb t'naC
74.327 +
74.328 + typedef typename T::Graph Graph;
74.329 + typedef typename Graph::Node Node;
74.330 + typedef typename Graph::NodeIt NodeIt;
74.331 + typedef typename Graph::Edge Edge;
74.332 + typedef typename Graph::EdgeIt EdgeIt;
74.333 + typedef typename Graph::InEdgeIt InEdgeIt;
74.334 + typedef typename Graph::OutEdgeIt OutEdgeIt;
74.335 +
74.336 + static const int INTERPOL_PREC=20;
74.337 + static const double A4HEIGHT = 841.8897637795276;
74.338 + static const double A4WIDTH = 595.275590551181;
74.339 + static const double A4BORDER = 15;
74.340 +
74.341 + bool dontPrint;
74.342 +
74.343 +public:
74.344 + ///Node shapes
74.345 +
74.346 + ///Node shapes
74.347 + ///
74.348 + enum NodeShapes {
74.349 + /// = 0
74.350 + ///\image html nodeshape_0.png
74.351 + ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
74.352 + CIRCLE=0,
74.353 + /// = 1
74.354 + ///\image html nodeshape_1.png
74.355 + ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
74.356 + ///
74.357 + SQUARE=1,
74.358 + /// = 2
74.359 + ///\image html nodeshape_2.png
74.360 + ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
74.361 + ///
74.362 + DIAMOND=2
74.363 + };
74.364 +
74.365 +private:
74.366 + class edgeLess {
74.367 + const Graph &g;
74.368 + public:
74.369 + edgeLess(const Graph &_g) : g(_g) {}
74.370 + bool operator()(Edge a,Edge b) const
74.371 + {
74.372 + Node ai=std::min(g.source(a),g.target(a));
74.373 + Node aa=std::max(g.source(a),g.target(a));
74.374 + Node bi=std::min(g.source(b),g.target(b));
74.375 + Node ba=std::max(g.source(b),g.target(b));
74.376 + return ai<bi ||
74.377 + (ai==bi && (aa < ba ||
74.378 + (aa==ba && ai==g.source(a) && bi==g.target(b))));
74.379 + }
74.380 + };
74.381 + bool isParallel(Edge e,Edge f) const
74.382 + {
74.383 + return (g.source(e)==g.source(f)&&
74.384 + g.target(e)==g.target(f)) ||
74.385 + (g.source(e)==g.target(f)&&
74.386 + g.target(e)==g.source(f));
74.387 + }
74.388 + template<class TT>
74.389 + static std::string psOut(const xy<TT> &p)
74.390 + {
74.391 + std::ostringstream os;
74.392 + os << p.x << ' ' << p.y;
74.393 + return os.str();
74.394 + }
74.395 + static std::string psOut(const Color &c)
74.396 + {
74.397 + std::ostringstream os;
74.398 + os << c.getR() << ' ' << c.getG() << ' ' << c.getB();
74.399 + return os.str();
74.400 + }
74.401 +
74.402 +public:
74.403 + GraphToEps(const T &t) : T(t), dontPrint(false) {};
74.404 +
74.405 + template<class X> struct CoordsTraits : public T {
74.406 + const X &_coords;
74.407 + CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
74.408 + };
74.409 + ///Sets the map of the node coordinates
74.410 +
74.411 + ///Sets the map of the node coordinates.
74.412 + ///\param x must be a node map with xy<double> or \ref xy "xy<int>" values.
74.413 + template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
74.414 + dontPrint=true;
74.415 + return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
74.416 + }
74.417 + template<class X> struct NodeSizesTraits : public T {
74.418 + const X &_nodeSizes;
74.419 + NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
74.420 + };
74.421 + ///Sets the map of the node sizes
74.422 +
74.423 + ///Sets the map of the node sizes
74.424 + ///\param x must be a node map with \c double (or convertible) values.
74.425 + template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
74.426 + {
74.427 + dontPrint=true;
74.428 + return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
74.429 + }
74.430 + template<class X> struct NodeShapesTraits : public T {
74.431 + const X &_nodeShapes;
74.432 + NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
74.433 + };
74.434 + ///Sets the map of the node shapes
74.435 +
74.436 + ///Sets the map of the node shapes.
74.437 + ///The availabe shape values
74.438 + ///can be found in \ref NodeShapes "enum NodeShapes".
74.439 + ///\param x must be a node map with \c int (or convertible) values.
74.440 + ///\sa NodeShapes
74.441 + template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
74.442 + {
74.443 + dontPrint=true;
74.444 + return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
74.445 + }
74.446 + template<class X> struct NodeTextsTraits : public T {
74.447 + const X &_nodeTexts;
74.448 + NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
74.449 + };
74.450 + ///Sets the text printed on the nodes
74.451 +
74.452 + ///Sets the text printed on the nodes
74.453 + ///\param x must be a node map with type that can be pushed to a standard
74.454 + ///ostream.
74.455 + template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
74.456 + {
74.457 + dontPrint=true;
74.458 + _showNodeText=true;
74.459 + return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
74.460 + }
74.461 + template<class X> struct NodePsTextsTraits : public T {
74.462 + const X &_nodePsTexts;
74.463 + NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
74.464 + };
74.465 + ///Inserts a PostScript block to the nodes
74.466 +
74.467 + ///With this command it is possible to insert a verbatim PostScript
74.468 + ///block to the nodes.
74.469 + ///The PS current point will be moved to the centre of the node before
74.470 + ///the PostScript block inserted.
74.471 + ///
74.472 + ///Before and after the block a newline character is inserted to you
74.473 + ///don't have to bother with the separators.
74.474 + ///
74.475 + ///\param x must be a node map with type that can be pushed to a standard
74.476 + ///ostream.
74.477 + ///
74.478 + ///\sa nodePsTextsPreamble()
74.479 + ///\todo Offer the choise not to move to the centre but pass the coordinates
74.480 + ///to the Postscript block inserted.
74.481 + template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
74.482 + {
74.483 + dontPrint=true;
74.484 + _showNodePsText=true;
74.485 + return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
74.486 + }
74.487 + template<class X> struct EdgeWidthsTraits : public T {
74.488 + const X &_edgeWidths;
74.489 + EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
74.490 + };
74.491 + ///Sets the map of the edge widths
74.492 +
74.493 + ///Sets the map of the edge widths
74.494 + ///\param x must be a edge map with \c double (or convertible) values.
74.495 + template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
74.496 + {
74.497 + dontPrint=true;
74.498 + return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
74.499 + }
74.500 +
74.501 + template<class X> struct NodeColorsTraits : public T {
74.502 + const X &_nodeColors;
74.503 + NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
74.504 + };
74.505 + ///Sets the map of the node colors
74.506 +
74.507 + ///Sets the map of the node colors
74.508 + ///\param x must be a node map with \ref Color values.
74.509 + template<class X> GraphToEps<NodeColorsTraits<X> >
74.510 + nodeColors(const X &x)
74.511 + {
74.512 + dontPrint=true;
74.513 + return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
74.514 + }
74.515 + template<class X> struct NodeTextColorsTraits : public T {
74.516 + const X &_nodeTextColors;
74.517 + NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
74.518 + };
74.519 + ///Sets the map of the node text colors
74.520 +
74.521 + ///Sets the map of the node text colors
74.522 + ///\param x must be a node map with \ref Color values.
74.523 + template<class X> GraphToEps<NodeTextColorsTraits<X> >
74.524 + nodeTextColors(const X &x)
74.525 + {
74.526 + dontPrint=true;
74.527 + _nodeTextColorType=CUST_COL;
74.528 + return GraphToEps<NodeTextColorsTraits<X> >
74.529 + (NodeTextColorsTraits<X>(*this,x));
74.530 + }
74.531 + template<class X> struct EdgeColorsTraits : public T {
74.532 + const X &_edgeColors;
74.533 + EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
74.534 + };
74.535 + ///Sets the map of the edge colors
74.536 +
74.537 + ///Sets the map of the edge colors
74.538 + ///\param x must be a edge map with \ref Color values.
74.539 + template<class X> GraphToEps<EdgeColorsTraits<X> >
74.540 + edgeColors(const X &x)
74.541 + {
74.542 + dontPrint=true;
74.543 + return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
74.544 + }
74.545 + ///Sets a global scale factor for node sizes
74.546 +
74.547 + ///Sets a global scale factor for node sizes
74.548 + ///
74.549 + GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
74.550 + ///Sets a global scale factor for edge widths
74.551 +
74.552 + ///Sets a global scale factor for edge widths
74.553 + ///
74.554 + GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
74.555 + ///Sets a global scale factor for the whole picture
74.556 +
74.557 + ///Sets a global scale factor for the whole picture
74.558 + ///
74.559 + GraphToEps<T> &scale(double d) {_scale=d;return *this;}
74.560 + ///Sets the width of the border around the picture
74.561 +
74.562 + ///Sets the width of the border around the picture
74.563 + ///
74.564 + GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
74.565 + ///Sets the width of the border around the picture
74.566 +
74.567 + ///Sets the width of the border around the picture
74.568 + ///
74.569 + GraphToEps<T> &border(double x, double y) {
74.570 + _xBorder=x;_yBorder=y;return *this;
74.571 + }
74.572 + ///Sets whether to draw arrows
74.573 +
74.574 + ///Sets whether to draw arrows
74.575 + ///
74.576 + GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
74.577 + ///Sets the length of the arrowheads
74.578 +
74.579 + ///Sets the length of the arrowheads
74.580 + ///
74.581 + GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
74.582 + ///Sets the width of the arrowheads
74.583 +
74.584 + ///Sets the width of the arrowheads
74.585 + ///
74.586 + GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
74.587 +
74.588 + ///Scales the drawing to fit to A4 page
74.589 +
74.590 + ///Scales the drawing to fit to A4 page
74.591 + ///
74.592 + GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
74.593 +
74.594 + ///Enables parallel edges
74.595 +
74.596 + ///Enables parallel edges
74.597 + ///\todo Partially implemented
74.598 + GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
74.599 +
74.600 + ///Sets the distance
74.601 +
74.602 + ///Sets the distance
74.603 + ///
74.604 + GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
74.605 +
74.606 + ///Hides the edges
74.607 +
74.608 + ///Hides the edges
74.609 + ///
74.610 + GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
74.611 + ///Hides the nodes
74.612 +
74.613 + ///Hides the nodes
74.614 + ///
74.615 + GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
74.616 +
74.617 + ///Sets the size of the node texts
74.618 +
74.619 + ///Sets the size of the node texts
74.620 + ///
74.621 + GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
74.622 +
74.623 + ///Sets the color of the node texts to be different from the node color
74.624 +
74.625 + ///Sets the color of the node texts to be as different from the node color
74.626 + ///as it is possible
74.627 + ///
74.628 + GraphToEps<T> &distantColorNodeTexts()
74.629 + {_nodeTextColorType=DIST_COL;return *this;}
74.630 + ///Sets the color of the node texts to be black or white and always visible.
74.631 +
74.632 + ///Sets the color of the node texts to be black or white according to
74.633 + ///which is more
74.634 + ///different from the node color
74.635 + ///
74.636 + GraphToEps<T> &distantBWNodeTexts()
74.637 + {_nodeTextColorType=DIST_BW;return *this;}
74.638 +
74.639 + ///Gives a preamble block for node Postscript block.
74.640 +
74.641 + ///Gives a preamble block for node Postscript block.
74.642 + ///
74.643 + ///\sa nodePsTexts()
74.644 + GraphToEps<T> & nodePsTextsPreamble(const char *str) {
74.645 + _nodePsTextsPreamble=str ;return *this;
74.646 + }
74.647 + ///Sets whether the the graph is undirected
74.648 +
74.649 + ///Sets whether the the graph is undirected
74.650 + ///
74.651 + GraphToEps<T> &undir(bool b=true) {_undir=b;return *this;}
74.652 + ///Sets whether the the graph is directed
74.653 +
74.654 + ///Sets whether the the graph is directed.
74.655 + ///Use it to show the undirected edges as a pair of directed ones.
74.656 + GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
74.657 +
74.658 + ///Sets the title.
74.659 +
74.660 + ///Sets the title of the generated image,
74.661 + ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
74.662 + ///the EPS file.
74.663 + GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
74.664 + ///Sets the copyright statement.
74.665 +
74.666 + ///Sets the copyright statement of the generated image,
74.667 + ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
74.668 + ///the EPS file.
74.669 + ///\todo Multiline copyright notice could be supported.
74.670 + GraphToEps<T> ©right(const std::string &t) {_copyright=t;return *this;}
74.671 +
74.672 +protected:
74.673 + bool isInsideNode(xy<double> p, double r,int t)
74.674 + {
74.675 + switch(t) {
74.676 + case CIRCLE:
74.677 + return p.normSquare()<=r*r;
74.678 + case SQUARE:
74.679 + return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
74.680 + case DIAMOND:
74.681 + return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
74.682 + }
74.683 + return false;
74.684 + }
74.685 +
74.686 +public:
74.687 + ~GraphToEps() { }
74.688 +
74.689 + ///Draws the graph.
74.690 +
74.691 + ///Like other functions using
74.692 + ///\ref named-templ-func-param "named template parameters",
74.693 + ///this function calles the algorithm itself, i.e. in this case
74.694 + ///it draws the graph.
74.695 + void run() {
74.696 + if(dontPrint) return;
74.697 +
74.698 + os << "%!PS-Adobe-2.0 EPSF-2.0\n";
74.699 + if(_title.size()>0) os << "%%Title: " << _title << '\n';
74.700 + if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
74.701 +// << "%%Copyright: XXXX\n"
74.702 + os << "%%Creator: LEMON GraphToEps function\n";
74.703 +
74.704 + {
74.705 + char cbuf[50];
74.706 + timeval tv;
74.707 + gettimeofday(&tv, 0);
74.708 + ctime_r(&tv.tv_sec,cbuf);
74.709 + os << "%%CreationDate: " << cbuf;
74.710 + }
74.711 + ///\todo: Chech whether the graph is empty.
74.712 + BoundingBox<double> bb;
74.713 + for(NodeIt n(g);n!=INVALID;++n) {
74.714 + double ns=_nodeSizes[n]*_nodeScale;
74.715 + xy<double> p(ns,ns);
74.716 + bb+=p+_coords[n];
74.717 + bb+=-p+_coords[n];
74.718 + }
74.719 + if(_scaleToA4)
74.720 + os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
74.721 + else os << "%%BoundingBox: "
74.722 + << bb.left()* _scale-_xBorder << ' '
74.723 + << bb.bottom()*_scale-_yBorder << ' '
74.724 + << bb.right()* _scale+_xBorder << ' '
74.725 + << bb.top()* _scale+_yBorder << '\n';
74.726 +
74.727 + os << "%%EndComments\n";
74.728 +
74.729 + //x1 y1 x2 y2 x3 y3 cr cg cb w
74.730 + os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
74.731 + << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
74.732 + os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
74.733 + //x y r
74.734 + os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
74.735 + //x y r
74.736 + os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
74.737 + << " 2 index 1 index sub 2 index 2 index add lineto\n"
74.738 + << " 2 index 1 index sub 2 index 2 index sub lineto\n"
74.739 + << " 2 index 1 index add 2 index 2 index sub lineto\n"
74.740 + << " closepath pop pop pop} bind def\n";
74.741 + //x y r
74.742 + os << "/di { newpath 2 index 1 index add 2 index moveto\n"
74.743 + << " 2 index 2 index 2 index add lineto\n"
74.744 + << " 2 index 1 index sub 2 index lineto\n"
74.745 + << " 2 index 2 index 2 index sub lineto\n"
74.746 + << " closepath pop pop pop} bind def\n";
74.747 + // x y r cr cg cb
74.748 + os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
74.749 + << " setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
74.750 + << " } bind def\n";
74.751 + os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
74.752 + << " setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
74.753 + << " } bind def\n";
74.754 + os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
74.755 + << " setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
74.756 + << " } bind def\n";
74.757 + os << "/arrl " << _arrowLength << " def\n";
74.758 + os << "/arrw " << _arrowWidth << " def\n";
74.759 + // l dx_norm dy_norm
74.760 + os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
74.761 + //len w dx_norm dy_norm x1 y1 cr cg cb
74.762 + os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
74.763 + << " /w exch def /len exch def\n"
74.764 + // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
74.765 + << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
74.766 + << " len w sub arrl sub dx dy lrl\n"
74.767 + << " arrw dy dx neg lrl\n"
74.768 + << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
74.769 + << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
74.770 + << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
74.771 + << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
74.772 + << " arrw dy dx neg lrl\n"
74.773 + << " len w sub arrl sub neg dx dy lrl\n"
74.774 + << " closepath fill } bind def\n";
74.775 + os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
74.776 + << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
74.777 +
74.778 + os << "\ngsave\n";
74.779 + if(_scaleToA4)
74.780 + if(bb.height()>bb.width()) {
74.781 + double sc= min((A4HEIGHT-2*A4BORDER)/bb.height(),
74.782 + (A4WIDTH-2*A4BORDER)/bb.width());
74.783 + os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
74.784 + << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER << " translate\n"
74.785 + << sc << " dup scale\n"
74.786 + << -bb.left() << ' ' << -bb.bottom() << " translate\n";
74.787 + }
74.788 + else {
74.789 + //\todo Verify centering
74.790 + double sc= min((A4HEIGHT-2*A4BORDER)/bb.width(),
74.791 + (A4WIDTH-2*A4BORDER)/bb.height());
74.792 + os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
74.793 + << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER << " translate\n"
74.794 + << sc << " dup scale\n90 rotate\n"
74.795 + << -bb.left() << ' ' << -bb.top() << " translate\n";
74.796 + }
74.797 + else if(_scale!=1.0) os << _scale << " dup scale\n";
74.798 +
74.799 + if(_showEdges) {
74.800 + os << "%Edges:\ngsave\n";
74.801 + if(_enableParallel) {
74.802 + std::vector<Edge> el;
74.803 + for(EdgeIt e(g);e!=INVALID;++e)
74.804 + if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
74.805 + el.push_back(e);
74.806 + sort(el.begin(),el.end(),edgeLess(g));
74.807 +
74.808 + typename std::vector<Edge>::iterator j;
74.809 + for(typename std::vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
74.810 + for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
74.811 +
74.812 + double sw=0;
74.813 + for(typename std::vector<Edge>::iterator e=i;e!=j;++e)
74.814 + sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
74.815 + sw-=_parEdgeDist;
74.816 + sw/=-2.0;
74.817 + xy<double> dvec(_coords[g.target(*i)]-_coords[g.source(*i)]);
74.818 + double l=std::sqrt(dvec.normSquare());
74.819 + ///\todo better 'epsilon' would be nice here.
74.820 + xy<double> d(dvec/std::max(l,1e-9));
74.821 + xy<double> m;
74.822 +// m=xy<double>(_coords[g.target(*i)]+_coords[g.source(*i)])/2.0;
74.823 +
74.824 +// m=xy<double>(_coords[g.source(*i)])+
74.825 +// dvec*(double(_nodeSizes[g.source(*i)])/
74.826 +// (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
74.827 +
74.828 + m=xy<double>(_coords[g.source(*i)])+
74.829 + d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
74.830 +
74.831 + for(typename std::vector<Edge>::iterator e=i;e!=j;++e) {
74.832 + sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
74.833 + xy<double> mm=m+rot90(d)*sw/.75;
74.834 + if(_drawArrows) {
74.835 + int node_shape;
74.836 + xy<double> s=_coords[g.source(*e)];
74.837 + xy<double> t=_coords[g.target(*e)];
74.838 + double rn=_nodeSizes[g.target(*e)]*_nodeScale;
74.839 + node_shape=_nodeShapes[g.target(*e)];
74.840 + Bezier3 bez(s,mm,mm,t);
74.841 + double t1=0,t2=1;
74.842 + for(int i=0;i<INTERPOL_PREC;++i)
74.843 + if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
74.844 + else t1=(t1+t2)/2;
74.845 + xy<double> apoint=bez((t1+t2)/2);
74.846 + rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale;
74.847 + rn*=rn;
74.848 + t2=(t1+t2)/2;t1=0;
74.849 + for(int i=0;i<INTERPOL_PREC;++i)
74.850 + if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
74.851 + else t2=(t1+t2)/2;
74.852 + xy<double> linend=bez((t1+t2)/2);
74.853 + bez=bez.before((t1+t2)/2);
74.854 +// rn=_nodeSizes[g.source(*e)]*_nodeScale;
74.855 +// node_shape=_nodeShapes[g.source(*e)];
74.856 +// t1=0;t2=1;
74.857 +// for(int i=0;i<INTERPOL_PREC;++i)
74.858 +// if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
74.859 +// else t2=(t1+t2)/2;
74.860 +// bez=bez.after((t1+t2)/2);
74.861 + os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
74.862 + << _edgeColors[*e].getR() << ' '
74.863 + << _edgeColors[*e].getG() << ' '
74.864 + << _edgeColors[*e].getB() << " setrgbcolor newpath\n"
74.865 + << bez.p1.x << ' ' << bez.p1.y << " moveto\n"
74.866 + << bez.p2.x << ' ' << bez.p2.y << ' '
74.867 + << bez.p3.x << ' ' << bez.p3.y << ' '
74.868 + << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
74.869 + xy<double> dd(rot90(linend-apoint));
74.870 + dd*=(.5*_edgeWidths[*e]*_edgeWidthScale+_arrowWidth)/
74.871 + std::sqrt(dd.normSquare());
74.872 + os << "newpath " << psOut(apoint) << " moveto "
74.873 + << psOut(linend+dd) << " lineto "
74.874 + << psOut(linend-dd) << " lineto closepath fill\n";
74.875 + }
74.876 + else {
74.877 + os << _coords[g.source(*e)].x << ' '
74.878 + << _coords[g.source(*e)].y << ' '
74.879 + << mm.x << ' ' << mm.y << ' '
74.880 + << _coords[g.target(*e)].x << ' '
74.881 + << _coords[g.target(*e)].y << ' '
74.882 + << _edgeColors[*e].getR() << ' '
74.883 + << _edgeColors[*e].getG() << ' '
74.884 + << _edgeColors[*e].getB() << ' '
74.885 + << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
74.886 + }
74.887 + sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
74.888 + }
74.889 + }
74.890 + }
74.891 + else for(EdgeIt e(g);e!=INVALID;++e)
74.892 + if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
74.893 + if(_drawArrows) {
74.894 + xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
74.895 + double rn=_nodeSizes[g.target(e)]*_nodeScale;
74.896 + int node_shape=_nodeShapes[g.target(e)];
74.897 + double t1=0,t2=1;
74.898 + for(int i=0;i<INTERPOL_PREC;++i)
74.899 + if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
74.900 + else t2=(t1+t2)/2;
74.901 + double l=sqrt(d.normSquare());
74.902 + d/=l;
74.903 +
74.904 + os << l*(1-(t1+t2)/2) << ' '
74.905 + << _edgeWidths[e]*_edgeWidthScale << ' '
74.906 + << d.x << ' ' << d.y << ' '
74.907 + << _coords[g.source(e)].x << ' '
74.908 + << _coords[g.source(e)].y << ' '
74.909 + << _edgeColors[e].getR() << ' '
74.910 + << _edgeColors[e].getG() << ' '
74.911 + << _edgeColors[e].getB() << " arr\n";
74.912 + }
74.913 + else os << _coords[g.source(e)].x << ' '
74.914 + << _coords[g.source(e)].y << ' '
74.915 + << _coords[g.target(e)].x << ' '
74.916 + << _coords[g.target(e)].y << ' '
74.917 + << _edgeColors[e].getR() << ' '
74.918 + << _edgeColors[e].getG() << ' '
74.919 + << _edgeColors[e].getB() << ' '
74.920 + << _edgeWidths[e]*_edgeWidthScale << " l\n";
74.921 + os << "grestore\n";
74.922 + }
74.923 + if(_showNodes) {
74.924 + os << "%Nodes:\ngsave\n";
74.925 + for(NodeIt n(g);n!=INVALID;++n) {
74.926 + os << _coords[n].x << ' ' << _coords[n].y << ' '
74.927 + << _nodeSizes[n]*_nodeScale << ' '
74.928 + << _nodeColors[n].getR() << ' '
74.929 + << _nodeColors[n].getG() << ' '
74.930 + << _nodeColors[n].getB() << ' ';
74.931 + switch(_nodeShapes[n]) {
74.932 + case CIRCLE:
74.933 + os<< "nc";break;
74.934 + case SQUARE:
74.935 + os<< "nsq";break;
74.936 + case DIAMOND:
74.937 + os<< "ndi";break;
74.938 + }
74.939 + os<<'\n';
74.940 + }
74.941 + os << "grestore\n";
74.942 + }
74.943 + if(_showNodeText) {
74.944 + os << "%Node texts:\ngsave\n";
74.945 + os << "/fosi " << _nodeTextSize << " def\n";
74.946 + os << "(Helvetica) findfont fosi scalefont setfont\n";
74.947 + for(NodeIt n(g);n!=INVALID;++n) {
74.948 + switch(_nodeTextColorType) {
74.949 + case DIST_COL:
74.950 + os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
74.951 + break;
74.952 + case DIST_BW:
74.953 + os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
74.954 + break;
74.955 + case CUST_COL:
74.956 + os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
74.957 + break;
74.958 + default:
74.959 + os << "0 0 0 setrgbcolor\n";
74.960 + }
74.961 + os << _coords[n].x << ' ' << _coords[n].y
74.962 + << " (" << _nodeTexts[n] << ") cshow\n";
74.963 + }
74.964 + os << "grestore\n";
74.965 + }
74.966 + if(_showNodePsText) {
74.967 + os << "%Node PS blocks:\ngsave\n";
74.968 + for(NodeIt n(g);n!=INVALID;++n)
74.969 + os << _coords[n].x << ' ' << _coords[n].y
74.970 + << " moveto\n" << _nodePsTexts[n] << "\n";
74.971 + os << "grestore\n";
74.972 + }
74.973 +
74.974 + os << "grestore\nshowpage\n";
74.975 +
74.976 + //CleanUp:
74.977 + if(_pleaseRemoveOsStream) {delete &os;}
74.978 + }
74.979 +};
74.980 +
74.981 +
74.982 +///Generates an EPS file from a graph
74.983 +
74.984 +///\ingroup io_group
74.985 +///Generates an EPS file from a graph.
74.986 +///\param g is a reference to the graph to be printed
74.987 +///\param os is a reference to the output stream.
74.988 +///By default it is <tt>std::cout</tt>
74.989 +///
74.990 +///This function also has a lot of
74.991 +///\ref named-templ-func-param "named parameters",
74.992 +///they are declared as the members of class \ref GraphToEps. The following
74.993 +///example shows how to use these parameters.
74.994 +///\code
74.995 +/// graphToEps(g,os).scale(10).coords(coords)
74.996 +/// .nodeScale(2).nodeSizes(sizes)
74.997 +/// .edgeWidthScale(.4).run();
74.998 +///\endcode
74.999 +///\warning Don't forget to put the \ref GraphToEps::run() "run()"
74.1000 +///to the end of the parameter list.
74.1001 +///\sa GraphToEps
74.1002 +///\sa graphToEps(G &g, char *file_name)
74.1003 +template<class G>
74.1004 +GraphToEps<DefaultGraphToEpsTraits<G> >
74.1005 +graphToEps(G &g, std::ostream& os=std::cout)
74.1006 +{
74.1007 + return
74.1008 + GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
74.1009 +}
74.1010 +
74.1011 +///Generates an EPS file from a graph
74.1012 +
74.1013 +///\ingroup misc
74.1014 +///This function does the same as
74.1015 +///\ref graphToEps(G &g,std::ostream& os)
74.1016 +///but it writes its output into the file \c file_name
74.1017 +///instead of a stream.
74.1018 +///\sa graphToEps(G &g, std::ostream& os)
74.1019 +template<class G>
74.1020 +GraphToEps<DefaultGraphToEpsTraits<G> >
74.1021 +graphToEps(G &g,const char *file_name)
74.1022 +{
74.1023 + return GraphToEps<DefaultGraphToEpsTraits<G> >
74.1024 + (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
74.1025 +}
74.1026 +
74.1027 +} //END OF NAMESPACE LEMON
74.1028 +
74.1029 +#endif // LEMON_GRAPH_TO_EPS_H
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/lemon/graph_utils.h Mon May 23 04:48:14 2005 +0000
75.3 @@ -0,0 +1,861 @@
75.4 +/* -*- C++ -*-
75.5 + * lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library
75.6 + *
75.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
75.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
75.9 + *
75.10 + * Permission to use, modify and distribute this software is granted
75.11 + * provided that this copyright notice appears in all copies. For
75.12 + * precise terms see the accompanying LICENSE file.
75.13 + *
75.14 + * This software is provided "AS IS" with no warranty of any kind,
75.15 + * express or implied, and with no claim as to its suitability for any
75.16 + * purpose.
75.17 + *
75.18 + */
75.19 +
75.20 +#ifndef LEMON_GRAPH_UTILS_H
75.21 +#define LEMON_GRAPH_UTILS_H
75.22 +
75.23 +#include <iterator>
75.24 +#include <vector>
75.25 +#include <map>
75.26 +
75.27 +#include <lemon/invalid.h>
75.28 +#include <lemon/utility.h>
75.29 +#include <lemon/maps.h>
75.30 +
75.31 +///\ingroup gutils
75.32 +///\file
75.33 +///\brief Graph utilities.
75.34 +///
75.35 +///\todo Please
75.36 +///revise the documentation.
75.37 +///
75.38 +
75.39 +
75.40 +namespace lemon {
75.41 +
75.42 + /// \addtogroup gutils
75.43 + /// @{
75.44 +
75.45 + /// \brief Function to count the items in the graph.
75.46 + ///
75.47 + /// This function counts the items in the graph.
75.48 + /// The complexity of the function is O(n) because
75.49 + /// it iterates on all of the items.
75.50 +
75.51 + template <typename Graph, typename ItemIt>
75.52 + inline int countItems(const Graph& g) {
75.53 + int num = 0;
75.54 + for (ItemIt it(g); it != INVALID; ++it) {
75.55 + ++num;
75.56 + }
75.57 + return num;
75.58 + }
75.59 +
75.60 + // Node counting:
75.61 +
75.62 + template <typename Graph>
75.63 + inline
75.64 + typename enable_if<typename Graph::NodeNumTag, int>::type
75.65 + _countNodes(const Graph &g) {
75.66 + return g.nodeNum();
75.67 + }
75.68 +
75.69 + template <typename Graph>
75.70 + inline int _countNodes(Wrap<Graph> w) {
75.71 + return countItems<Graph, typename Graph::NodeIt>(w.value);
75.72 + }
75.73 +
75.74 + /// \brief Function to count the nodes in the graph.
75.75 + ///
75.76 + /// This function counts the nodes in the graph.
75.77 + /// The complexity of the function is O(n) but for some
75.78 + /// graph structure it is specialized to run in O(1).
75.79 + ///
75.80 + /// \todo refer how to specialize it
75.81 +
75.82 + template <typename Graph>
75.83 + inline int countNodes(const Graph& g) {
75.84 + return _countNodes<Graph>(g);
75.85 + }
75.86 +
75.87 + // Edge counting:
75.88 +
75.89 + template <typename Graph>
75.90 + inline
75.91 + typename enable_if<typename Graph::EdgeNumTag, int>::type
75.92 + _countEdges(const Graph &g) {
75.93 + return g.edgeNum();
75.94 + }
75.95 +
75.96 + template <typename Graph>
75.97 + inline int _countEdges(Wrap<Graph> w) {
75.98 + return countItems<Graph, typename Graph::EdgeIt>(w.value);
75.99 + }
75.100 +
75.101 + /// \brief Function to count the edges in the graph.
75.102 + ///
75.103 + /// This function counts the edges in the graph.
75.104 + /// The complexity of the function is O(e) but for some
75.105 + /// graph structure it is specialized to run in O(1).
75.106 +
75.107 + template <typename Graph>
75.108 + inline int countEdges(const Graph& g) {
75.109 + return _countEdges<Graph>(g);
75.110 + }
75.111 +
75.112 + // Undirected edge counting:
75.113 +
75.114 + template <typename Graph>
75.115 + inline
75.116 + typename enable_if<typename Graph::EdgeNumTag, int>::type
75.117 + _countUndirEdges(const Graph &g) {
75.118 + return g.undirEdgeNum();
75.119 + }
75.120 +
75.121 + template <typename Graph>
75.122 + inline int _countUndirEdges(Wrap<Graph> w) {
75.123 + return countItems<Graph, typename Graph::UndirEdgeIt>(w.value);
75.124 + }
75.125 +
75.126 + /// \brief Function to count the edges in the graph.
75.127 + ///
75.128 + /// This function counts the edges in the graph.
75.129 + /// The complexity of the function is O(e) but for some
75.130 + /// graph structure it is specialized to run in O(1).
75.131 +
75.132 + template <typename Graph>
75.133 + inline int countUndirEdges(const Graph& g) {
75.134 + return _countUndirEdges<Graph>(g);
75.135 + }
75.136 +
75.137 +
75.138 +
75.139 + template <typename Graph, typename DegIt>
75.140 + inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
75.141 + int num = 0;
75.142 + for (DegIt it(_g, _n); it != INVALID; ++it) {
75.143 + ++num;
75.144 + }
75.145 + return num;
75.146 + }
75.147 +
75.148 + /// Finds an edge between two nodes of a graph.
75.149 +
75.150 + /// Finds an edge from node \c u to node \c v in graph \c g.
75.151 + ///
75.152 + /// If \c prev is \ref INVALID (this is the default value), then
75.153 + /// it finds the first edge from \c u to \c v. Otherwise it looks for
75.154 + /// the next edge from \c u to \c v after \c prev.
75.155 + /// \return The found edge or \ref INVALID if there is no such an edge.
75.156 + ///
75.157 + /// Thus you can iterate through each edge from \c u to \c v as it follows.
75.158 + /// \code
75.159 + /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
75.160 + /// ...
75.161 + /// }
75.162 + /// \endcode
75.163 + /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
75.164 + /// interface here...
75.165 + /// \bug Untested ...
75.166 + template <typename Graph>
75.167 + typename Graph::Edge findEdge(const Graph &g,
75.168 + typename Graph::Node u, typename Graph::Node v,
75.169 + typename Graph::Edge prev = INVALID)
75.170 + {
75.171 + typename Graph::OutEdgeIt e(g,prev);
75.172 + // if(prev==INVALID) g.first(e,u);
75.173 + if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
75.174 + else ++e;
75.175 + while(e!=INVALID && g.target(e)!=v) ++e;
75.176 + return e;
75.177 + }
75.178 +
75.179 + ///\e
75.180 +
75.181 + ///\todo Please document.
75.182 + ///
75.183 + template <typename Graph>
75.184 + inline int countOutEdges(const Graph& _g, const typename Graph::Node& _n) {
75.185 + return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
75.186 + }
75.187 +
75.188 + ///\e
75.189 +
75.190 + ///\todo Please document.
75.191 + ///
75.192 + template <typename Graph>
75.193 + inline int countInEdges(const Graph& _g, const typename Graph::Node& _n) {
75.194 + return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
75.195 + }
75.196 +
75.197 + // graph copy
75.198 +
75.199 + template <
75.200 + typename DestinationGraph,
75.201 + typename SourceGraph,
75.202 + typename NodeBijection>
75.203 + void copyNodes(DestinationGraph& _d, const SourceGraph& _s,
75.204 + NodeBijection& _nb) {
75.205 + for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
75.206 + _nb[it] = _d.addNode();
75.207 + }
75.208 + }
75.209 +
75.210 + template <
75.211 + typename DestinationGraph,
75.212 + typename SourceGraph,
75.213 + typename NodeBijection,
75.214 + typename EdgeBijection>
75.215 + void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
75.216 + const NodeBijection& _nb, EdgeBijection& _eb) {
75.217 + for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
75.218 + _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
75.219 + }
75.220 + }
75.221 +
75.222 + template <
75.223 + typename DestinationGraph,
75.224 + typename SourceGraph,
75.225 + typename NodeBijection,
75.226 + typename EdgeBijection>
75.227 + void copyGraph(DestinationGraph& _d, const SourceGraph& _s,
75.228 + NodeBijection& _nb, EdgeBijection& _eb) {
75.229 + nodeCopy(_d, _s, _nb);
75.230 + edgeCopy(_d, _s, _nb, _eb);
75.231 + }
75.232 +
75.233 + template <
75.234 + typename _DestinationGraph,
75.235 + typename _SourceGraph,
75.236 + typename _NodeBijection
75.237 + =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
75.238 + typename _EdgeBijection
75.239 + = typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
75.240 + >
75.241 + class GraphCopy {
75.242 + public:
75.243 +
75.244 + typedef _DestinationGraph DestinationGraph;
75.245 + typedef _SourceGraph SourceGraph;
75.246 +
75.247 + typedef _NodeBijection NodeBijection;
75.248 + typedef _EdgeBijection EdgeBijection;
75.249 +
75.250 + protected:
75.251 +
75.252 + NodeBijection node_bijection;
75.253 + EdgeBijection edge_bijection;
75.254 +
75.255 + public:
75.256 +
75.257 + GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
75.258 + copyGraph(_d, _s, node_bijection, edge_bijection);
75.259 + }
75.260 +
75.261 + const NodeBijection& getNodeBijection() const {
75.262 + return node_bijection;
75.263 + }
75.264 +
75.265 + const EdgeBijection& getEdgeBijection() const {
75.266 + return edge_bijection;
75.267 + }
75.268 +
75.269 + };
75.270 +
75.271 +
75.272 + template <typename _Graph, typename _Item>
75.273 + class ItemSetTraits {};
75.274 +
75.275 + template <typename _Graph>
75.276 + class ItemSetTraits<_Graph, typename _Graph::Node> {
75.277 + public:
75.278 +
75.279 + typedef _Graph Graph;
75.280 +
75.281 + typedef typename Graph::Node Item;
75.282 + typedef typename Graph::NodeIt ItemIt;
75.283 +
75.284 + template <typename _Value>
75.285 + class Map : public Graph::template NodeMap<_Value> {
75.286 + public:
75.287 + typedef typename Graph::template NodeMap<_Value> Parent;
75.288 + typedef typename Parent::Value Value;
75.289 +
75.290 + Map(const Graph& _graph) : Parent(_graph) {}
75.291 + Map(const Graph& _graph, const Value& _value)
75.292 + : Parent(_graph, _value) {}
75.293 + };
75.294 +
75.295 + };
75.296 +
75.297 + template <typename _Graph>
75.298 + class ItemSetTraits<_Graph, typename _Graph::Edge> {
75.299 + public:
75.300 +
75.301 + typedef _Graph Graph;
75.302 +
75.303 + typedef typename Graph::Edge Item;
75.304 + typedef typename Graph::EdgeIt ItemIt;
75.305 +
75.306 + template <typename _Value>
75.307 + class Map : public Graph::template EdgeMap<_Value> {
75.308 + public:
75.309 + typedef typename Graph::template EdgeMap<_Value> Parent;
75.310 + typedef typename Parent::Value Value;
75.311 +
75.312 + Map(const Graph& _graph) : Parent(_graph) {}
75.313 + Map(const Graph& _graph, const Value& _value)
75.314 + : Parent(_graph, _value) {}
75.315 + };
75.316 +
75.317 + };
75.318 +
75.319 + template <typename _Graph>
75.320 + class ItemSetTraits<_Graph, typename _Graph::UndirEdge> {
75.321 + public:
75.322 +
75.323 + typedef _Graph Graph;
75.324 +
75.325 + typedef typename Graph::UndirEdge Item;
75.326 + typedef typename Graph::UndirEdgeIt ItemIt;
75.327 +
75.328 + template <typename _Value>
75.329 + class Map : public Graph::template UndirEdgeMap<_Value> {
75.330 + public:
75.331 + typedef typename Graph::template UndirEdgeMap<_Value> Parent;
75.332 + typedef typename Parent::Value Value;
75.333 +
75.334 + Map(const Graph& _graph) : Parent(_graph) {}
75.335 + Map(const Graph& _graph, const Value& _value)
75.336 + : Parent(_graph, _value) {}
75.337 + };
75.338 +
75.339 + };
75.340 +
75.341 + /// @}
75.342 +
75.343 + /// \addtogroup graph_maps
75.344 + /// @{
75.345 +
75.346 + template <typename Map, typename Enable = void>
75.347 + struct ReferenceMapTraits {
75.348 + typedef typename Map::Value Value;
75.349 + typedef typename Map::Value& Reference;
75.350 + typedef const typename Map::Value& ConstReference;
75.351 + typedef typename Map::Value* Pointer;
75.352 + typedef const typename Map::Value* ConstPointer;
75.353 + };
75.354 +
75.355 + template <typename Map>
75.356 + struct ReferenceMapTraits<
75.357 + Map,
75.358 + typename enable_if<typename Map::FullTypeTag, void>::type
75.359 + > {
75.360 + typedef typename Map::Value Value;
75.361 + typedef typename Map::Reference Reference;
75.362 + typedef typename Map::ConstReference ConstReference;
75.363 + typedef typename Map::Pointer Pointer;
75.364 + typedef typename Map::ConstPointer ConstPointer;
75.365 + };
75.366 +
75.367 + /// Provides an immutable and unique id for each item in the graph.
75.368 +
75.369 + /// The IdMap class provides an unique and immutable mapping for each item
75.370 + /// in the graph.
75.371 + ///
75.372 + template <typename _Graph, typename _Item>
75.373 + class IdMap {
75.374 + public:
75.375 + typedef _Graph Graph;
75.376 + typedef int Value;
75.377 + typedef _Item Item;
75.378 + typedef _Item Key;
75.379 +
75.380 + typedef True NeedCopy;
75.381 +
75.382 + /// \brief Constructor.
75.383 + ///
75.384 + /// Constructor for creating id map.
75.385 + IdMap(const Graph& _graph) : graph(&_graph) {}
75.386 +
75.387 + /// \brief Gives back the \e id of the item.
75.388 + ///
75.389 + /// Gives back the immutable and unique \e id of the map.
75.390 + int operator[](const Item& item) const { return graph->id(item);}
75.391 +
75.392 +
75.393 + private:
75.394 + const Graph* graph;
75.395 +
75.396 + public:
75.397 +
75.398 + /// \brief The class represents the inverse of the map.
75.399 + ///
75.400 + /// The class represents the inverse of the map.
75.401 + /// \see inverse()
75.402 + class InverseMap {
75.403 + public:
75.404 +
75.405 + typedef True NeedCopy;
75.406 +
75.407 + /// \brief Constructor.
75.408 + ///
75.409 + /// Constructor for creating an id-to-item map.
75.410 + InverseMap(const Graph& _graph) : graph(&_graph) {}
75.411 +
75.412 + /// \brief Constructor.
75.413 + ///
75.414 + /// Constructor for creating an id-to-item map.
75.415 + InverseMap(const IdMap& idMap) : graph(idMap.graph) {}
75.416 +
75.417 + /// \brief Gives back the given item from its id.
75.418 + ///
75.419 + /// Gives back the given item from its id.
75.420 + ///
75.421 + Item operator[](int id) const { return graph->fromId(id, Item());}
75.422 + private:
75.423 + const Graph* graph;
75.424 + };
75.425 +
75.426 + /// \brief Gives back the inverse of the map.
75.427 + ///
75.428 + /// Gives back the inverse of the map.
75.429 + InverseMap inverse() const { return InverseMap(*graph);}
75.430 +
75.431 + };
75.432 +
75.433 +
75.434 + /// \brief General inversable graph-map type.
75.435 +
75.436 + /// This type provides simple inversable map functions.
75.437 + /// The InversableMap wraps an arbitrary ReadWriteMap
75.438 + /// and if a key is setted to a new value then store it
75.439 + /// in the inverse map.
75.440 + /// \param _Graph The graph type.
75.441 + /// \param _Map The map to extend with inversable functionality.
75.442 + template <
75.443 + typename _Graph,
75.444 + typename _Item,
75.445 + typename _Value,
75.446 + typename _Map
75.447 + = typename ItemSetTraits<_Graph, _Item>::template Map<_Value>::Parent
75.448 + >
75.449 + class InvertableMap : protected _Map {
75.450 +
75.451 + public:
75.452 +
75.453 + typedef _Map Map;
75.454 + typedef _Graph Graph;
75.455 +
75.456 + /// The key type of InvertableMap (Node, Edge, UndirEdge).
75.457 + typedef typename _Map::Key Key;
75.458 + /// The value type of the InvertableMap.
75.459 + typedef typename _Map::Value Value;
75.460 +
75.461 + /// \brief Constructor.
75.462 + ///
75.463 + /// Construct a new InvertableMap for the graph.
75.464 + ///
75.465 + InvertableMap(const Graph& graph) : Map(graph) {}
75.466 +
75.467 + /// \brief The setter function of the map.
75.468 + ///
75.469 + /// Sets the mapped value.
75.470 + void set(const Key& key, const Value& val) {
75.471 + Value oldval = Map::operator[](key);
75.472 + typename Container::iterator it = invMap.find(oldval);
75.473 + if (it != invMap.end() && it->second == key) {
75.474 + invMap.erase(it);
75.475 + }
75.476 + invMap.insert(make_pair(val, key));
75.477 + Map::set(key, val);
75.478 + }
75.479 +
75.480 + /// \brief The getter function of the map.
75.481 + ///
75.482 + /// It gives back the value associated with the key.
75.483 + const Value operator[](const Key& key) const {
75.484 + return Map::operator[](key);
75.485 + }
75.486 +
75.487 + /// \brief Add a new key to the map.
75.488 + ///
75.489 + /// Add a new key to the map. It is called by the
75.490 + /// \c AlterationNotifier.
75.491 + virtual void add(const Key& key) {
75.492 + Map::add(key);
75.493 + }
75.494 +
75.495 + /// \brief Erase the key from the map.
75.496 + ///
75.497 + /// Erase the key to the map. It is called by the
75.498 + /// \c AlterationNotifier.
75.499 + virtual void erase(const Key& key) {
75.500 + Value val = Map::operator[](key);
75.501 + typename Container::iterator it = invMap.find(val);
75.502 + if (it != invMap.end() && it->second == key) {
75.503 + invMap.erase(it);
75.504 + }
75.505 + Map::erase(key);
75.506 + }
75.507 +
75.508 + /// \brief Clear the keys from the map and inverse map.
75.509 + ///
75.510 + /// Clear the keys from the map and inverse map. It is called by the
75.511 + /// \c AlterationNotifier.
75.512 + virtual void clear() {
75.513 + invMap.clear();
75.514 + Map::clear();
75.515 + }
75.516 +
75.517 + private:
75.518 +
75.519 + typedef std::map<Value, Key> Container;
75.520 + Container invMap;
75.521 +
75.522 + public:
75.523 +
75.524 + /// \brief The inverse map type.
75.525 + ///
75.526 + /// The inverse of this map. The subscript operator of the map
75.527 + /// gives back always the item what was last assigned to the value.
75.528 + class InverseMap {
75.529 + public:
75.530 + /// \brief Constructor of the InverseMap.
75.531 + ///
75.532 + /// Constructor of the InverseMap.
75.533 + InverseMap(const InvertableMap& _inverted) : inverted(_inverted) {}
75.534 +
75.535 + /// The value type of the InverseMap.
75.536 + typedef typename InvertableMap::Key Value;
75.537 + /// The key type of the InverseMap.
75.538 + typedef typename InvertableMap::Value Key;
75.539 +
75.540 + /// \brief Subscript operator.
75.541 + ///
75.542 + /// Subscript operator. It gives back always the item
75.543 + /// what was last assigned to the value.
75.544 + Value operator[](const Key& key) const {
75.545 + typename Container::const_iterator it = inverted.invMap.find(key);
75.546 + return it->second;
75.547 + }
75.548 +
75.549 + private:
75.550 + const InvertableMap& inverted;
75.551 + };
75.552 +
75.553 + /// \brief It gives back the just readeable inverse map.
75.554 + ///
75.555 + /// It gives back the just readeable inverse map.
75.556 + InverseMap inverse() const {
75.557 + return InverseMap(*this);
75.558 + }
75.559 +
75.560 +
75.561 +
75.562 + };
75.563 +
75.564 + /// \brief Provides a mutable, continuous and unique descriptor for each
75.565 + /// item in the graph.
75.566 + ///
75.567 + /// The DescriptorMap class provides a mutable, continuous and immutable
75.568 + /// mapping for each item in the graph. The value for an item may mutated
75.569 + /// on each operation when the an item erased or added to graph.
75.570 + ///
75.571 + /// \param _Graph The graph class the \c DescriptorMap belongs to.
75.572 + /// \param _Item The Item is the Key of the Map. It may be Node, Edge or
75.573 + /// UndirEdge.
75.574 + /// \param _Map A ReadWriteMap mapping from the item type to integer.
75.575 + template <
75.576 + typename _Graph,
75.577 + typename _Item,
75.578 + typename _Map
75.579 + = typename ItemSetTraits<_Graph, _Item>::template Map<int>::Parent
75.580 + >
75.581 + class DescriptorMap : protected _Map {
75.582 +
75.583 + typedef _Item Item;
75.584 + typedef _Map Map;
75.585 +
75.586 + public:
75.587 + /// The graph class of DescriptorMap.
75.588 + typedef _Graph Graph;
75.589 +
75.590 + /// The key type of DescriptorMap (Node, Edge, UndirEdge).
75.591 + typedef typename _Map::Key Key;
75.592 + /// The value type of DescriptorMap.
75.593 + typedef typename _Map::Value Value;
75.594 +
75.595 + /// \brief Constructor.
75.596 + ///
75.597 + /// Constructor for descriptor map.
75.598 + DescriptorMap(const Graph& _graph) : Map(_graph) {
75.599 + build();
75.600 + }
75.601 +
75.602 + /// \brief Add a new key to the map.
75.603 + ///
75.604 + /// Add a new key to the map. It is called by the
75.605 + /// \c AlterationNotifier.
75.606 + virtual void add(const Item& item) {
75.607 + Map::add(item);
75.608 + Map::set(item, invMap.size());
75.609 + invMap.push_back(item);
75.610 + }
75.611 +
75.612 + /// \brief Erase the key from the map.
75.613 + ///
75.614 + /// Erase the key to the map. It is called by the
75.615 + /// \c AlterationNotifier.
75.616 + virtual void erase(const Item& item) {
75.617 + Map::set(invMap.back(), Map::operator[](item));
75.618 + invMap[Map::operator[](item)] = invMap.back();
75.619 + invMap.pop_back();
75.620 + Map::erase(item);
75.621 + }
75.622 +
75.623 + /// \brief Build the unique map.
75.624 + ///
75.625 + /// Build the unique map. It is called by the
75.626 + /// \c AlterationNotifier.
75.627 + virtual void build() {
75.628 + Map::build();
75.629 + Item it;
75.630 + const typename Map::Graph* graph = Map::getGraph();
75.631 + for (graph->first(it); it != INVALID; graph->next(it)) {
75.632 + Map::set(it, invMap.size());
75.633 + invMap.push_back(it);
75.634 + }
75.635 + }
75.636 +
75.637 + /// \brief Clear the keys from the map.
75.638 + ///
75.639 + /// Clear the keys from the map. It is called by the
75.640 + /// \c AlterationNotifier.
75.641 + virtual void clear() {
75.642 + invMap.clear();
75.643 + Map::clear();
75.644 + }
75.645 +
75.646 + /// \brief Gives back the \e descriptor of the item.
75.647 + ///
75.648 + /// Gives back the mutable and unique \e descriptor of the map.
75.649 + int operator[](const Item& item) const {
75.650 + return Map::operator[](item);
75.651 + }
75.652 +
75.653 + private:
75.654 +
75.655 + typedef std::vector<Item> Container;
75.656 + Container invMap;
75.657 +
75.658 + public:
75.659 + /// \brief The inverse map type.
75.660 + ///
75.661 + /// The inverse map type.
75.662 + class InverseMap {
75.663 + public:
75.664 + /// \brief Constructor of the InverseMap.
75.665 + ///
75.666 + /// Constructor of the InverseMap.
75.667 + InverseMap(const DescriptorMap& _inverted)
75.668 + : inverted(_inverted) {}
75.669 +
75.670 +
75.671 + /// The value type of the InverseMap.
75.672 + typedef typename DescriptorMap::Key Value;
75.673 + /// The key type of the InverseMap.
75.674 + typedef typename DescriptorMap::Value Key;
75.675 +
75.676 + /// \brief Subscript operator.
75.677 + ///
75.678 + /// Subscript operator. It gives back the item
75.679 + /// that the descriptor belongs to currently.
75.680 + Value operator[](const Key& key) const {
75.681 + return inverted.invMap[key];
75.682 + }
75.683 +
75.684 + private:
75.685 + const DescriptorMap& inverted;
75.686 + };
75.687 +
75.688 + /// \brief Gives back the inverse of the map.
75.689 + ///
75.690 + /// Gives back the inverse of the map.
75.691 + const InverseMap inverse() const {
75.692 + return InverseMap(*this);
75.693 + }
75.694 + };
75.695 +
75.696 + /// \brief Returns the source of the given edge.
75.697 + ///
75.698 + /// The SourceMap gives back the source Node of the given edge.
75.699 + /// \author Balazs Dezso
75.700 + template <typename Graph>
75.701 + class SourceMap {
75.702 + public:
75.703 +
75.704 + typedef True NeedCopy;
75.705 +
75.706 + typedef typename Graph::Node Value;
75.707 + typedef typename Graph::Edge Key;
75.708 +
75.709 + /// \brief Constructor
75.710 + ///
75.711 + /// Constructor
75.712 + /// \param _graph The graph that the map belongs to.
75.713 + SourceMap(const Graph& _graph) : graph(_graph) {}
75.714 +
75.715 + /// \brief The subscript operator.
75.716 + ///
75.717 + /// The subscript operator.
75.718 + /// \param edge The edge
75.719 + /// \return The source of the edge
75.720 + Value operator[](const Key& edge) {
75.721 + return graph.source(edge);
75.722 + }
75.723 +
75.724 + private:
75.725 + const Graph& graph;
75.726 + };
75.727 +
75.728 + /// \brief Returns a \ref SourceMap class
75.729 + ///
75.730 + /// This function just returns an \ref SourceMap class.
75.731 + /// \relates SourceMap
75.732 + template <typename Graph>
75.733 + inline SourceMap<Graph> sourceMap(const Graph& graph) {
75.734 + return SourceMap<Graph>(graph);
75.735 + }
75.736 +
75.737 + /// \brief Returns the target of the given edge.
75.738 + ///
75.739 + /// The TargetMap gives back the target Node of the given edge.
75.740 + /// \author Balazs Dezso
75.741 + template <typename Graph>
75.742 + class TargetMap {
75.743 + public:
75.744 +
75.745 + typedef True NeedCopy;
75.746 +
75.747 + typedef typename Graph::Node Value;
75.748 + typedef typename Graph::Edge Key;
75.749 +
75.750 + /// \brief Constructor
75.751 + ///
75.752 + /// Constructor
75.753 + /// \param _graph The graph that the map belongs to.
75.754 + TargetMap(const Graph& _graph) : graph(_graph) {}
75.755 +
75.756 + /// \brief The subscript operator.
75.757 + ///
75.758 + /// The subscript operator.
75.759 + /// \param edge The edge
75.760 + /// \return The target of the edge
75.761 + Value operator[](const Key& key) {
75.762 + return graph.target(key);
75.763 + }
75.764 +
75.765 + private:
75.766 + const Graph& graph;
75.767 + };
75.768 +
75.769 + /// \brief Returns a \ref TargetMap class
75.770 +
75.771 + /// This function just returns an \ref TargetMap class.
75.772 + /// \relates TargetMap
75.773 + template <typename Graph>
75.774 + inline TargetMap<Graph> targetMap(const Graph& graph) {
75.775 + return TargetMap<Graph>(graph);
75.776 + }
75.777 +
75.778 + /// \brief Returns the "forward" directed edge view of undirected edge.
75.779 + ///
75.780 + /// Returns the "forward" directed edge view of undirected edge.
75.781 + /// \author Balazs Dezso
75.782 + template <typename Graph>
75.783 + class ForwardMap {
75.784 + public:
75.785 +
75.786 + typedef True NeedCopy;
75.787 +
75.788 + typedef typename Graph::Edge Value;
75.789 + typedef typename Graph::UndirEdge Key;
75.790 +
75.791 + /// \brief Constructor
75.792 + ///
75.793 + /// Constructor
75.794 + /// \param _graph The graph that the map belongs to.
75.795 + ForwardMap(const Graph& _graph) : graph(_graph) {}
75.796 +
75.797 + /// \brief The subscript operator.
75.798 + ///
75.799 + /// The subscript operator.
75.800 + /// \param key An undirected edge
75.801 + /// \return The "forward" directed edge view of undirected edge
75.802 + Value operator[](const Key& key) const {
75.803 + return graph.edgeWithSource(key, graph.source(key));
75.804 + }
75.805 +
75.806 + private:
75.807 + const Graph& graph;
75.808 + };
75.809 +
75.810 + /// \brief Returns a \ref ForwardMap class
75.811 +
75.812 + /// This function just returns an \ref ForwardMap class.
75.813 + /// \relates ForwardMap
75.814 + template <typename Graph>
75.815 + inline ForwardMap<Graph> forwardMap(const Graph& graph) {
75.816 + return ForwardMap<Graph>(graph);
75.817 + }
75.818 +
75.819 + /// \brief Returns the "backward" directed edge view of undirected edge.
75.820 + ///
75.821 + /// Returns the "backward" directed edge view of undirected edge.
75.822 + /// \author Balazs Dezso
75.823 + template <typename Graph>
75.824 + class BackwardMap {
75.825 + public:
75.826 + typedef True NeedCopy;
75.827 +
75.828 + typedef typename Graph::Edge Value;
75.829 + typedef typename Graph::UndirEdge Key;
75.830 +
75.831 + /// \brief Constructor
75.832 + ///
75.833 + /// Constructor
75.834 + /// \param _graph The graph that the map belongs to.
75.835 + BackwardMap(const Graph& _graph) : graph(_graph) {}
75.836 +
75.837 + /// \brief The subscript operator.
75.838 + ///
75.839 + /// The subscript operator.
75.840 + /// \param key An undirected edge
75.841 + /// \return The "backward" directed edge view of undirected edge
75.842 + Value operator[](const Key& key) const {
75.843 + return graph.edgeWithSource(key, graph.target(key));
75.844 + }
75.845 +
75.846 + private:
75.847 + const Graph& graph;
75.848 + };
75.849 +
75.850 + /// \brief Returns a \ref BackwardMap class
75.851 +
75.852 + /// This function just returns an \ref BackwardMap class.
75.853 + /// \relates BackwardMap
75.854 + template <typename Graph>
75.855 + inline BackwardMap<Graph> backwardMap(const Graph& graph) {
75.856 + return BackwardMap<Graph>(graph);
75.857 + }
75.858 +
75.859 +
75.860 + /// @}
75.861 +
75.862 +} //END OF NAMESPACE LEMON
75.863 +
75.864 +#endif
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
76.2 +++ b/lemon/graph_writer.h Mon May 23 04:48:14 2005 +0000
76.3 @@ -0,0 +1,683 @@
76.4 +/* -*- C++ -*-
76.5 + * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
76.6 + *
76.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
76.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
76.9 + *
76.10 + * Permission to use, modify and distribute this software is granted
76.11 + * provided that this copyright notice appears in all copies. For
76.12 + * precise terms see the accompanying LICENSE file.
76.13 + *
76.14 + * This software is provided "AS IS" with no warranty of any kind,
76.15 + * express or implied, and with no claim as to its suitability for any
76.16 + * purpose.
76.17 + *
76.18 + */
76.19 +
76.20 +///\ingroup io_group
76.21 +///\file
76.22 +///\brief Lemon Graph Format writer.
76.23 +
76.24 +#ifndef LEMON_GRAPH_WRITER_H
76.25 +#define LEMON_GRAPH_WRITER_H
76.26 +
76.27 +#include <iostream>
76.28 +
76.29 +#include <lemon/error.h>
76.30 +#include <lemon/lemon_writer.h>
76.31 +
76.32 +namespace lemon {
76.33 +
76.34 + /// \addtogroup io_group
76.35 + /// @{
76.36 +
76.37 + /// \brief The graph writer class.
76.38 + ///
76.39 + /// The \c GraphWriter class provides the graph output. To write a graph
76.40 + /// you should first give writing commands for the writer. You can declare
76.41 + /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and
76.42 + /// Edge writing.
76.43 + ///
76.44 + /// \code
76.45 + /// GraphWriter<ListGraph> writer(std::cout, graph);
76.46 + /// \endcode
76.47 + ///
76.48 + /// The \c writeNodeMap() function declares a \c NodeMap writing
76.49 + /// command in the \c GraphWriter. You should give as parameter
76.50 + /// the name of the map and the map object. The NodeMap writing
76.51 + /// command with name "id" should write a unique map because it
76.52 + /// is regarded as ID map.
76.53 + ///
76.54 + /// \code
76.55 + /// IdMap<ListGraph, Node> nodeIdMap;
76.56 + /// writer.writeNodeMap("id", nodeIdMap);
76.57 + ///
76.58 + /// writer.writeNodeMap("coords", coords);
76.59 + /// writer.writeNodeMap("color", colorMap);
76.60 + /// \endcode
76.61 + ///
76.62 + /// With the \c writeEdgeMap() member function you can give an edge map
76.63 + /// writing command similar to the NodeMaps.
76.64 + ///
76.65 + /// \code
76.66 + /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
76.67 + /// edgeDescMap(graph);
76.68 + /// writer.writeEdgeMap("descriptor", edgeDescMap);
76.69 + ///
76.70 + /// writer.writeEdgeMap("weight", weightMap);
76.71 + /// writer.writeEdgeMap("label", labelMap);
76.72 + /// \endcode
76.73 + ///
76.74 + /// With \c writeNode() and \c writeEdge() functions you can
76.75 + /// point out Nodes and Edges in the graph. By example, you can
76.76 + /// write out the source and target of the graph.
76.77 + ///
76.78 + /// \code
76.79 + /// writer.writeNode("source", sourceNode);
76.80 + /// writer.writeNode("target", targetNode);
76.81 + ///
76.82 + /// writer.writeEdge("observed", edge);
76.83 + /// \endcode
76.84 + ///
76.85 + /// After you give all write commands you must call the \c run() member
76.86 + /// function, which execute all the writer commands.
76.87 + ///
76.88 + /// \code
76.89 + /// writer.run();
76.90 + /// \endcode
76.91 + ///
76.92 + /// \see DefaultWriterTraits
76.93 + /// \see QuotedStringWriter
76.94 + /// \see IdMap
76.95 + /// \see DescriptorMap
76.96 + /// \see \ref GraphReader
76.97 + /// \see \ref graph-io-page
76.98 + /// \author Balazs Dezso
76.99 + template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
76.100 + class GraphWriter {
76.101 + public:
76.102 +
76.103 + typedef _Graph Graph;
76.104 + typedef typename Graph::Node Node;
76.105 + typedef typename Graph::Edge Edge;
76.106 +
76.107 + typedef _WriterTraits WriterTraits;
76.108 +
76.109 + /// \brief Construct a new GraphWriter.
76.110 + ///
76.111 + /// Construct a new GraphWriter. It writes the given graph
76.112 + /// to the given stream.
76.113 + GraphWriter(std::ostream& _os, const Graph& _graph)
76.114 + : writer(new LemonWriter(_os)), own_writer(true),
76.115 + nodeset_writer(*writer, _graph, std::string()),
76.116 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.117 + node_writer(*writer, nodeset_writer, std::string()),
76.118 + edge_writer(*writer, edgeset_writer, std::string()),
76.119 + attribute_writer(*writer, std::string()) {}
76.120 +
76.121 + /// \brief Construct a new GraphWriter.
76.122 + ///
76.123 + /// Construct a new GraphWriter. It writes into the given graph
76.124 + /// to the given file.
76.125 + GraphWriter(const std::string& _filename, const Graph& _graph)
76.126 + : writer(new LemonWriter(_filename)), own_writer(true),
76.127 + nodeset_writer(*writer, _graph, std::string()),
76.128 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.129 + node_writer(*writer, nodeset_writer, std::string()),
76.130 + edge_writer(*writer, edgeset_writer, std::string()),
76.131 + attribute_writer(*writer, std::string()) {}
76.132 +
76.133 + /// \brief Construct a new GraphWriter.
76.134 + ///
76.135 + /// Construct a new GraphWriter. It writes into the given graph
76.136 + /// to given LemonReader.
76.137 + GraphWriter(LemonWriter& _writer, const Graph& _graph)
76.138 + : writer(_writer), own_writer(false),
76.139 + nodeset_writer(*writer, _graph, std::string()),
76.140 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.141 + node_writer(*writer, nodeset_writer, std::string()),
76.142 + edge_writer(*writer, edgeset_writer, std::string()),
76.143 + attribute_writer(*writer, std::string()) {}
76.144 +
76.145 + /// \brief Destruct the graph writer.
76.146 + ///
76.147 + /// Destruct the graph writer.
76.148 + ~GraphWriter() {
76.149 + if (own_writer)
76.150 + delete writer;
76.151 + }
76.152 +
76.153 + /// \brief Add a new node map writer command for the writer.
76.154 + ///
76.155 + /// Add a new node map writer command for the writer.
76.156 + template <typename Map>
76.157 + GraphWriter& writeNodeMap(std::string name, const Map& map) {
76.158 + nodeset_writer.writeNodeMap(name, map);
76.159 + return *this;
76.160 + }
76.161 +
76.162 + /// \brief Add a new node map writer command for the writer.
76.163 + ///
76.164 + /// Add a new node map writer command for the writer.
76.165 + template <typename Writer, typename Map>
76.166 + GraphWriter& writeNodeMap(std::string name, const Map& map,
76.167 + const Writer& writer = Writer()) {
76.168 + nodeset_writer.writeNodeMap(name, map, writer);
76.169 + return *this;
76.170 + }
76.171 +
76.172 +
76.173 + /// \brief Add a new edge map writer command for the writer.
76.174 + ///
76.175 + /// Add a new edge map writer command for the writer.
76.176 + template <typename Map>
76.177 + GraphWriter& writeEdgeMap(std::string name, const Map& map) {
76.178 + edgeset_writer.writeEdgeMap(name, map);
76.179 + return *this;
76.180 + }
76.181 +
76.182 +
76.183 + /// \brief Add a new edge map writer command for the writer.
76.184 + ///
76.185 + /// Add a new edge map writer command for the writer.
76.186 + template <typename Writer, typename Map>
76.187 + GraphWriter& writeEdgeMap(std::string name, const Map& map,
76.188 + const Writer& writer = Writer()) {
76.189 + edgeset_writer.writeEdgeMap(name, map, writer);
76.190 + return *this;
76.191 + }
76.192 +
76.193 + /// \brief Add a new labeled node writer for the writer.
76.194 + ///
76.195 + /// Add a new labeled node writer for the writer.
76.196 + GraphWriter& writeNode(std::string name, const Node& node) {
76.197 + node_writer.writeNode(name, node);
76.198 + return *this;
76.199 + }
76.200 +
76.201 + /// \brief Add a new labeled edge writer for the writer.
76.202 + ///
76.203 + /// Add a new labeled edge writer for the writer.
76.204 + GraphWriter& writeEdge(std::string name, const Edge& edge) {
76.205 + edge_writer.writeEdge(name, edge);
76.206 + }
76.207 +
76.208 + /// \brief Add a new attribute writer command.
76.209 + ///
76.210 + /// Add a new attribute writer command.
76.211 + template <typename Value>
76.212 + GraphWriter& writeAttribute(std::string name, const Value& value) {
76.213 + attribute_writer.writeAttribute(name, value);
76.214 + return *this;
76.215 + }
76.216 +
76.217 + /// \brief Add a new attribute writer command.
76.218 + ///
76.219 + /// Add a new attribute writer command.
76.220 + template <typename Writer, typename Value>
76.221 + GraphWriter& writeAttribute(std::string name, const Value& value,
76.222 + const Writer& writer) {
76.223 + attribute_writer.writeAttribute<Writer>(name, value, writer);
76.224 + return *this;
76.225 + }
76.226 +
76.227 + /// \brief Conversion operator to LemonWriter.
76.228 + ///
76.229 + /// Conversion operator to LemonWriter. It make possible
76.230 + /// to access the encapsulated \e LemonWriter, this way
76.231 + /// you can attach to this writer new instances of
76.232 + /// \e LemonWriter::SectionWriter.
76.233 + operator LemonWriter&() {
76.234 + return *writer;
76.235 + }
76.236 +
76.237 + /// \brief Executes the writer commands.
76.238 + ///
76.239 + /// Executes the writer commands.
76.240 + void run() {
76.241 + writer->run();
76.242 + }
76.243 +
76.244 + /// \brief Write the id of the given node.
76.245 + ///
76.246 + /// It writes the id of the given node. If there was written an "id"
76.247 + /// named node map then it will write the map value belongs to the node.
76.248 + void writeId(std::ostream& os, const Node& item) const {
76.249 + nodeset_writer.writeId(os, item);
76.250 + }
76.251 +
76.252 + /// \brief Write the id of the given edge.
76.253 + ///
76.254 + /// It writes the id of the given edge. If there was written an "id"
76.255 + /// named edge map then it will write the map value belongs to the edge.
76.256 + void writeId(std::ostream& os, const Edge& item) const {
76.257 + edgeset_writer.writeId(os, item);
76.258 + }
76.259 +
76.260 + private:
76.261 +
76.262 + LemonWriter* writer;
76.263 + bool own_writer;
76.264 +
76.265 + NodeSetWriter<Graph, WriterTraits> nodeset_writer;
76.266 + EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
76.267 +
76.268 + NodeWriter<Graph> node_writer;
76.269 + EdgeWriter<Graph> edge_writer;
76.270 +
76.271 + AttributeWriter<WriterTraits> attribute_writer;
76.272 + };
76.273 +
76.274 +
76.275 + /// \brief Write a graph to the output.
76.276 + ///
76.277 + /// Write a graph to the output.
76.278 + /// \param os The output stream.
76.279 + /// \param g The graph.
76.280 + /// \param capacity The capacity map.
76.281 + /// \param s The source node.
76.282 + /// \param t The target node.
76.283 + /// \param cost The cost map.
76.284 + template<typename Graph, typename CapacityMap, typename CostMap>
76.285 + void writeGraph(std::ostream& os, const Graph &g,
76.286 + const CapacityMap& capacity, const typename Graph::Node &s,
76.287 + const typename Graph::Node &t, const CostMap& cost) {
76.288 + GraphWriter<Graph> writer(os, g);
76.289 + IdMap<Graph, typename Graph::Node> nodeIdMap(g);
76.290 + writer.writeNodeMap("id", nodeIdMap);
76.291 + IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
76.292 + writer.writeEdgeMap("id", edgeIdMap);
76.293 + writer.writeEdgeMap("capacity", capacity);
76.294 + writer.writeEdgeMap("cost", cost);
76.295 + writer.writeNode("source", s);
76.296 + writer.writeNode("target", t);
76.297 + writer.run();
76.298 + }
76.299 +
76.300 + /// \brief Write a graph to the output.
76.301 + ///
76.302 + /// Write a graph to the output.
76.303 + /// \param os The output stream.
76.304 + /// \param g The graph.
76.305 + /// \param capacity The capacity map.
76.306 + /// \param s The source node.
76.307 + /// \param t The target node.
76.308 + template<typename Graph, typename CapacityMap>
76.309 + void writeGraph(std::ostream& os, const Graph &g,
76.310 + const CapacityMap& capacity, const typename Graph::Node &s,
76.311 + const typename Graph::Node &t) {
76.312 + GraphWriter<Graph> writer(os, g);
76.313 + IdMap<Graph, typename Graph::Node> nodeIdMap(g);
76.314 + writer.writeNodeMap("id", nodeIdMap);
76.315 + IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
76.316 + writer.writeEdgeMap("id", edgeIdMap);
76.317 + writer.writeEdgeMap("capacity", capacity);
76.318 + writer.writeNode("source", s);
76.319 + writer.writeNode("target", t);
76.320 + writer.run();
76.321 + }
76.322 +
76.323 + /// \brief Write a graph to the output.
76.324 + ///
76.325 + /// Write a graph to the output.
76.326 + /// \param os The output stream.
76.327 + /// \param g The graph.
76.328 + /// \param capacity The capacity map.
76.329 + /// \param s The source node.
76.330 + template<typename Graph, typename CapacityMap>
76.331 + void writeGraph(std::ostream& os, const Graph &g,
76.332 + const CapacityMap& capacity, const typename Graph::Node &s) {
76.333 + GraphWriter<Graph> writer(os, g);
76.334 + IdMap<Graph, typename Graph::Node> nodeIdMap(g);
76.335 + writer.writeNodeMap("id", nodeIdMap);
76.336 + IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
76.337 + writer.writeEdgeMap("id", edgeIdMap);
76.338 + writer.writeEdgeMap("capacity", capacity);
76.339 + writer.writeNode("source", s);
76.340 + writer.run();
76.341 + }
76.342 +
76.343 + /// \brief Write a graph to the output.
76.344 + ///
76.345 + /// Write a graph to the output.
76.346 + /// \param os The output stream.
76.347 + /// \param g The graph.
76.348 + /// \param capacity The capacity map.
76.349 + template<typename Graph, typename CapacityMap>
76.350 + void writeGraph(std::ostream& os, const Graph &g,
76.351 + const CapacityMap& capacity) {
76.352 + GraphWriter<Graph> writer(os, g);
76.353 + IdMap<Graph, typename Graph::Node> nodeIdMap(g);
76.354 + writer.writeNodeMap("id", nodeIdMap);
76.355 + IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
76.356 + writer.writeEdgeMap("id", edgeIdMap);
76.357 + writer.writeEdgeMap("capacity", capacity);
76.358 + writer.run();
76.359 + }
76.360 +
76.361 + /// \brief Write a graph to the output.
76.362 + ///
76.363 + /// Write a graph to the output.
76.364 + /// \param os The output stream.
76.365 + /// \param g The graph.
76.366 + template<typename Graph>
76.367 + void writeGraph(std::ostream& os, const Graph &g) {
76.368 + GraphWriter<Graph> writer(os, g);
76.369 + IdMap<Graph, typename Graph::Node> nodeIdMap(g);
76.370 + writer.writeNodeMap("id", nodeIdMap);
76.371 + IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
76.372 + writer.writeEdgeMap("id", edgeIdMap);
76.373 + writer.run();
76.374 + }
76.375 +
76.376 + /// \brief The undirected graph writer class.
76.377 + ///
76.378 + /// The \c UndirGraphWriter class provides the undir graph output. To write
76.379 + /// a graph you should first give writing commands for the writer. You can
76.380 + /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
76.381 + /// writing and labeled Node, Edge or UndirEdge writing.
76.382 + ///
76.383 + /// \code
76.384 + /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
76.385 + /// \endcode
76.386 + ///
76.387 + /// The \c writeNodeMap() function declares a \c NodeMap writing
76.388 + /// command in the \c UndirGraphWriter. You should give as parameter
76.389 + /// the name of the map and the map object. The NodeMap writing
76.390 + /// command with name "id" should write a unique map because it
76.391 + /// is regarded as ID map.
76.392 + ///
76.393 + /// \code
76.394 + /// IdMap<UndirListGraph, Node> nodeIdMap;
76.395 + /// writer.writeNodeMap("id", nodeIdMap);
76.396 + ///
76.397 + /// writer.writeNodeMap("coords", coords);
76.398 + /// writer.writeNodeMap("color", colorMap);
76.399 + /// \endcode
76.400 + ///
76.401 + /// With the \c writeUndirEdgeMap() member function you can give an
76.402 + /// undirected edge map writing command similar to the NodeMaps.
76.403 + ///
76.404 + /// \code
76.405 + /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
76.406 + /// edgeDescMap(graph);
76.407 + /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
76.408 + ///
76.409 + /// writer.writeUndirEdgeMap("weight", weightMap);
76.410 + /// writer.writeUndirEdgeMap("label", labelMap);
76.411 + /// \endcode
76.412 + ///
76.413 + /// The EdgeMap handling is just a syntactical sugar. It writes
76.414 + /// two undirected edge map with '+' and '-' prefix in the name.
76.415 + ///
76.416 + /// \code
76.417 + /// writer.writeEdgeMap("capacity", capacityMap);
76.418 + /// \endcode
76.419 + ///
76.420 + ///
76.421 + /// With \c writeNode() and \c writeUndirEdge() functions you can
76.422 + /// point out nodes and undirected edges in the graph. By example, you can
76.423 + /// write out the source and target of the graph.
76.424 + ///
76.425 + /// \code
76.426 + /// writer.writeNode("source", sourceNode);
76.427 + /// writer.writeNode("target", targetNode);
76.428 + ///
76.429 + /// writer.writeUndirEdge("observed", undirEdge);
76.430 + /// \endcode
76.431 + ///
76.432 + /// After you give all write commands you must call the \c run() member
76.433 + /// function, which execute all the writer commands.
76.434 + ///
76.435 + /// \code
76.436 + /// writer.run();
76.437 + /// \endcode
76.438 + ///
76.439 + /// \see DefaultWriterTraits
76.440 + /// \see QuotedStringWriter
76.441 + /// \see IdMap
76.442 + /// \see DescriptorMap
76.443 + /// \see \ref GraphWriter
76.444 + /// \see \ref graph-io-page
76.445 + /// \author Balazs Dezso
76.446 + template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
76.447 + class UndirGraphWriter {
76.448 + public:
76.449 +
76.450 + typedef _Graph Graph;
76.451 + typedef typename Graph::Node Node;
76.452 + typedef typename Graph::Edge Edge;
76.453 + typedef typename Graph::UndirEdge UndirEdge;
76.454 +
76.455 + typedef _WriterTraits WriterTraits;
76.456 +
76.457 + /// \brief Construct a new UndirGraphWriter.
76.458 + ///
76.459 + /// Construct a new UndirGraphWriter. It writes the given graph
76.460 + /// to the given stream.
76.461 + UndirGraphWriter(std::ostream& _os, const Graph& _graph)
76.462 + : writer(new LemonWriter(_os)), own_writer(true),
76.463 + nodeset_writer(*writer, _graph, std::string()),
76.464 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.465 + node_writer(*writer, nodeset_writer, std::string()),
76.466 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
76.467 + attribute_writer(*writer, std::string()) {}
76.468 +
76.469 + /// \brief Construct a new UndirGraphWriter.
76.470 + ///
76.471 + /// Construct a new UndirGraphWriter. It writes into the given graph
76.472 + /// to the given file.
76.473 + UndirGraphWriter(const std::string& _filename, const Graph& _graph)
76.474 + : writer(new LemonWriter(_filename)), own_writer(true),
76.475 + nodeset_writer(*writer, _graph, std::string()),
76.476 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.477 + node_writer(*writer, nodeset_writer, std::string()),
76.478 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
76.479 + attribute_writer(*writer, std::string()) {}
76.480 +
76.481 + /// \brief Construct a new UndirGraphWriter.
76.482 + ///
76.483 + /// Construct a new UndirGraphWriter. It writes into the given graph
76.484 + /// to given LemonReader.
76.485 + UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
76.486 + : writer(_writer), own_writer(false),
76.487 + nodeset_writer(*writer, _graph, std::string()),
76.488 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
76.489 + node_writer(*writer, nodeset_writer, std::string()),
76.490 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
76.491 + attribute_writer(*writer, std::string()) {}
76.492 +
76.493 + /// \brief Destruct the graph writer.
76.494 + ///
76.495 + /// Destruct the graph writer.
76.496 + ~UndirGraphWriter() {
76.497 + if (own_writer)
76.498 + delete writer;
76.499 + }
76.500 +
76.501 + /// \brief Add a new node map writer command for the writer.
76.502 + ///
76.503 + /// Add a new node map writer command for the writer.
76.504 + template <typename Map>
76.505 + UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
76.506 + nodeset_writer.writeNodeMap(name, map);
76.507 + return *this;
76.508 + }
76.509 +
76.510 + /// \brief Add a new node map writer command for the writer.
76.511 + ///
76.512 + /// Add a new node map writer command for the writer.
76.513 + template <typename Writer, typename Map>
76.514 + UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
76.515 + const Writer& writer = Writer()) {
76.516 + nodeset_writer.writeNodeMap(name, map, writer);
76.517 + return *this;
76.518 + }
76.519 +
76.520 + /// \brief Add a new edge map writer command for the writer.
76.521 + ///
76.522 + /// Add a new edge map writer command for the writer.
76.523 + template <typename Map>
76.524 + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
76.525 + undir_edgeset_writer.writeEdgeMap(name, map);
76.526 + return *this;
76.527 + }
76.528 +
76.529 + /// \brief Add a new edge map writer command for the writer.
76.530 + ///
76.531 + /// Add a new edge map writer command for the writer.
76.532 + template <typename Writer, typename Map>
76.533 + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
76.534 + const Writer& writer = Writer()) {
76.535 + undir_edgeset_writer.writeEdgeMap(name, map, writer);
76.536 + return *this;
76.537 + }
76.538 +
76.539 + /// \brief Add a new undirected edge map writer command for the writer.
76.540 + ///
76.541 + /// Add a new undirected edge map writer command for the writer.
76.542 + template <typename Map>
76.543 + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
76.544 + undir_edgeset_writer.writeUndirEdgeMap(name, map);
76.545 + return *this;
76.546 + }
76.547 +
76.548 + /// \brief Add a new undirected edge map writer command for the writer.
76.549 + ///
76.550 + /// Add a new edge undirected map writer command for the writer.
76.551 + template <typename Writer, typename Map>
76.552 + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
76.553 + const Writer& writer = Writer()) {
76.554 + undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
76.555 + return *this;
76.556 + }
76.557 +
76.558 + /// \brief Add a new labeled node writer for the writer.
76.559 + ///
76.560 + /// Add a new labeled node writer for the writer.
76.561 + UndirGraphWriter& writeNode(std::string name, const Node& node) {
76.562 + node_writer.writeNode(name, node);
76.563 + return *this;
76.564 + }
76.565 +
76.566 + /// \brief Add a new labeled edge writer for the writer.
76.567 + ///
76.568 + /// Add a new labeled edge writer for the writer.
76.569 + UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
76.570 + undir_edge_writer.writeEdge(name, edge);
76.571 + }
76.572 +
76.573 + /// \brief Add a new labeled undirected edge writer for the writer.
76.574 + ///
76.575 + /// Add a new labeled undirected edge writer for the writer.
76.576 + UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
76.577 + undir_edge_writer.writeUndirEdge(name, edge);
76.578 + }
76.579 +
76.580 + /// \brief Add a new attribute writer command.
76.581 + ///
76.582 + /// Add a new attribute writer command.
76.583 + template <typename Value>
76.584 + UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
76.585 + attribute_writer.writeAttribute(name, value);
76.586 + return *this;
76.587 + }
76.588 +
76.589 + /// \brief Add a new attribute writer command.
76.590 + ///
76.591 + /// Add a new attribute writer command.
76.592 + template <typename Writer, typename Value>
76.593 + UndirGraphWriter& writeAttribute(std::string name, const Value& value,
76.594 + const Writer& writer) {
76.595 + attribute_writer.writeAttribute<Writer>(name, value, writer);
76.596 + return *this;
76.597 + }
76.598 +
76.599 + /// \brief Conversion operator to LemonWriter.
76.600 + ///
76.601 + /// Conversion operator to LemonWriter. It make possible
76.602 + /// to access the encapsulated \e LemonWriter, this way
76.603 + /// you can attach to this writer new instances of
76.604 + /// \e LemonWriter::SectionWriter.
76.605 + operator LemonWriter&() {
76.606 + return *writer;
76.607 + }
76.608 +
76.609 + /// \brief Executes the writer commands.
76.610 + ///
76.611 + /// Executes the writer commands.
76.612 + void run() {
76.613 + writer->run();
76.614 + }
76.615 +
76.616 + /// \brief Write the id of the given node.
76.617 + ///
76.618 + /// It writes the id of the given node. If there was written an "id"
76.619 + /// named node map then it will write the map value belongs to the node.
76.620 + void writeId(std::ostream& os, const Node& item) const {
76.621 + nodeset_writer.writeId(os, item);
76.622 + }
76.623 +
76.624 + /// \brief Write the id of the given edge.
76.625 + ///
76.626 + /// It writes the id of the given edge. If there was written an "id"
76.627 + /// named edge map then it will write the map value belongs to the edge.
76.628 + void writeId(std::ostream& os, const Edge& item) const {
76.629 + undir_edgeset_writer.writeId(os, item);
76.630 + }
76.631 +
76.632 + /// \brief Write the id of the given undirected edge.
76.633 + ///
76.634 + /// It writes the id of the given undirected edge. If there was written
76.635 + /// an "id" named edge map then it will write the map value belongs to
76.636 + /// the edge.
76.637 + void writeId(std::ostream& os, const UndirEdge& item) const {
76.638 + undir_edgeset_writer.writeId(os, item);
76.639 + }
76.640 +
76.641 +
76.642 + private:
76.643 +
76.644 + LemonWriter* writer;
76.645 + bool own_writer;
76.646 +
76.647 + NodeSetWriter<Graph, WriterTraits> nodeset_writer;
76.648 + UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
76.649 +
76.650 + NodeWriter<Graph> node_writer;
76.651 + UndirEdgeWriter<Graph> undir_edge_writer;
76.652 +
76.653 + AttributeWriter<WriterTraits> attribute_writer;
76.654 + };
76.655 +
76.656 +
76.657 + /// \brief Write an undirected graph to the output.
76.658 + ///
76.659 + /// Write an undirected graph to the output.
76.660 + /// \param os The output stream.
76.661 + /// \param g The graph.
76.662 + /// \param capacity The capacity undirected map.
76.663 + template<typename Graph, typename CapacityMap>
76.664 + void writeUndirGraph(std::ostream& os, const Graph &g,
76.665 + const CapacityMap& capacity) {
76.666 + UndirGraphWriter<Graph> writer(os, g);
76.667 + writer.writeUndirEdgeMap("capacity", capacity);
76.668 + writer.run();
76.669 + }
76.670 +
76.671 + /// \brief Write an undirected graph to the output.
76.672 + ///
76.673 + /// Write an undirected graph to the output.
76.674 + /// \param os The output stream.
76.675 + /// \param g The graph.
76.676 + template<typename Graph>
76.677 + void writeUndirGraph(std::ostream& os, const Graph &g) {
76.678 + UndirGraphWriter<Graph> writer(os, g);
76.679 + writer.run();
76.680 + }
76.681 +
76.682 + /// @}
76.683 +
76.684 +}
76.685 +
76.686 +#endif
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/lemon/invalid.h Mon May 23 04:48:14 2005 +0000
77.3 @@ -0,0 +1,52 @@
77.4 +/* -*- C++ -*-
77.5 + * lemon/invalid.h - Part of LEMON, a generic C++ optimization library
77.6 + *
77.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
77.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
77.9 + *
77.10 + * Permission to use, modify and distribute this software is granted
77.11 + * provided that this copyright notice appears in all copies. For
77.12 + * precise terms see the accompanying LICENSE file.
77.13 + *
77.14 + * This software is provided "AS IS" with no warranty of any kind,
77.15 + * express or implied, and with no claim as to its suitability for any
77.16 + * purpose.
77.17 + *
77.18 + */
77.19 +
77.20 +#ifndef LEMON_INVALID_H
77.21 +#define LEMON_INVALID_H
77.22 +
77.23 +///\file
77.24 +///\brief Definition of INVALID.
77.25 +
77.26 +namespace lemon {
77.27 +
77.28 + /// Dummy type to make it easier to make invalid iterators.
77.29 +
77.30 + /// See \ref INVALID, how to use it.
77.31 +
77.32 + struct Invalid {
77.33 + public:
77.34 + bool operator==(Invalid) { return true; }
77.35 + bool operator!=(Invalid) { return false; }
77.36 + bool operator< (Invalid) { return false; }
77.37 + };
77.38 +
77.39 + /// Invalid iterators.
77.40 +
77.41 + /// \ref Invalid is a global type that converts to each iterator
77.42 + /// in such a way that the value of the target iterator will be invalid.
77.43 +
77.44 + // It is also used to convert the \c INVALID constant to the
77.45 + // node iterator that makes is possible to write
77.46 +
77.47 + //extern Invalid INVALID;
77.48 +
77.49 + //const Invalid &INVALID = *(Invalid *)0;
77.50 + const Invalid INVALID = Invalid();
77.51 +
77.52 +} //namespace lemon
77.53 +
77.54 +#endif
77.55 +
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/lemon/kruskal.h Mon May 23 04:48:14 2005 +0000
78.3 @@ -0,0 +1,348 @@
78.4 +/* -*- C++ -*-
78.5 + * lemon/kruskal.h - Part of LEMON, a generic C++ optimization library
78.6 + *
78.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
78.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
78.9 + *
78.10 + * Permission to use, modify and distribute this software is granted
78.11 + * provided that this copyright notice appears in all copies. For
78.12 + * precise terms see the accompanying LICENSE file.
78.13 + *
78.14 + * This software is provided "AS IS" with no warranty of any kind,
78.15 + * express or implied, and with no claim as to its suitability for any
78.16 + * purpose.
78.17 + *
78.18 + */
78.19 +
78.20 +#ifndef LEMON_KRUSKAL_H
78.21 +#define LEMON_KRUSKAL_H
78.22 +
78.23 +#include <algorithm>
78.24 +#include <lemon/unionfind.h>
78.25 +
78.26 +/**
78.27 +@defgroup spantree Minimum Cost Spanning Tree Algorithms
78.28 +@ingroup galgs
78.29 +\brief This group containes the algorithms for finding a minimum cost spanning
78.30 +tree in a graph
78.31 +
78.32 +This group containes the algorithms for finding a minimum cost spanning
78.33 +tree in a graph
78.34 +*/
78.35 +
78.36 +///\ingroup spantree
78.37 +///\file
78.38 +///\brief Kruskal's algorithm to compute a minimum cost tree
78.39 +///
78.40 +///Kruskal's algorithm to compute a minimum cost tree.
78.41 +
78.42 +namespace lemon {
78.43 +
78.44 + /// \addtogroup spantree
78.45 + /// @{
78.46 +
78.47 + /// Kruskal's algorithm to find a minimum cost tree of a graph.
78.48 +
78.49 + /// This function runs Kruskal's algorithm to find a minimum cost tree.
78.50 + /// \param G The graph the algorithm runs on. The algorithm considers the
78.51 + /// graph to be undirected, the direction of the edges are not used.
78.52 + ///
78.53 + /// \param in This object is used to describe the edge costs. It must
78.54 + /// be an STL compatible 'Forward Container'
78.55 + /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>,
78.56 + /// where X is the type of the costs. It must contain every edge in
78.57 + /// cost-ascending order.
78.58 + ///\par
78.59 + /// For the sake of simplicity, there is a helper class KruskalMapInput,
78.60 + /// which converts a
78.61 + /// simple edge map to an input of this form. Alternatively, you can use
78.62 + /// the function \ref kruskalEdgeMap to compute the minimum cost tree if
78.63 + /// the edge costs are given by an edge map.
78.64 + ///
78.65 + /// \retval out This must be a writable \c bool edge map.
78.66 + /// After running the algorithm
78.67 + /// this will contain the found minimum cost spanning tree: the value of an
78.68 + /// edge will be set to \c true if it belongs to the tree, otherwise it will
78.69 + /// be set to \c false. The value of each edge will be set exactly once.
78.70 + ///
78.71 + /// \return The cost of the found tree.
78.72 +
78.73 + template <class GR, class IN, class OUT>
78.74 + typename IN::value_type::second_type
78.75 + kruskal(GR const& G, IN const& in,
78.76 + OUT& out)
78.77 + {
78.78 + typedef typename IN::value_type::second_type EdgeCost;
78.79 + typedef typename GR::template NodeMap<int> NodeIntMap;
78.80 + typedef typename GR::Node Node;
78.81 +
78.82 + NodeIntMap comp(G, -1);
78.83 + UnionFind<Node,NodeIntMap> uf(comp);
78.84 +
78.85 + EdgeCost tot_cost = 0;
78.86 + for (typename IN::const_iterator p = in.begin();
78.87 + p!=in.end(); ++p ) {
78.88 + if ( uf.join(G.target((*p).first),
78.89 + G.source((*p).first)) ) {
78.90 + out.set((*p).first, true);
78.91 + tot_cost += (*p).second;
78.92 + }
78.93 + else {
78.94 + out.set((*p).first, false);
78.95 + }
78.96 + }
78.97 + return tot_cost;
78.98 + }
78.99 +
78.100 + /* A work-around for running Kruskal with const-reference bool maps... */
78.101 +
78.102 + /// Helper class for calling kruskal with "constant" output map.
78.103 +
78.104 + /// Helper class for calling kruskal with output maps constructed
78.105 + /// on-the-fly.
78.106 + ///
78.107 + /// A typical examle is the following call:
78.108 + /// <tt>kruskal(G, some_input, makeSequenceOutput(iterator))</tt>.
78.109 + /// Here, the third argument is a temporary object (which wraps around an
78.110 + /// iterator with a writable bool map interface), and thus by rules of C++
78.111 + /// is a \c const object. To enable call like this exist this class and
78.112 + /// the prototype of the \ref kruskal() function with <tt>const& OUT</tt>
78.113 + /// third argument.
78.114 + template<class Map>
78.115 + class NonConstMapWr {
78.116 + const Map &m;
78.117 + public:
78.118 + typedef typename Map::Value Value;
78.119 +
78.120 + NonConstMapWr(const Map &_m) : m(_m) {}
78.121 +
78.122 + template<class Key>
78.123 + void set(Key const& k, Value const &v) const { m.set(k,v); }
78.124 + };
78.125 +
78.126 + template <class GR, class IN, class OUT>
78.127 + inline
78.128 + typename IN::value_type::second_type
78.129 + kruskal(GR const& G, IN const& edges, OUT const& out_map)
78.130 + {
78.131 + NonConstMapWr<OUT> map_wr(out_map);
78.132 + return kruskal(G, edges, map_wr);
78.133 + }
78.134 +
78.135 + /* ** ** Input-objects ** ** */
78.136 +
78.137 + /// Kruskal's input source.
78.138 +
78.139 + /// Kruskal's input source.
78.140 + ///
78.141 + /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead.
78.142 + ///
78.143 + /// \sa makeKruskalMapInput()
78.144 + ///
78.145 + ///\param GR The type of the graph the algorithm runs on.
78.146 + ///\param Map An edge map containing the cost of the edges.
78.147 + ///\par
78.148 + ///The cost type can be any type satisfying
78.149 + ///the STL 'LessThan comparable'
78.150 + ///concept if it also has an operator+() implemented. (It is necessary for
78.151 + ///computing the total cost of the tree).
78.152 + ///
78.153 + template<class GR, class Map>
78.154 + class KruskalMapInput
78.155 + : public std::vector< std::pair<typename GR::Edge,
78.156 + typename Map::Value> > {
78.157 +
78.158 + public:
78.159 + typedef std::vector< std::pair<typename GR::Edge,
78.160 + typename Map::Value> > Parent;
78.161 + typedef typename Parent::value_type value_type;
78.162 +
78.163 + private:
78.164 + class comparePair {
78.165 + public:
78.166 + bool operator()(const value_type& a,
78.167 + const value_type& b) {
78.168 + return a.second < b.second;
78.169 + }
78.170 + };
78.171 +
78.172 + public:
78.173 +
78.174 + void sort() {
78.175 + std::sort(this->begin(), this->end(), comparePair());
78.176 + }
78.177 +
78.178 + KruskalMapInput(GR const& G, Map const& m) {
78.179 + typedef typename GR::EdgeIt EdgeIt;
78.180 +
78.181 + for(EdgeIt e(G);e!=INVALID;++e) push_back(value_type(e, m[e]));
78.182 + sort();
78.183 + }
78.184 + };
78.185 +
78.186 + /// Creates a KruskalMapInput object for \ref kruskal()
78.187 +
78.188 + /// It makes easier to use
78.189 + /// \ref KruskalMapInput by making it unnecessary
78.190 + /// to explicitly give the type of the parameters.
78.191 + ///
78.192 + /// In most cases you possibly
78.193 + /// want to use the function kruskalEdgeMap() instead.
78.194 + ///
78.195 + ///\param G The type of the graph the algorithm runs on.
78.196 + ///\param m An edge map containing the cost of the edges.
78.197 + ///\par
78.198 + ///The cost type can be any type satisfying the
78.199 + ///STL 'LessThan Comparable'
78.200 + ///concept if it also has an operator+() implemented. (It is necessary for
78.201 + ///computing the total cost of the tree).
78.202 + ///
78.203 + ///\return An appropriate input source for \ref kruskal().
78.204 + ///
78.205 + template<class GR, class Map>
78.206 + inline
78.207 + KruskalMapInput<GR,Map> makeKruskalMapInput(const GR &G,const Map &m)
78.208 + {
78.209 + return KruskalMapInput<GR,Map>(G,m);
78.210 + }
78.211 +
78.212 +
78.213 +
78.214 + /* ** ** Output-objects: simple writable bool maps ** ** */
78.215 +
78.216 +
78.217 +
78.218 + /// A writable bool-map that makes a sequence of "true" keys
78.219 +
78.220 + /// A writable bool-map that creates a sequence out of keys that receives
78.221 + /// the value "true".
78.222 + ///
78.223 + /// \sa makeKruskalSequenceOutput()
78.224 + ///
78.225 + /// Very often, when looking for a min cost spanning tree, we want as
78.226 + /// output a container containing the edges of the found tree. For this
78.227 + /// purpose exist this class that wraps around an STL iterator with a
78.228 + /// writable bool map interface. When a key gets value "true" this key
78.229 + /// is added to sequence pointed by the iterator.
78.230 + ///
78.231 + /// A typical usage:
78.232 + /// \code
78.233 + /// std::vector<Graph::Edge> v;
78.234 + /// kruskal(g, input, makeKruskalSequenceOutput(back_inserter(v)));
78.235 + /// \endcode
78.236 + ///
78.237 + /// For the most common case, when the input is given by a simple edge
78.238 + /// map and the output is a sequence of the tree edges, a special
78.239 + /// wrapper function exists: \ref kruskalEdgeMap_IteratorOut().
78.240 + ///
78.241 + /// \warning Not a regular property map, as it doesn't know its Key
78.242 +
78.243 + template<class Iterator>
78.244 + class KruskalSequenceOutput {
78.245 + mutable Iterator it;
78.246 +
78.247 + public:
78.248 + typedef bool Value;
78.249 +
78.250 + KruskalSequenceOutput(Iterator const &_it) : it(_it) {}
78.251 +
78.252 + template<typename Key>
78.253 + void set(Key const& k, bool v) const { if(v) {*it=k; ++it;} }
78.254 + };
78.255 +
78.256 + template<class Iterator>
78.257 + inline
78.258 + KruskalSequenceOutput<Iterator>
78.259 + makeKruskalSequenceOutput(Iterator it) {
78.260 + return KruskalSequenceOutput<Iterator>(it);
78.261 + }
78.262 +
78.263 +
78.264 +
78.265 + /* ** ** Wrapper funtions ** ** */
78.266 +
78.267 +
78.268 +
78.269 + /// \brief Wrapper function to kruskal().
78.270 + /// Input is from an edge map, output is a plain bool map.
78.271 + ///
78.272 + /// Wrapper function to kruskal().
78.273 + /// Input is from an edge map, output is a plain bool map.
78.274 + ///
78.275 + ///\param G The type of the graph the algorithm runs on.
78.276 + ///\param in An edge map containing the cost of the edges.
78.277 + ///\par
78.278 + ///The cost type can be any type satisfying the
78.279 + ///STL 'LessThan Comparable'
78.280 + ///concept if it also has an operator+() implemented. (It is necessary for
78.281 + ///computing the total cost of the tree).
78.282 + ///
78.283 + /// \retval out This must be a writable \c bool edge map.
78.284 + /// After running the algorithm
78.285 + /// this will contain the found minimum cost spanning tree: the value of an
78.286 + /// edge will be set to \c true if it belongs to the tree, otherwise it will
78.287 + /// be set to \c false. The value of each edge will be set exactly once.
78.288 + ///
78.289 + /// \return The cost of the found tree.
78.290 +
78.291 + template <class GR, class IN, class RET>
78.292 + inline
78.293 + typename IN::Value
78.294 + kruskalEdgeMap(GR const& G,
78.295 + IN const& in,
78.296 + RET &out) {
78.297 + return kruskal(G,
78.298 + KruskalMapInput<GR,IN>(G,in),
78.299 + out);
78.300 + }
78.301 +
78.302 + /// \brief Wrapper function to kruskal().
78.303 + /// Input is from an edge map, output is an STL Sequence.
78.304 + ///
78.305 + /// Wrapper function to kruskal().
78.306 + /// Input is from an edge map, output is an STL Sequence.
78.307 + ///
78.308 + ///\param G The type of the graph the algorithm runs on.
78.309 + ///\param in An edge map containing the cost of the edges.
78.310 + ///\par
78.311 + ///The cost type can be any type satisfying the
78.312 + ///STL 'LessThan Comparable'
78.313 + ///concept if it also has an operator+() implemented. (It is necessary for
78.314 + ///computing the total cost of the tree).
78.315 + ///
78.316 + /// \retval out This must be an iteraror of an STL Container with
78.317 + /// <tt>GR::Edge</tt> as its <tt>value_type</tt>.
78.318 + /// The algorithm copies the elements of the found tree into this sequence.
78.319 + /// For example, if we know that the spanning tree of the graph \c G has
78.320 + /// say 53 edges then
78.321 + /// we can put its edges into a STL vector \c tree with a code like this.
78.322 + /// \code
78.323 + /// std::vector<Edge> tree(53);
78.324 + /// kruskalEdgeMap_IteratorOut(G,cost,tree.begin());
78.325 + /// \endcode
78.326 + /// Or if we don't know in advance the size of the tree, we can write this.
78.327 + /// \code
78.328 + /// std::vector<Edge> tree;
78.329 + /// kruskalEdgeMap_IteratorOut(G,cost,std::back_inserter(tree));
78.330 + /// \endcode
78.331 + ///
78.332 + /// \return The cost of the found tree.
78.333 + ///
78.334 + /// \bug its name does not follow the coding style.
78.335 +
78.336 + template <class GR, class IN, class RET>
78.337 + inline
78.338 + typename IN::Value
78.339 + kruskalEdgeMap_IteratorOut(const GR& G,
78.340 + const IN& in,
78.341 + RET out)
78.342 + {
78.343 + KruskalSequenceOutput<RET> _out(out);
78.344 + return kruskal(G, KruskalMapInput<GR,IN>(G, in), _out);
78.345 + }
78.346 +
78.347 + /// @}
78.348 +
78.349 +} //namespace lemon
78.350 +
78.351 +#endif //LEMON_KRUSKAL_H
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/lemon/lemon.pc.in Mon May 23 04:48:14 2005 +0000
79.3 @@ -0,0 +1,10 @@
79.4 +prefix=@prefix@
79.5 +exec_prefix=@exec_prefix@
79.6 +libdir=@libdir@
79.7 +includedir=@includedir@
79.8 +
79.9 +Name: @PACKAGE_NAME@
79.10 +Description: a Library of Efficient Models and Optimization in Networks
79.11 +Version: @PACKAGE_VERSION@
79.12 +Libs: -L${libdir} -lemon
79.13 +Cflags: -I${includedir}
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
80.2 +++ b/lemon/lemon_reader.h Mon May 23 04:48:14 2005 +0000
80.3 @@ -0,0 +1,1977 @@
80.4 +/* -*- C++ -*-
80.5 + * lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
80.6 + *
80.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
80.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
80.9 + *
80.10 + * Permission to use, modify and distribute this software is granted
80.11 + * provided that this copyright notice appears in all copies. For
80.12 + * precise terms see the accompanying LICENSE file.
80.13 + *
80.14 + * This software is provided "AS IS" with no warranty of any kind,
80.15 + * express or implied, and with no claim as to its suitability for any
80.16 + * purpose.
80.17 + *
80.18 + */
80.19 +
80.20 +///\ingroup io_group
80.21 +///\file
80.22 +///\brief Lemon Format reader.
80.23 +
80.24 +
80.25 +#ifndef LEMON_LEMON_READER_H
80.26 +#define LEMON_LEMON_READER_H
80.27 +
80.28 +
80.29 +#include <iostream>
80.30 +#include <fstream>
80.31 +#include <string>
80.32 +#include <vector>
80.33 +#include <algorithm>
80.34 +#include <map>
80.35 +#include <memory>
80.36 +
80.37 +#include <lemon/error.h>
80.38 +#include <lemon/graph_utils.h>
80.39 +#include <lemon/utility.h>
80.40 +#include <lemon/bits/item_reader.h>
80.41 +
80.42 +
80.43 +namespace lemon {
80.44 +
80.45 + namespace _reader_bits {
80.46 +
80.47 + template <typename T>
80.48 + bool operator<(T, T) {
80.49 + throw DataFormatError("Id is not comparable");
80.50 + }
80.51 +
80.52 + template <typename T>
80.53 + struct Less {
80.54 + bool operator()(const T& p, const T& q) const {
80.55 + return p < q;
80.56 + }
80.57 + };
80.58 +
80.59 + template <typename M1, typename M2>
80.60 + class WriteComposeMap {
80.61 + public:
80.62 + typedef True NeedCopy;
80.63 +
80.64 + typedef typename M2::Key Key;
80.65 + typedef typename M1::Value Value;
80.66 +
80.67 + WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2)
80.68 + : m1(_m1), m2(_m2) {}
80.69 +
80.70 + void set(const Key& key, const Value& value) {
80.71 + m1.set(m2[key], value);
80.72 + }
80.73 +
80.74 + private:
80.75 +
80.76 + typename SmartReference<M1>::Type m1;
80.77 + typename SmartConstReference<M2>::Type m2;
80.78 +
80.79 + };
80.80 +
80.81 + template <typename M1, typename M2>
80.82 + WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
80.83 + return WriteComposeMap<M1, M2>(m1, m2);
80.84 + }
80.85 +
80.86 + template <typename M1, typename M2>
80.87 + WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
80.88 + return WriteComposeMap<M1, M2>(m1, m2);
80.89 + }
80.90 +
80.91 + }
80.92 +
80.93 + /// \ingroup io_group
80.94 + /// \brief Lemon Format reader class.
80.95 + ///
80.96 + /// The Lemon Format contains several sections. We do not want to
80.97 + /// determine what sections are in a lemon file we give only a framework
80.98 + /// to read a section oriented format.
80.99 + ///
80.100 + /// In the Lemon Format each section starts with a line contains a \c \@
80.101 + /// character on the first not white space position. This line is the
80.102 + /// header line of the section. Each next lines belong to this section
80.103 + /// while it does not starts with \c \@ character. This line can start a
80.104 + /// new section or if it can close the file with the \c \@end line.
80.105 + /// The file format ignore the empty and comment lines. The line is
80.106 + /// comment line if it starts with a \c # character.
80.107 + ///
80.108 + /// The framework provides an abstract LemonReader::SectionReader class
80.109 + /// what defines the interface of a SectionReader. The SectionReader
80.110 + /// has the \c header() member function what get a header line string and
80.111 + /// decides if it want to process the next section. Several SectionReaders
80.112 + /// can be attached to an LemonReader and the first attached what can
80.113 + /// process the section will be used. Its \c read() member will called
80.114 + /// with a stream contains the section. From this stream the empty and
80.115 + /// comment lines are filtered out.
80.116 + ///
80.117 + /// \relates GraphReader
80.118 + /// \relates NodeSetReader
80.119 + /// \relates EdgeSetReader
80.120 + /// \relates NodesReader
80.121 + /// \relates EdgesReader
80.122 + /// \relates AttributeReader
80.123 + class LemonReader {
80.124 + private:
80.125 +
80.126 + class FilterStreamBuf : public std::streambuf {
80.127 + public:
80.128 +
80.129 + typedef std::streambuf Parent;
80.130 + typedef Parent::char_type char_type;
80.131 + FilterStreamBuf(std::istream& is, int& num)
80.132 + : _is(is), _base(0), _eptr(0),
80.133 + _num(num), skip_state(after_endl) {}
80.134 +
80.135 + protected:
80.136 +
80.137 + enum skip_state_type {
80.138 + no_skip,
80.139 + after_endl,
80.140 + comment_line
80.141 + };
80.142 +
80.143 + char_type small_buf[1];
80.144 +
80.145 +
80.146 + std::istream& _is;
80.147 +
80.148 + char_type* _base;
80.149 + char_type* _eptr;
80.150 +
80.151 + int& _num;
80.152 +
80.153 + skip_state_type skip_state;
80.154 +
80.155 +
80.156 + char_type* base() { return _base; }
80.157 +
80.158 + char_type* eptr() { return _eptr; }
80.159 +
80.160 + int blen() { return _eptr - _base; }
80.161 +
80.162 + void setb(char_type* buf, int len) {
80.163 + _base = buf;
80.164 + _eptr = buf + len;
80.165 + }
80.166 +
80.167 + virtual std::streambuf* setbuf(char *buf, int len) {
80.168 + if (base()) return 0;
80.169 + if (buf != 0 && len >= (int)sizeof(small_buf)) {
80.170 + setb(buf, len);
80.171 + } else {
80.172 + setb(small_buf, sizeof(small_buf));
80.173 + }
80.174 + setg(0, 0, 0);
80.175 + return this;
80.176 + }
80.177 +
80.178 + bool put_char(char c) {
80.179 + switch (skip_state) {
80.180 + case no_skip:
80.181 + switch (c) {
80.182 + case '\n':
80.183 + skip_state = after_endl;
80.184 + return true;
80.185 + default:
80.186 + return true;
80.187 + }
80.188 + case after_endl:
80.189 + switch (c) {
80.190 + case '@':
80.191 + return false;
80.192 + case '\n':
80.193 + return false;
80.194 + case '#':
80.195 + skip_state = comment_line;
80.196 + return false;
80.197 + default:
80.198 + if (!isspace(c)) {
80.199 + skip_state = no_skip;
80.200 + return true;
80.201 + } else {
80.202 + return false;
80.203 + }
80.204 + }
80.205 + break;
80.206 + case comment_line:
80.207 + switch (c) {
80.208 + case '\n':
80.209 + skip_state = after_endl;
80.210 + return false;
80.211 + default:
80.212 + return false;
80.213 + }
80.214 + }
80.215 + return false;
80.216 + }
80.217 +
80.218 + virtual int underflow() {
80.219 + char c;
80.220 + if (_is.read(&c, 1)) {
80.221 + _is.putback(c);
80.222 + if (c == '@') {
80.223 + return EOF;
80.224 + }
80.225 + } else {
80.226 + return EOF;
80.227 + }
80.228 + char_type *ptr;
80.229 + for (ptr = base(); ptr != eptr(); ++ptr) {
80.230 + if (_is.read(&c, 1)) {
80.231 + if (c == '\n') ++_num;
80.232 + if (put_char(c)) {
80.233 + *ptr = c;
80.234 + } else {
80.235 + if (skip_state == after_endl && c == '@') {
80.236 + _is.putback('@');
80.237 + break;
80.238 + }
80.239 + --ptr;
80.240 + }
80.241 + } else {
80.242 + break;
80.243 + }
80.244 + }
80.245 + setg(base(), base(), ptr);
80.246 + return *base();
80.247 + }
80.248 +
80.249 + virtual int sync() {
80.250 + return EOF;
80.251 + }
80.252 + };
80.253 +
80.254 + public:
80.255 +
80.256 + /// \brief Abstract base class for reading a section.
80.257 + ///
80.258 + /// This class has an \c header() member function what get a
80.259 + /// header line string and decides if it want to process the next
80.260 + /// section. Several SectionReaders can be attached to an LemonReader
80.261 + /// and the first attached what can process the section will be used.
80.262 + /// Its \c read() member will called with a stream contains the section.
80.263 + /// From this stream the empty lines and comments are filtered out.
80.264 + class SectionReader {
80.265 + friend class LemonReader;
80.266 + protected:
80.267 + /// \brief Constructor for SectionReader.
80.268 + ///
80.269 + /// Constructor for SectionReader. It attach this reader to
80.270 + /// the given LemonReader.
80.271 + SectionReader(LemonReader& reader) {
80.272 + reader.attach(*this);
80.273 + }
80.274 +
80.275 + /// \brief Gives back true when the SectionReader can process
80.276 + /// the section with the given header line.
80.277 + ///
80.278 + /// It gives back true when the SectionReader can process
80.279 + /// the section with the given header line.
80.280 + virtual bool header(const std::string& line) = 0;
80.281 +
80.282 + /// \brief Reader function of the section.
80.283 + ///
80.284 + /// It reads the content of the section.
80.285 + virtual void read(std::istream& is) = 0;
80.286 + };
80.287 +
80.288 + /// \brief Constructor for LemonReader.
80.289 + ///
80.290 + /// Constructor for LemonReader which reads from the given stream.
80.291 + LemonReader(std::istream& _is)
80.292 + : is(&_is), own_is(false) {}
80.293 +
80.294 + /// \brief Constructor for LemonReader.
80.295 + ///
80.296 + /// Constructor for LemonReader which reads from the given file.
80.297 + LemonReader(const std::string& filename)
80.298 + : is(0), own_is(true) {
80.299 + is = new std::ifstream(filename.c_str());
80.300 + }
80.301 +
80.302 + /// \brief Desctructor for LemonReader.
80.303 + ///
80.304 + /// Desctructor for LemonReader.
80.305 + ~LemonReader() {
80.306 + if (own_is) {
80.307 + delete is;
80.308 + }
80.309 + }
80.310 +
80.311 + private:
80.312 + LemonReader(const LemonReader&);
80.313 + void operator=(const LemonReader&);
80.314 +
80.315 + void attach(SectionReader& reader) {
80.316 + readers.push_back(&reader);
80.317 + }
80.318 +
80.319 + public:
80.320 + /// \brief Executes the LemonReader.
80.321 + ///
80.322 + /// It executes the LemonReader.
80.323 + void run() {
80.324 + int line_num = 0;
80.325 + std::string line;
80.326 + try {
80.327 + while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
80.328 + SectionReaders::iterator it;
80.329 + for (it = readers.begin(); it != readers.end(); ++it) {
80.330 + if ((*it)->header(line)) {
80.331 + char buf[2048];
80.332 + FilterStreamBuf buffer(*is, line_num);
80.333 + buffer.pubsetbuf(buf, sizeof(buf));
80.334 + std::istream is(&buffer);
80.335 + (*it)->read(is);
80.336 + break;
80.337 + }
80.338 + }
80.339 + }
80.340 + } catch (DataFormatError& error) {
80.341 + error.line(line_num);
80.342 + throw error;
80.343 + }
80.344 + }
80.345 +
80.346 +
80.347 + private:
80.348 +
80.349 + std::istream* is;
80.350 + bool own_is;
80.351 +
80.352 + typedef std::vector<SectionReader*> SectionReaders;
80.353 + SectionReaders readers;
80.354 +
80.355 + };
80.356 +
80.357 + /// \brief Helper class for implementing the common SectionReaders.
80.358 + ///
80.359 + /// Helper class for implementing the common SectionReaders.
80.360 + class CommonSectionReaderBase : public LemonReader::SectionReader {
80.361 + typedef LemonReader::SectionReader Parent;
80.362 + protected:
80.363 +
80.364 + /// \brief Constructor for CommonSectionReaderBase.
80.365 + ///
80.366 + /// Constructor for CommonSectionReaderBase. It attach this reader to
80.367 + /// the given LemonReader.
80.368 + CommonSectionReaderBase(LemonReader& _reader)
80.369 + : Parent(_reader) {}
80.370 +
80.371 + template <typename _Item>
80.372 + class ReaderBase;
80.373 +
80.374 + template <typename _Item>
80.375 + class InverterBase : public ReaderBase<_Item> {
80.376 + public:
80.377 + typedef _Item Item;
80.378 + virtual void read(std::istream&, const Item&) = 0;
80.379 + virtual Item read(std::istream&) const = 0;
80.380 +
80.381 + virtual InverterBase<_Item>* getInverter() {
80.382 + return this;
80.383 + }
80.384 + };
80.385 +
80.386 + template <typename _Item, typename _Map, typename _Reader>
80.387 + class MapReaderInverter : public InverterBase<_Item> {
80.388 + public:
80.389 + typedef _Item Item;
80.390 + typedef _Reader Reader;
80.391 + typedef typename Reader::Value Value;
80.392 + typedef _Map Map;
80.393 + typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
80.394 +
80.395 + typename SmartReference<Map>::Type map;
80.396 + Reader reader;
80.397 + Inverse inverse;
80.398 +
80.399 + MapReaderInverter(typename SmartParameter<Map>::Type _map,
80.400 + const Reader& _reader)
80.401 + : map(_map), reader(_reader) {}
80.402 +
80.403 + virtual ~MapReaderInverter() {}
80.404 +
80.405 + virtual void read(std::istream& is, const Item& item) {
80.406 + Value value;
80.407 + reader.read(is, value);
80.408 + map.set(item, value);
80.409 + typename Inverse::iterator it = inverse.find(value);
80.410 + if (it == inverse.end()) {
80.411 + inverse.insert(std::make_pair(value, item));
80.412 + } else {
80.413 + throw DataFormatError("Multiple ID occurence");
80.414 + }
80.415 + }
80.416 +
80.417 + virtual Item read(std::istream& is) const {
80.418 + Value value;
80.419 + reader.read(is, value);
80.420 + typename Inverse::const_iterator it = inverse.find(value);
80.421 + if (it != inverse.end()) {
80.422 + return it->second;
80.423 + } else {
80.424 + throw DataFormatError("Invalid ID error");
80.425 + }
80.426 + }
80.427 + };
80.428 +
80.429 + template <typename _Item, typename _Reader>
80.430 + class SkipReaderInverter : public InverterBase<_Item> {
80.431 + public:
80.432 + typedef _Item Item;
80.433 + typedef _Reader Reader;
80.434 + typedef typename Reader::Value Value;
80.435 + typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
80.436 +
80.437 + Reader reader;
80.438 +
80.439 + SkipReaderInverter(const Reader& _reader)
80.440 + : reader(_reader) {}
80.441 +
80.442 + virtual ~SkipReaderInverter() {}
80.443 +
80.444 + virtual void read(std::istream& is, const Item& item) {
80.445 + Value value;
80.446 + reader.read(is, value);
80.447 + typename Inverse::iterator it = inverse.find(value);
80.448 + if (it == inverse.end()) {
80.449 + inverse.insert(std::make_pair(value, item));
80.450 + } else {
80.451 + throw DataFormatError("Multiple ID occurence error");
80.452 + }
80.453 + }
80.454 +
80.455 + virtual Item read(std::istream& is) const {
80.456 + Value value;
80.457 + reader.read(is, value);
80.458 + typename Inverse::const_iterator it = inverse.find(value);
80.459 + if (it != inverse.end()) {
80.460 + return it->second;
80.461 + } else {
80.462 + throw DataFormatError("Invalid ID error");
80.463 + }
80.464 + }
80.465 +
80.466 + private:
80.467 + Inverse inverse;
80.468 + };
80.469 +
80.470 + template <typename _Item>
80.471 + class ReaderBase {
80.472 + public:
80.473 + typedef _Item Item;
80.474 +
80.475 + virtual ~ReaderBase() {}
80.476 +
80.477 + virtual void read(std::istream& is, const Item& item) = 0;
80.478 + virtual InverterBase<_Item>* getInverter() = 0;
80.479 + };
80.480 +
80.481 + template <typename _Item, typename _Map, typename _Reader>
80.482 + class MapReader : public ReaderBase<_Item> {
80.483 + public:
80.484 + typedef _Map Map;
80.485 + typedef _Reader Reader;
80.486 + typedef typename Reader::Value Value;
80.487 + typedef _Item Item;
80.488 +
80.489 + typename SmartReference<Map>::Type map;
80.490 + Reader reader;
80.491 +
80.492 + MapReader(typename SmartParameter<Map>::Type _map,
80.493 + const Reader& _reader)
80.494 + : map(_map), reader(_reader) {}
80.495 +
80.496 + virtual ~MapReader() {}
80.497 +
80.498 + virtual void read(std::istream& is, const Item& item) {
80.499 + Value value;
80.500 + reader.read(is, value);
80.501 + map.set(item, value);
80.502 + }
80.503 +
80.504 + virtual InverterBase<_Item>* getInverter() {
80.505 + return new MapReaderInverter<Item, Map, Reader>(map, reader);
80.506 + }
80.507 + };
80.508 +
80.509 +
80.510 + template <typename _Item, typename _Reader>
80.511 + class SkipReader : public ReaderBase<_Item> {
80.512 + public:
80.513 + typedef _Reader Reader;
80.514 + typedef typename Reader::Value Value;
80.515 + typedef _Item Item;
80.516 +
80.517 + Reader reader;
80.518 + SkipReader(const Reader& _reader) : reader(_reader) {}
80.519 +
80.520 + virtual ~SkipReader() {}
80.521 +
80.522 + virtual void read(std::istream& is, const Item&) {
80.523 + Value value;
80.524 + reader.read(is, value);
80.525 + }
80.526 +
80.527 + virtual InverterBase<Item>* getInverter() {
80.528 + return new SkipReaderInverter<Item, Reader>(reader);
80.529 + }
80.530 + };
80.531 +
80.532 + template <typename _Item>
80.533 + class IdReaderBase {
80.534 + public:
80.535 + typedef _Item Item;
80.536 + virtual Item read(std::istream& is) const = 0;
80.537 + };
80.538 +
80.539 + template <typename _Item, typename _BoxedIdReader>
80.540 + class IdReader : public IdReaderBase<_Item> {
80.541 + public:
80.542 + typedef _Item Item;
80.543 + typedef _BoxedIdReader BoxedIdReader;
80.544 +
80.545 + const BoxedIdReader& boxedIdReader;
80.546 +
80.547 + IdReader(const BoxedIdReader& _boxedIdReader)
80.548 + : boxedIdReader(_boxedIdReader) {}
80.549 +
80.550 + virtual Item read(std::istream& is) const {
80.551 + return boxedIdReader.readId(is, Item());
80.552 + }
80.553 + };
80.554 +
80.555 + class ValueReaderBase {
80.556 + public:
80.557 + virtual void read(std::istream&) {};
80.558 + };
80.559 +
80.560 + template <typename _Value, typename _Reader>
80.561 + class ValueReader : public ValueReaderBase {
80.562 + public:
80.563 + typedef _Value Value;
80.564 + typedef _Reader Reader;
80.565 +
80.566 + ValueReader(Value& _value, const Reader& _reader)
80.567 + : value(_value), reader(_reader) {}
80.568 +
80.569 + virtual void read(std::istream& is) {
80.570 + reader.read(is, value);
80.571 + }
80.572 + private:
80.573 + Value& value;
80.574 + Reader reader;
80.575 + };
80.576 +
80.577 + };
80.578 +
80.579 + /// \ingroup io_group
80.580 + /// \brief SectionReader for reading a graph's nodeset.
80.581 + ///
80.582 + /// The lemon format can store multiple graph nodesets with several maps.
80.583 + /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
80.584 + /// \c nodeset_id may be empty.
80.585 + ///
80.586 + /// The first line of the section contains the names of the maps separated
80.587 + /// with white spaces. Each next lines describes a node in the nodeset, and
80.588 + /// contains the mapped values for each map.
80.589 + ///
80.590 + /// If the nodeset contains an \c "id" named map then it will be regarded
80.591 + /// as id map. This map should contain only unique values and when the
80.592 + /// \c readId() member will read a value from the given stream it will
80.593 + /// give back that node which is mapped to this value.
80.594 + ///
80.595 + /// \relates LemonReader
80.596 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
80.597 + class NodeSetReader : public CommonSectionReaderBase {
80.598 + typedef CommonSectionReaderBase Parent;
80.599 + public:
80.600 +
80.601 + typedef _Graph Graph;
80.602 + typedef _Traits Traits;
80.603 + typedef typename Graph::Node Node;
80.604 + typedef typename Traits::Skipper DefaultSkipper;
80.605 +
80.606 + /// \brief Constructor.
80.607 + ///
80.608 + /// Constructor for NodeSetReader. It creates the NodeSetReader and
80.609 + /// attach it into the given LemonReader. The nodeset reader will
80.610 + /// add the readed nodes to the given Graph. The reader will read
80.611 + /// the section when the \c section_id and the \c _id are the same.
80.612 + NodeSetReader(LemonReader& _reader,
80.613 + typename SmartParameter<Graph>::Type _graph,
80.614 + const std::string& _id = std::string(),
80.615 + const DefaultSkipper& _skipper = DefaultSkipper())
80.616 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {}
80.617 +
80.618 +
80.619 + /// \brief Destructor.
80.620 + ///
80.621 + /// Destructor for NodeSetReader.
80.622 + virtual ~NodeSetReader() {
80.623 + for (typename MapReaders::iterator it = readers.begin();
80.624 + it != readers.end(); ++it) {
80.625 + delete it->second;
80.626 + }
80.627 + }
80.628 +
80.629 + private:
80.630 + NodeSetReader(const NodeSetReader&);
80.631 + void operator=(const NodeSetReader&);
80.632 +
80.633 + public:
80.634 +
80.635 + /// \brief Add a new node map reader command for the reader.
80.636 + ///
80.637 + /// Add a new node map reader command for the reader.
80.638 + template <typename Map>
80.639 + NodeSetReader& readNodeMap(std::string name, Map& map) {
80.640 + return _readMap<
80.641 + typename Traits::template Reader<typename Map::Value>, Map,
80.642 + typename SmartParameter<Map>::Type>(name, map);
80.643 + }
80.644 +
80.645 + template <typename Map>
80.646 + NodeSetReader& readNodeMap(std::string name, const Map& map) {
80.647 + return _readMap<
80.648 + typename Traits::template Reader<typename Map::Value>, Map,
80.649 + typename SmartParameter<Map>::Type>(name, map);
80.650 + }
80.651 +
80.652 + /// \brief Add a new node map reader command for the reader.
80.653 + ///
80.654 + /// Add a new node map reader command for the reader.
80.655 + template <typename Reader, typename Map>
80.656 + NodeSetReader& readNodeMap(std::string name, Map& map,
80.657 + const Reader& reader = Reader()) {
80.658 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
80.659 + (name, map, reader);
80.660 + }
80.661 +
80.662 + template <typename Reader, typename Map>
80.663 + NodeSetReader& readNodeMap(std::string name, const Map& map,
80.664 + const Reader& reader = Reader()) {
80.665 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
80.666 + (name, map, reader);
80.667 + }
80.668 +
80.669 + private:
80.670 +
80.671 + template <typename Reader, typename Map, typename MapParameter>
80.672 + NodeSetReader& _readMap(std::string name, MapParameter map,
80.673 + const Reader& reader = Reader()) {
80.674 + if (readers.find(name) != readers.end()) {
80.675 + ErrorMessage msg;
80.676 + msg << "Multiple read rule for node map: " << name;
80.677 + throw IOParameterError(msg.message());
80.678 + }
80.679 + readers.insert(
80.680 + make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
80.681 + return *this;
80.682 + }
80.683 +
80.684 + public:
80.685 +
80.686 + /// \brief Add a new node map skipper command for the reader.
80.687 + ///
80.688 + /// Add a new node map skipper command for the reader.
80.689 + template <typename Reader>
80.690 + NodeSetReader& skipNodeMap(std::string name,
80.691 + const Reader& reader = Reader()) {
80.692 + if (readers.find(name) != readers.end()) {
80.693 + ErrorMessage msg;
80.694 + msg << "Multiple read rule for node map: " << name;
80.695 + throw IOParameterError(msg.message());
80.696 + }
80.697 + readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
80.698 + return *this;
80.699 + }
80.700 +
80.701 + protected:
80.702 +
80.703 + /// \brief Gives back true when the SectionReader can process
80.704 + /// the section with the given header line.
80.705 + ///
80.706 + /// It gives back true when the header line starts with \c \@nodeset,
80.707 + /// and the header line's id and the nodeset's id are the same.
80.708 + virtual bool header(const std::string& line) {
80.709 + std::istringstream ls(line);
80.710 + std::string command;
80.711 + std::string name;
80.712 + ls >> command >> name;
80.713 + return command == "@nodeset" && name == id;
80.714 + }
80.715 +
80.716 + /// \brief Reader function of the section.
80.717 + ///
80.718 + /// It reads the content of the section.
80.719 + virtual void read(std::istream& is) {
80.720 + std::vector<ReaderBase<Node>* > index;
80.721 + std::string line;
80.722 +
80.723 + getline(is, line);
80.724 + std::istringstream ls(line);
80.725 + while (ls >> id) {
80.726 + typename MapReaders::iterator it = readers.find(id);
80.727 + if (it != readers.end()) {
80.728 + index.push_back(it->second);
80.729 + } else {
80.730 + index.push_back(&skipper);
80.731 + }
80.732 + if (id == "id" && inverter.get() == 0) {
80.733 + inverter.reset(index.back()->getInverter());
80.734 + index.back() = inverter.get();
80.735 + }
80.736 + }
80.737 + while (getline(is, line)) {
80.738 + Node node = graph.addNode();
80.739 + std::istringstream ls(line);
80.740 + for (int i = 0; i < (int)index.size(); ++i) {
80.741 + index[i]->read(ls, node);
80.742 + }
80.743 + }
80.744 + }
80.745 +
80.746 + public:
80.747 +
80.748 + /// \brief Returns true if the nodeset can give back the node by its id.
80.749 + ///
80.750 + /// Returns true if the nodeset can give back the node by its id.
80.751 + /// It is possible only if an "id" named map was read.
80.752 + bool isIdReader() const {
80.753 + return inverter.get() != 0;
80.754 + }
80.755 +
80.756 + /// \brief Gives back the node by its id.
80.757 + ///
80.758 + /// It reads an id from the stream and gives back which node belongs to
80.759 + /// it. It is possible only if there was read an "id" named map.
80.760 + Node readId(std::istream& is, Node = Node()) const {
80.761 + return inverter->read(is);
80.762 + }
80.763 +
80.764 + private:
80.765 +
80.766 + typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
80.767 + MapReaders readers;
80.768 +
80.769 + typename SmartReference<Graph>::Type graph;
80.770 + std::string id;
80.771 + SkipReader<Node, DefaultSkipper> skipper;
80.772 +
80.773 + std::auto_ptr<InverterBase<Node> > inverter;
80.774 + };
80.775 +
80.776 + /// \ingroup io_group
80.777 + /// \brief SectionReader for reading a graph's edgeset.
80.778 + ///
80.779 + /// The lemon format can store multiple graph edgesets with several maps.
80.780 + /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
80.781 + /// \c edgeset_id may be empty.
80.782 + ///
80.783 + /// The first line of the section contains the names of the maps separated
80.784 + /// with white spaces. Each next lines describes an edge in the edgeset. The
80.785 + /// line contains the source and the target nodes' id and the mapped
80.786 + /// values for each map.
80.787 + ///
80.788 + /// If the edgeset contains an \c "id" named map then it will be regarded
80.789 + /// as id map. This map should contain only unique values and when the
80.790 + /// \c readId() member will read a value from the given stream it will
80.791 + /// give back that edge which is mapped to this value.
80.792 + ///
80.793 + /// The edgeset reader needs a node id reader to identify which nodes
80.794 + /// have to be connected. If a NodeSetReader reads an "id" named map,
80.795 + /// it will be able to resolve the nodes by ids.
80.796 + ///
80.797 + /// \relates LemonReader
80.798 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
80.799 + class EdgeSetReader : public CommonSectionReaderBase {
80.800 + typedef CommonSectionReaderBase Parent;
80.801 + public:
80.802 +
80.803 + typedef _Graph Graph;
80.804 + typedef _Traits Traits;
80.805 + typedef typename Graph::Node Node;
80.806 + typedef typename Graph::Edge Edge;
80.807 + typedef typename Traits::Skipper DefaultSkipper;
80.808 +
80.809 + /// \brief Constructor.
80.810 + ///
80.811 + /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
80.812 + /// attach it into the given LemonReader. The edgeset reader will
80.813 + /// add the readed edges to the given Graph. It will use the given
80.814 + /// node id reader to read the source and target nodes of the edges.
80.815 + /// The reader will read the section only if the \c _id and the
80.816 + /// \c edgset_id are the same.
80.817 + template <typename NodeIdReader>
80.818 + EdgeSetReader(LemonReader& _reader,
80.819 + typename SmartParameter<Graph>::Type _graph,
80.820 + const NodeIdReader& _nodeIdReader,
80.821 + const std::string& _id = std::string(),
80.822 + const DefaultSkipper& _skipper = DefaultSkipper())
80.823 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
80.824 + nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
80.825 +
80.826 + /// \brief Destructor.
80.827 + ///
80.828 + /// Destructor for EdgeSetReader.
80.829 + virtual ~EdgeSetReader() {
80.830 + for (typename MapReaders::iterator it = readers.begin();
80.831 + it != readers.end(); ++it) {
80.832 + delete it->second;
80.833 + }
80.834 + }
80.835 +
80.836 + private:
80.837 + EdgeSetReader(const EdgeSetReader&);
80.838 + void operator=(const EdgeSetReader&);
80.839 +
80.840 + public:
80.841 +
80.842 + /// \brief Add a new edge map reader command for the reader.
80.843 + ///
80.844 + /// Add a new edge map reader command for the reader.
80.845 + template <typename Map>
80.846 + EdgeSetReader& readEdgeMap(std::string name, Map& map) {
80.847 + return _readMap<
80.848 + typename Traits::template Reader<typename Map::Value>, Map,
80.849 + typename SmartParameter<Map>::Type>(name, map);
80.850 + }
80.851 +
80.852 + template <typename Map>
80.853 + EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
80.854 + return _readMap<
80.855 + typename Traits::template Reader<typename Map::Value>, Map,
80.856 + typename SmartParameter<Map>::Type>(name, map);
80.857 + }
80.858 +
80.859 + /// \brief Add a new edge map reader command for the reader.
80.860 + ///
80.861 + /// Add a new edge map reader command for the reader.
80.862 + template <typename Reader, typename Map>
80.863 + EdgeSetReader& readEdgeMap(std::string name, Map& map,
80.864 + const Reader& reader = Reader()) {
80.865 + return _readMap<Reader, Map,
80.866 + typename SmartParameter<Map>::Type>(name, map, reader);
80.867 + }
80.868 +
80.869 + template <typename Reader, typename Map>
80.870 + EdgeSetReader& readEdgeMap(std::string name, const Map& map,
80.871 + const Reader& reader = Reader()) {
80.872 + return _readMap<Reader, Map,
80.873 + typename SmartParameter<Map>::Type>(name, map, reader);
80.874 + }
80.875 +
80.876 + private:
80.877 +
80.878 + template <typename Reader, typename Map, typename MapParameter>
80.879 + EdgeSetReader& _readMap(std::string name, MapParameter map,
80.880 + const Reader& reader = Reader()) {
80.881 + if (readers.find(name) != readers.end()) {
80.882 + ErrorMessage msg;
80.883 + msg << "Multiple read rule for edge map: " << name;
80.884 + throw IOParameterError(msg.message());
80.885 + }
80.886 + readers.insert(
80.887 + make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
80.888 + return *this;
80.889 + }
80.890 +
80.891 + public:
80.892 +
80.893 + /// \brief Add a new edge map skipper command for the reader.
80.894 + ///
80.895 + /// Add a new edge map skipper command for the reader.
80.896 + template <typename Reader>
80.897 + EdgeSetReader& skipEdgeMap(std::string name,
80.898 + const Reader& reader = Reader()) {
80.899 + if (readers.find(name) != readers.end()) {
80.900 + ErrorMessage msg;
80.901 + msg << "Multiple read rule for edge map: " << name;
80.902 + throw IOParameterError(msg.message());
80.903 + }
80.904 + readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
80.905 + return *this;
80.906 + }
80.907 +
80.908 + protected:
80.909 +
80.910 + /// \brief Gives back true when the SectionReader can process
80.911 + /// the section with the given header line.
80.912 + ///
80.913 + /// It gives back true when the header line starts with \c \@edgeset,
80.914 + /// and the header line's id and the edgeset's id are the same.
80.915 + virtual bool header(const std::string& line) {
80.916 + std::istringstream ls(line);
80.917 + std::string command;
80.918 + std::string name;
80.919 + ls >> command >> name;
80.920 + return command == "@edgeset" && name == id;
80.921 + }
80.922 +
80.923 + /// \brief Reader function of the section.
80.924 + ///
80.925 + /// It reads the content of the section.
80.926 + virtual void read(std::istream& is) {
80.927 + std::vector<ReaderBase<Edge>* > index;
80.928 + std::string line;
80.929 +
80.930 + getline(is, line);
80.931 + std::istringstream ls(line);
80.932 + while (ls >> id) {
80.933 + typename MapReaders::iterator it = readers.find(id);
80.934 + if (it != readers.end()) {
80.935 + index.push_back(it->second);
80.936 + } else {
80.937 + index.push_back(&skipper);
80.938 + }
80.939 + if (id == "id" && inverter.get() == 0) {
80.940 + inverter.reset(index.back()->getInverter());
80.941 + index.back() = inverter.get();
80.942 + }
80.943 + }
80.944 + while (getline(is, line)) {
80.945 + std::istringstream ls(line);
80.946 + Node from = nodeIdReader->read(ls);
80.947 + Node to = nodeIdReader->read(ls);
80.948 + Edge edge = graph.addEdge(from, to);
80.949 + for (int i = 0; i < (int)index.size(); ++i) {
80.950 + index[i]->read(ls, edge);
80.951 + }
80.952 + }
80.953 + }
80.954 +
80.955 + public:
80.956 +
80.957 + /// \brief Returns true if the edgeset can give back the edge by its id.
80.958 + ///
80.959 + /// Returns true if the edgeset can give back the edge by its id.
80.960 + /// It is possible only if an "id" named map was read.
80.961 + bool isIdReader() const {
80.962 + return inverter.get() != 0;
80.963 + }
80.964 +
80.965 + /// \brief Gives back the edge by its id.
80.966 + ///
80.967 + /// It reads an id from the stream and gives back which edge belongs to
80.968 + /// it. It is possible only if there was read an "id" named map.
80.969 + Edge readId(std::istream& is, Edge = Edge()) const {
80.970 + return inverter->read(is);
80.971 + }
80.972 +
80.973 + private:
80.974 +
80.975 + typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
80.976 + MapReaders readers;
80.977 +
80.978 + typename SmartReference<Graph>::Type graph;
80.979 + std::string id;
80.980 + SkipReader<Edge, DefaultSkipper> skipper;
80.981 +
80.982 + std::auto_ptr<InverterBase<Edge> > inverter;
80.983 + std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
80.984 + };
80.985 +
80.986 + /// \ingroup io_group
80.987 + /// \brief SectionReader for reading a undirected graph's edgeset.
80.988 + ///
80.989 + /// The lemon format can store multiple undirected edgesets with several
80.990 + /// maps. The undirected edgeset section's header line is \c \@undiredgeset
80.991 + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
80.992 + ///
80.993 + /// The first line of the section contains the names of the maps separated
80.994 + /// with white spaces. Each next lines describes an edge in the edgeset. The
80.995 + /// line contains the connected nodes' id and the mapped values for each map.
80.996 + ///
80.997 + /// The section can handle the directed as a syntactical sugar. Two
80.998 + /// undirected edge map describes one directed edge map. This two maps
80.999 + /// are the forward map and the backward map and the names of this map
80.1000 + /// is near the same just with a prefix \c '+' or \c '-' character
80.1001 + /// difference.
80.1002 + ///
80.1003 + /// If the edgeset contains an \c "id" named map then it will be regarded
80.1004 + /// as id map. This map should contain only unique values and when the
80.1005 + /// \c readId() member will read a value from the given stream it will
80.1006 + /// give back that undiricted edge which is mapped to this value.
80.1007 + ///
80.1008 + /// The undirected edgeset reader needs a node id reader to identify which
80.1009 + /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
80.1010 + /// it will be able to resolve the nodes by ids.
80.1011 + ///
80.1012 + /// \relates LemonReader
80.1013 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
80.1014 + class UndirEdgeSetReader : public CommonSectionReaderBase {
80.1015 + typedef CommonSectionReaderBase Parent;
80.1016 + public:
80.1017 +
80.1018 + typedef _Graph Graph;
80.1019 + typedef _Traits Traits;
80.1020 + typedef typename Graph::Node Node;
80.1021 + typedef typename Graph::Edge Edge;
80.1022 + typedef typename Graph::UndirEdge UndirEdge;
80.1023 + typedef typename Traits::Skipper DefaultSkipper;
80.1024 +
80.1025 + /// \brief Constructor.
80.1026 + ///
80.1027 + /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader
80.1028 + /// and attach it into the given LemonReader. The undirected edgeset
80.1029 + /// reader will add the readed undirected edges to the given Graph. It
80.1030 + /// will use the given node id reader to read the source and target
80.1031 + /// nodes of the edges. The reader will read the section only if the
80.1032 + /// \c _id and the \c undiredgset_id are the same.
80.1033 + template <typename NodeIdReader>
80.1034 + UndirEdgeSetReader(LemonReader& _reader,
80.1035 + typename SmartParameter<Graph>::Type _graph,
80.1036 + const NodeIdReader& _nodeIdReader,
80.1037 + const std::string& _id = std::string(),
80.1038 + const DefaultSkipper& _skipper = DefaultSkipper())
80.1039 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
80.1040 + nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
80.1041 +
80.1042 + /// \brief Destructor.
80.1043 + ///
80.1044 + /// Destructor for UndirEdgeSetReader.
80.1045 + virtual ~UndirEdgeSetReader() {
80.1046 + for (typename MapReaders::iterator it = readers.begin();
80.1047 + it != readers.end(); ++it) {
80.1048 + delete it->second;
80.1049 + }
80.1050 + }
80.1051 +
80.1052 + private:
80.1053 + UndirEdgeSetReader(const UndirEdgeSetReader&);
80.1054 + void operator=(const UndirEdgeSetReader&);
80.1055 +
80.1056 + public:
80.1057 +
80.1058 + /// \brief Add a new undirected edge map reader command for the reader.
80.1059 + ///
80.1060 + /// Add a new edge undirected map reader command for the reader.
80.1061 + template <typename Map>
80.1062 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
80.1063 + return _readMap<
80.1064 + typename Traits::template Reader<typename Map::Value>, Map,
80.1065 + typename SmartParameter<Map>::Type>(name, map);
80.1066 + }
80.1067 +
80.1068 + template <typename Map>
80.1069 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
80.1070 + return _readMap<
80.1071 + typename Traits::template Reader<typename Map::Value>, Map,
80.1072 + typename SmartParameter<Map>::Type>(name, map);
80.1073 + }
80.1074 +
80.1075 + /// \brief Add a new undirected edge map reader command for the reader.
80.1076 + ///
80.1077 + /// Add a new edge undirected map reader command for the reader.
80.1078 + template <typename Reader, typename Map>
80.1079 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map,
80.1080 + const Reader& reader = Reader()) {
80.1081 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
80.1082 + (name, map, reader);
80.1083 + }
80.1084 +
80.1085 + template <typename Reader, typename Map>
80.1086 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map,
80.1087 + const Reader& reader = Reader()) {
80.1088 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
80.1089 + (name, map, reader);
80.1090 + }
80.1091 +
80.1092 + private:
80.1093 +
80.1094 + template <typename Reader, typename Map, typename MapParameter>
80.1095 + UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
80.1096 + const Reader& reader = Reader()) {
80.1097 + if (readers.find(name) != readers.end()) {
80.1098 + ErrorMessage msg;
80.1099 + msg << "Multiple read rule for edge map: " << name;
80.1100 + throw IOParameterError(msg.message());
80.1101 + }
80.1102 + readers.insert(
80.1103 + make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
80.1104 + return *this;
80.1105 + }
80.1106 +
80.1107 + public:
80.1108 +
80.1109 + /// \brief Add a new undirected edge map skipper command for the reader.
80.1110 + ///
80.1111 + /// Add a new undirected edge map skipper command for the reader.
80.1112 + template <typename Reader>
80.1113 + UndirEdgeSetReader& skipUndirEdgeMap(std::string name,
80.1114 + const Reader& reader = Reader()) {
80.1115 + if (readers.find(name) != readers.end()) {
80.1116 + ErrorMessage msg;
80.1117 + msg << "Multiple read rule for node map: " << name;
80.1118 + throw IOParameterError(msg.message());
80.1119 + }
80.1120 + readers.insert(make_pair(name,
80.1121 + new SkipReader<UndirEdge, Reader>(reader)));
80.1122 + return *this;
80.1123 + }
80.1124 +
80.1125 + /// \brief Add a new directed edge map reader command for the reader.
80.1126 + ///
80.1127 + /// Add a new directed edge map reader command for the reader.
80.1128 + template <typename Map>
80.1129 + UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
80.1130 + return _readDirMap<
80.1131 + typename Traits::template Reader<typename Map::Value>, Map,
80.1132 + typename SmartParameter<Map>::Type>(name, map);
80.1133 + }
80.1134 +
80.1135 + template <typename Map>
80.1136 + UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
80.1137 + return _readDirMap<
80.1138 + typename Traits::template Reader<typename Map::Value>, Map,
80.1139 + typename SmartParameter<Map>::Type>(name, map);
80.1140 + }
80.1141 +
80.1142 + /// \brief Add a new directed edge map reader command for the reader.
80.1143 + ///
80.1144 + /// Add a new directed edge map reader command for the reader.
80.1145 + template <typename Reader, typename Map>
80.1146 + UndirEdgeSetReader& readEdgeMap(std::string name, Map& map,
80.1147 + const Reader& reader = Reader()) {
80.1148 + return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
80.1149 + (name, map, reader);
80.1150 + }
80.1151 +
80.1152 + template <typename Reader, typename Map>
80.1153 + UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map,
80.1154 + const Reader& reader = Reader()) {
80.1155 + return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
80.1156 + (name, map, reader);
80.1157 + }
80.1158 +
80.1159 + private:
80.1160 +
80.1161 + template <typename Reader, typename Map, typename MapParameter>
80.1162 + UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
80.1163 + const Reader& reader = Reader()) {
80.1164 + readMap("+" + name,
80.1165 + _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
80.1166 + readMap("-" + name,
80.1167 + _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
80.1168 + return *this;
80.1169 + }
80.1170 +
80.1171 + public:
80.1172 +
80.1173 + /// \brief Add a new directed edge map skipper command for the reader.
80.1174 + ///
80.1175 + /// Add a new directed edge map skipper command for the reader.
80.1176 + template <typename Reader>
80.1177 + UndirEdgeSetReader& skipEdgeMap(std::string name,
80.1178 + const Reader& reader = Reader()) {
80.1179 + skipMap("+" + name, reader);
80.1180 + skipMap("-" + name, reader);
80.1181 + return *this;
80.1182 + }
80.1183 +
80.1184 + protected:
80.1185 +
80.1186 + /// \brief Gives back true when the SectionReader can process
80.1187 + /// the section with the given header line.
80.1188 + ///
80.1189 + /// It gives back true when the header line starts with \c \@undiredgeset,
80.1190 + /// and the header line's id and the edgeset's id are the same.
80.1191 + virtual bool header(const std::string& line) {
80.1192 + std::istringstream ls(line);
80.1193 + std::string command;
80.1194 + std::string name;
80.1195 + ls >> command >> name;
80.1196 + return command == "@undiredgeset" && name == id;
80.1197 + }
80.1198 +
80.1199 + /// \brief Reader function of the section.
80.1200 + ///
80.1201 + /// It reads the content of the section.
80.1202 + virtual void read(std::istream& is) {
80.1203 + std::vector<ReaderBase<UndirEdge>* > index;
80.1204 + std::string line;
80.1205 +
80.1206 + getline(is, line);
80.1207 + std::istringstream ls(line);
80.1208 + while (ls >> id) {
80.1209 + typename MapReaders::iterator it = readers.find(id);
80.1210 + if (it != readers.end()) {
80.1211 + index.push_back(it->second);
80.1212 + } else {
80.1213 + index.push_back(&skipper);
80.1214 + }
80.1215 + if (id == "id" && inverter.get() == 0) {
80.1216 + inverter.reset(index.back()->getInverter());
80.1217 + index.back() = inverter.get();
80.1218 + }
80.1219 + }
80.1220 + while (getline(is, line)) {
80.1221 + std::istringstream ls(line);
80.1222 + Node from = nodeIdReader->read(ls);
80.1223 + Node to = nodeIdReader->read(ls);
80.1224 + UndirEdge edge = graph.addEdge(from, to);
80.1225 + for (int i = 0; i < (int)index.size(); ++i) {
80.1226 + index[i]->read(ls, edge);
80.1227 + }
80.1228 + }
80.1229 + }
80.1230 +
80.1231 + public:
80.1232 +
80.1233 + /// \brief Returns true if the edgeset can give back the edge by its id.
80.1234 + ///
80.1235 + /// Returns true if the edgeset can give back the undirected edge by its
80.1236 + /// id. It is possible only if an "id" named map was read.
80.1237 + bool isIdReader() const {
80.1238 + return inverter.get() != 0;
80.1239 + }
80.1240 +
80.1241 + /// \brief Gives back the undirected edge by its id.
80.1242 + ///
80.1243 + /// It reads an id from the stream and gives back which undirected edge
80.1244 + /// belongs to it. It is possible only if there was read an "id" named map.
80.1245 + UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const {
80.1246 + return inverter->read(is);
80.1247 + }
80.1248 +
80.1249 + /// \brief Gives back the directed edge by its id.
80.1250 + ///
80.1251 + /// It reads an id from the stream and gives back which directed edge
80.1252 + /// belongs to it. The directed edge id is the \c '+' or \c '-' character
80.1253 + /// and the undirected edge id. It is possible only if there was read
80.1254 + /// an "id" named map.
80.1255 + Edge readId(std::istream& is, Edge = Edge()) const {
80.1256 + char c;
80.1257 + is >> c;
80.1258 + UndirEdge undirEdge = inverter->read(is);
80.1259 + if (c == '+') {
80.1260 + return graph.edgeWithSource(undirEdge, graph.source(undirEdge));
80.1261 + } else if (c == '-') {
80.1262 + return graph.edgeWithSource(undirEdge, graph.target(undirEdge));
80.1263 + } else {
80.1264 + throw DataFormatError("Wrong id format for edge "
80.1265 + "in undirected edgeset");
80.1266 + }
80.1267 + }
80.1268 +
80.1269 + private:
80.1270 +
80.1271 + typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
80.1272 + MapReaders readers;
80.1273 +
80.1274 + typename SmartReference<Graph>::Type graph;
80.1275 + std::string id;
80.1276 + SkipReader<UndirEdge, DefaultSkipper> skipper;
80.1277 +
80.1278 + std::auto_ptr<InverterBase<UndirEdge> > inverter;
80.1279 + std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
80.1280 + };
80.1281 +
80.1282 + /// \ingroup io_group
80.1283 + /// \brief SectionReader for reading labeled nodes.
80.1284 + ///
80.1285 + /// The nodes section's header line is \c \@nodes \c nodes_id, but the
80.1286 + /// \c nodes_id may be empty.
80.1287 + ///
80.1288 + /// Each line in the section contains the name of the node
80.1289 + /// and then the node id.
80.1290 + ///
80.1291 + /// \relates LemonReader
80.1292 + template <typename _Graph>
80.1293 + class NodeReader : public CommonSectionReaderBase {
80.1294 + typedef CommonSectionReaderBase Parent;
80.1295 + typedef _Graph Graph;
80.1296 + typedef typename Graph::Node Node;
80.1297 + public:
80.1298 +
80.1299 + /// \brief Constructor.
80.1300 + ///
80.1301 + /// Constructor for NodeReader. It creates the NodeReader and
80.1302 + /// attach it into the given LemonReader. It will use the given
80.1303 + /// node id reader to give back the nodes. The reader will read the
80.1304 + /// section only if the \c _id and the \c nodes_id are the same.
80.1305 + template <typename _IdReader>
80.1306 + NodeReader(LemonReader& _reader, const _IdReader& _idReader,
80.1307 + const std::string& _id = std::string())
80.1308 + : Parent(_reader), id(_id),
80.1309 + idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {}
80.1310 +
80.1311 + /// \brief Destructor.
80.1312 + ///
80.1313 + /// Destructor for NodeReader.
80.1314 + virtual ~NodeReader() {}
80.1315 +
80.1316 + private:
80.1317 + NodeReader(const NodeReader&);
80.1318 + void operator=(const NodeReader&);
80.1319 +
80.1320 + public:
80.1321 +
80.1322 + /// \brief Add a node reader command for the NodeReader.
80.1323 + ///
80.1324 + /// Add a node reader command for the NodeReader.
80.1325 + void readNode(const std::string& name, Node& item) {
80.1326 + if (readers.find(name) != readers.end()) {
80.1327 + ErrorMessage msg;
80.1328 + msg << "Multiple read rule for node: " << name;
80.1329 + throw IOParameterError(msg.message());
80.1330 + }
80.1331 + readers.insert(make_pair(name, &item));
80.1332 + }
80.1333 +
80.1334 + protected:
80.1335 +
80.1336 + /// \brief Gives back true when the SectionReader can process
80.1337 + /// the section with the given header line.
80.1338 + ///
80.1339 + /// It gives back true when the header line start with \c \@nodes,
80.1340 + /// and the header line's id and the reader's id are the same.
80.1341 + virtual bool header(const std::string& line) {
80.1342 + std::istringstream ls(line);
80.1343 + std::string command;
80.1344 + std::string name;
80.1345 + ls >> command >> name;
80.1346 + return command == "@nodes" && name == id;
80.1347 + }
80.1348 +
80.1349 + /// \brief Reader function of the section.
80.1350 + ///
80.1351 + /// It reads the content of the section.
80.1352 + virtual void read(std::istream& is) {
80.1353 + std::string line;
80.1354 + while (getline(is, line)) {
80.1355 + std::istringstream ls(line);
80.1356 + std::string id;
80.1357 + ls >> id;
80.1358 + typename NodeReaders::iterator it = readers.find(id);
80.1359 + if (it != readers.end()) {
80.1360 + *(it->second) = idReader->read(ls);
80.1361 + }
80.1362 + }
80.1363 + }
80.1364 +
80.1365 + private:
80.1366 +
80.1367 + std::string id;
80.1368 +
80.1369 + typedef std::map<std::string, Node*> NodeReaders;
80.1370 + NodeReaders readers;
80.1371 + std::auto_ptr<IdReaderBase<Node> > idReader;
80.1372 + };
80.1373 +
80.1374 + /// \ingroup io_group
80.1375 + /// \brief SectionReader for reading labeled edges.
80.1376 + ///
80.1377 + /// The edges section's header line is \c \@edges \c edges_id, but the
80.1378 + /// \c edges_id may be empty.
80.1379 + ///
80.1380 + /// Each line in the section contains the name of the edge
80.1381 + /// and then the edge id.
80.1382 + ///
80.1383 + /// \relates LemonReader
80.1384 + template <typename _Graph>
80.1385 + class EdgeReader : public CommonSectionReaderBase {
80.1386 + typedef CommonSectionReaderBase Parent;
80.1387 + typedef _Graph Graph;
80.1388 + typedef typename Graph::Edge Edge;
80.1389 + public:
80.1390 +
80.1391 + /// \brief Constructor.
80.1392 + ///
80.1393 + /// Constructor for EdgeReader. It creates the EdgeReader and
80.1394 + /// attach it into the given LemonReader. It will use the given
80.1395 + /// edge id reader to give back the edges. The reader will read the
80.1396 + /// section only if the \c _id and the \c edges_id are the same.
80.1397 + template <typename _IdReader>
80.1398 + EdgeReader(LemonReader& _reader, const _IdReader& _idReader,
80.1399 + const std::string& _id = std::string())
80.1400 + : Parent(_reader), id(_id),
80.1401 + idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {}
80.1402 +
80.1403 + /// \brief Destructor.
80.1404 + ///
80.1405 + /// Destructor for EdgeReader.
80.1406 + virtual ~EdgeReader() {}
80.1407 + private:
80.1408 + EdgeReader(const EdgeReader&);
80.1409 + void operator=(const EdgeReader&);
80.1410 +
80.1411 + public:
80.1412 +
80.1413 + /// \brief Add an edge reader command for the EdgeReader.
80.1414 + ///
80.1415 + /// Add an edge reader command for the EdgeReader.
80.1416 + void readEdge(const std::string& name, Edge& item) {
80.1417 + if (readers.find(name) != readers.end()) {
80.1418 + ErrorMessage msg;
80.1419 + msg << "Multiple read rule for edge: " << name;
80.1420 + throw IOParameterError(msg.message());
80.1421 + }
80.1422 + readers.insert(make_pair(name, &item));
80.1423 + }
80.1424 +
80.1425 + protected:
80.1426 +
80.1427 + /// \brief Gives back true when the SectionReader can process
80.1428 + /// the section with the given header line.
80.1429 + ///
80.1430 + /// It gives back true when the header line start with \c \@edges,
80.1431 + /// and the header line's id and the reader's id are the same.
80.1432 + virtual bool header(const std::string& line) {
80.1433 + std::istringstream ls(line);
80.1434 + std::string command;
80.1435 + std::string name;
80.1436 + ls >> command >> name;
80.1437 + return command == "@edges" && name == id;
80.1438 + }
80.1439 +
80.1440 + /// \brief Reader function of the section.
80.1441 + ///
80.1442 + /// It reads the content of the section.
80.1443 + virtual void read(std::istream& is) {
80.1444 + std::string line;
80.1445 + while (getline(is, line)) {
80.1446 + std::istringstream ls(line);
80.1447 + std::string id;
80.1448 + ls >> id;
80.1449 + typename EdgeReaders::iterator it = readers.find(id);
80.1450 + if (it != readers.end()) {
80.1451 + *(it->second) = idReader->read(ls);
80.1452 + }
80.1453 + }
80.1454 + }
80.1455 +
80.1456 + private:
80.1457 +
80.1458 + std::string id;
80.1459 +
80.1460 + typedef std::map<std::string, Edge*> EdgeReaders;
80.1461 + EdgeReaders readers;
80.1462 + std::auto_ptr<IdReaderBase<Edge> > idReader;
80.1463 + };
80.1464 +
80.1465 + /// \ingroup io_group
80.1466 + /// \brief SectionReader for reading labeled undirected edges.
80.1467 + ///
80.1468 + /// The undirected edges section's header line is \c \@undiredges
80.1469 + /// \c undiredges_id, but the \c undiredges_id may be empty.
80.1470 + ///
80.1471 + /// Each line in the section contains the name of the undirected edge
80.1472 + /// and then the undirected edge id.
80.1473 + ///
80.1474 + /// \relates LemonReader
80.1475 + template <typename _Graph>
80.1476 + class UndirEdgeReader : public CommonSectionReaderBase {
80.1477 + typedef CommonSectionReaderBase Parent;
80.1478 + typedef _Graph Graph;
80.1479 + typedef typename Graph::Edge Edge;
80.1480 + typedef typename Graph::UndirEdge UndirEdge;
80.1481 + public:
80.1482 +
80.1483 + /// \brief Constructor.
80.1484 + ///
80.1485 + /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
80.1486 + /// attach it into the given LemonReader. It will use the given
80.1487 + /// undirected edge id reader to give back the edges. The reader will
80.1488 + /// read the section only if the \c _id and the \c undiredges_id are
80.1489 + /// the same.
80.1490 + template <typename _IdReader>
80.1491 + UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader,
80.1492 + const std::string& _id = std::string())
80.1493 + : Parent(_reader), id(_id),
80.1494 + undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
80.1495 + edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
80.1496 + {}
80.1497 +
80.1498 + /// \brief Destructor.
80.1499 + ///
80.1500 + /// Destructor for UndirEdgeReader.
80.1501 + virtual ~UndirEdgeReader() {}
80.1502 + private:
80.1503 + UndirEdgeReader(const UndirEdgeReader&);
80.1504 + void operator=(const UndirEdgeReader&);
80.1505 +
80.1506 + public:
80.1507 +
80.1508 + /// \brief Add an undirected edge reader command for the UndirEdgeReader.
80.1509 + ///
80.1510 + /// Add an undirected edge reader command for the UndirEdgeReader.
80.1511 + void readUndirEdge(const std::string& name, UndirEdge& item) {
80.1512 + if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) {
80.1513 + ErrorMessage msg;
80.1514 + msg << "Multiple read rule for undirected edge: " << name;
80.1515 + throw IOParameterError(msg.message());
80.1516 + }
80.1517 + undirEdgeReaders.insert(make_pair(name, &item));
80.1518 + }
80.1519 +
80.1520 + /// \brief Add an edge reader command for the UndirEdgeReader.
80.1521 + ///
80.1522 + /// Add an edge reader command for the UndirEdgeReader.
80.1523 + void readEdge(const std::string& name, Edge& item) {
80.1524 + if (edgeReaders.find(name) != edgeReaders.end()) {
80.1525 + ErrorMessage msg;
80.1526 + msg << "Multiple read rule for edge: " << name;
80.1527 + throw IOParameterError(msg.message());
80.1528 + }
80.1529 + edgeReaders.insert(make_pair(name, &item));
80.1530 + }
80.1531 +
80.1532 + protected:
80.1533 +
80.1534 + /// \brief Gives back true when the SectionReader can process
80.1535 + /// the section with the given header line.
80.1536 + ///
80.1537 + /// It gives back true when the header line start with \c \@edges,
80.1538 + /// and the header line's id and the reader's id are the same.
80.1539 + virtual bool header(const std::string& line) {
80.1540 + std::istringstream ls(line);
80.1541 + std::string command;
80.1542 + std::string name;
80.1543 + ls >> command >> name;
80.1544 + return command == "@undiredges" && name == id;
80.1545 + }
80.1546 +
80.1547 + /// \brief Reader function of the section.
80.1548 + ///
80.1549 + /// It reads the content of the section.
80.1550 + virtual void read(std::istream& is) {
80.1551 + std::string line;
80.1552 + while (getline(is, line)) {
80.1553 + std::istringstream ls(line);
80.1554 + std::string id;
80.1555 + ls >> id;
80.1556 + {
80.1557 + typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
80.1558 + if (it != undirEdgeReaders.end()) {
80.1559 + *(it->second) = undirEdgeIdReader->read(ls);
80.1560 + break;
80.1561 + }
80.1562 + } {
80.1563 + typename EdgeReaders::iterator it = edgeReaders.find(id);
80.1564 + if (it != edgeReaders.end()) {
80.1565 + *(it->second) = edgeIdReader->read(ls);
80.1566 + break;
80.1567 + }
80.1568 + }
80.1569 + }
80.1570 + }
80.1571 +
80.1572 + private:
80.1573 +
80.1574 + std::string id;
80.1575 +
80.1576 + typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
80.1577 + UndirEdgeReaders undirEdgeReaders;
80.1578 + std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
80.1579 +
80.1580 + typedef std::map<std::string, Edge*> EdgeReaders;
80.1581 + EdgeReaders edgeReaders;
80.1582 + std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
80.1583 + };
80.1584 +
80.1585 + /// \ingroup io_group
80.1586 + /// \brief SectionReader for attributes.
80.1587 + ///
80.1588 + /// The lemon format can store multiple attribute set. Each set has
80.1589 + /// the header line \c \@attributes \c attributeset_id, but the
80.1590 + /// attributeset_id may be empty.
80.1591 + ///
80.1592 + /// The attributeset section contains several lines. Each of them starts
80.1593 + /// with an attribute and then a the value for the id.
80.1594 + ///
80.1595 + /// \relates LemonReader
80.1596 + template <typename _Traits = DefaultReaderTraits>
80.1597 + class AttributeReader : public CommonSectionReaderBase {
80.1598 + typedef CommonSectionReaderBase Parent;
80.1599 + typedef _Traits Traits;
80.1600 + public:
80.1601 + /// \brief Constructor.
80.1602 + ///
80.1603 + /// Constructor for AttributeReader. It creates the AttributeReader and
80.1604 + /// attach it into the given LemonReader. The reader process a section
80.1605 + /// only if the \c section_id and the \c _id are the same.
80.1606 + AttributeReader(LemonReader& _reader,
80.1607 + const std::string& _id = std::string())
80.1608 + : Parent(_reader), id(_id) {}
80.1609 +
80.1610 + /// \brief Destructor.
80.1611 + ///
80.1612 + /// Destructor for AttributeReader.
80.1613 + virtual ~AttributeReader() {
80.1614 + for (typename Readers::iterator it = readers.begin();
80.1615 + it != readers.end(); ++it) {
80.1616 + delete it->second;
80.1617 + }
80.1618 + }
80.1619 +
80.1620 + private:
80.1621 + AttributeReader(const AttributeReader&);
80.1622 + void operator=(AttributeReader&);
80.1623 +
80.1624 + public:
80.1625 + /// \brief Add an attribute reader command for the reader.
80.1626 + ///
80.1627 + /// Add an attribute reader command for the reader.
80.1628 + template <typename Value>
80.1629 + AttributeReader& readAttribute(const std::string& id, Value& value) {
80.1630 + return readAttribute<typename Traits::template Reader<Value> >
80.1631 + (id, value);
80.1632 + }
80.1633 +
80.1634 + /// \brief Add an attribute reader command for the reader.
80.1635 + ///
80.1636 + /// Add an attribute reader command for the reader.
80.1637 + template <typename Reader, typename Value>
80.1638 + AttributeReader& readAttribute(const std::string& name, Value& value,
80.1639 + const Reader& reader = Reader()) {
80.1640 + if (readers.find(name) != readers.end()) {
80.1641 + ErrorMessage msg;
80.1642 + msg << "Multiple read rule for attribute: " << name;
80.1643 + throw IOParameterError(msg.message());
80.1644 + }
80.1645 + readers.insert(make_pair(name, new ValueReader<Value, Reader>
80.1646 + (value, reader)));
80.1647 + return *this;
80.1648 + }
80.1649 +
80.1650 + protected:
80.1651 +
80.1652 + /// \brief Gives back true when the SectionReader can process
80.1653 + /// the section with the given header line.
80.1654 + ///
80.1655 + /// It gives back true when the header line start with \c \@attributes,
80.1656 + /// and the header line's id and the attributeset's id are the same.
80.1657 + bool header(const std::string& line) {
80.1658 + std::istringstream ls(line);
80.1659 + std::string command;
80.1660 + std::string name;
80.1661 + ls >> command >> name;
80.1662 + return command == "@attributes" && name == id;
80.1663 + }
80.1664 +
80.1665 + /// \brief Reader function of the section.
80.1666 + ///
80.1667 + /// It reads the content of the section.
80.1668 + void read(std::istream& is) {
80.1669 + std::string line;
80.1670 + while (getline(is, line)) {
80.1671 + std::istringstream ls(line);
80.1672 + std::string id;
80.1673 + ls >> id;
80.1674 + typename Readers::iterator it = readers.find(id);
80.1675 + if (it != readers.end()) {
80.1676 + it->second->read(ls);
80.1677 + }
80.1678 + }
80.1679 + }
80.1680 +
80.1681 + private:
80.1682 + std::string id;
80.1683 +
80.1684 + typedef std::map<std::string, ValueReaderBase*> Readers;
80.1685 + Readers readers;
80.1686 + };
80.1687 +
80.1688 + /// \ingroup io_group
80.1689 + /// \brief SectionReader for retrieve what is in the file.
80.1690 + ///
80.1691 + /// SectionReader for retrieve what is in the file. If you want
80.1692 + /// to know which sections, maps and items are in the file
80.1693 + /// use the next code:
80.1694 + /// \code
80.1695 + /// LemonReader reader("input.lgf");
80.1696 + /// ContentReader content(reader);
80.1697 + /// reader.run();
80.1698 + /// \endcode
80.1699 + class ContentReader : public LemonReader::SectionReader {
80.1700 + typedef LemonReader::SectionReader Parent;
80.1701 + public:
80.1702 + /// \brief Constructor.
80.1703 + ///
80.1704 + /// Constructor for
80.1705 + ContentReader(LemonReader& _reader) : Parent(_reader) {}
80.1706 +
80.1707 + /// \brief Desctructor.
80.1708 + ///
80.1709 + /// Desctructor.
80.1710 + virtual ~ContentReader() {}
80.1711 +
80.1712 + /// \brief Gives back how many nodesets are in the file.
80.1713 + ///
80.1714 + /// Gives back how many nodesets are in the file.
80.1715 + int nodeSetNum() const {
80.1716 + return nodesets.size();
80.1717 + }
80.1718 +
80.1719 + /// \brief Gives back the name of nodeset on the indiced position.
80.1720 + ///
80.1721 + /// Gives back the name of nodeset on the indiced position.
80.1722 + std::string nodeSetName(int index) const {
80.1723 + return nodesets[index].name;
80.1724 + }
80.1725 +
80.1726 + /// \brief Gives back the map names of nodeset on the indiced position.
80.1727 + ///
80.1728 + /// Gives back the map names of nodeset on the indiced position.
80.1729 + const std::vector<std::string>& nodeSetMaps(int index) const {
80.1730 + return nodesets[index].items;
80.1731 + }
80.1732 +
80.1733 + /// \brief Gives back how many edgesets are in the file.
80.1734 + ///
80.1735 + /// Gives back how many edgesets are in the file.
80.1736 + int edgeSetNum() const {
80.1737 + return edgesets.size();
80.1738 + }
80.1739 +
80.1740 + /// \brief Gives back the name of edgeset on the indiced position.
80.1741 + ///
80.1742 + /// Gives back the name of edgeset on the indiced position.
80.1743 + std::string edgeSetName(int index) const {
80.1744 + return edgesets[index].name;
80.1745 + }
80.1746 +
80.1747 + /// \brief Gives back the map names of edgeset on the indiced position.
80.1748 + ///
80.1749 + /// Gives back the map names of edgeset on the indiced position.
80.1750 + const std::vector<std::string>& edgeSetMaps(int index) const {
80.1751 + return edgesets[index].items;
80.1752 + }
80.1753 +
80.1754 + /// \brief Gives back how many undirected edgesets are in the file.
80.1755 + ///
80.1756 + /// Gives back how many undirected edgesets are in the file.
80.1757 + int undirEdgeSetNum() const {
80.1758 + return undiredgesets.size();
80.1759 + }
80.1760 +
80.1761 + /// \brief Gives back the name of undirected edgeset on the indiced
80.1762 + /// position.
80.1763 + ///
80.1764 + /// Gives back the name of undirected edgeset on the indiced position.
80.1765 + std::string undirEdgeSetName(int index) const {
80.1766 + return undiredgesets[index].name;
80.1767 + }
80.1768 +
80.1769 + /// \brief Gives back the map names of undirected edgeset on the indiced
80.1770 + /// position.
80.1771 + ///
80.1772 + /// Gives back the map names of undirected edgeset on the indiced position.
80.1773 + const std::vector<std::string>& undirEdgeSetMaps(int index) const {
80.1774 + return undiredgesets[index].items;
80.1775 + }
80.1776 +
80.1777 + /// \brief Gives back how many labeled nodes section are in the file.
80.1778 + ///
80.1779 + /// Gives back how many labeled nodes section are in the file.
80.1780 + int nodesNum() const {
80.1781 + return nodes.size();
80.1782 + }
80.1783 +
80.1784 + /// \brief Gives back the name of labeled nodes section on the indiced
80.1785 + /// position.
80.1786 + ///
80.1787 + /// Gives back the name of labeled nodes section on the indiced position.
80.1788 + std::string nodesName(int index) const {
80.1789 + return nodes[index].name;
80.1790 + }
80.1791 +
80.1792 + /// \brief Gives back the names of the labeled nodes in the indiced
80.1793 + /// section.
80.1794 + ///
80.1795 + /// Gives back the names of the labeled nodes in the indiced section.
80.1796 + const std::vector<std::string>& nodesItems(int index) const {
80.1797 + return nodes[index].items;
80.1798 + }
80.1799 +
80.1800 + /// \brief Gives back how many labeled edges section are in the file.
80.1801 + ///
80.1802 + /// Gives back how many labeled edges section are in the file.
80.1803 + int edgesNum() const {
80.1804 + return edges.size();
80.1805 + }
80.1806 +
80.1807 + /// \brief Gives back the name of labeled edges section on the indiced
80.1808 + /// position.
80.1809 + ///
80.1810 + /// Gives back the name of labeled edges section on the indiced position.
80.1811 + std::string edgesName(int index) const {
80.1812 + return edges[index].name;
80.1813 + }
80.1814 +
80.1815 + /// \brief Gives back the names of the labeled edges in the indiced
80.1816 + /// section.
80.1817 + ///
80.1818 + /// Gives back the names of the labeled edges in the indiced section.
80.1819 + const std::vector<std::string>& edgesItems(int index) const {
80.1820 + return edges[index].items;
80.1821 + }
80.1822 +
80.1823 + /// \brief Gives back how many labeled undirected edges section are
80.1824 + /// in the file.
80.1825 + ///
80.1826 + /// Gives back how many labeled undirected edges section are in the file.
80.1827 + int undirEdgesNum() const {
80.1828 + return undiredges.size();
80.1829 + }
80.1830 +
80.1831 + /// \brief Gives back the name of labeled undirected edges section
80.1832 + /// on the indiced position.
80.1833 + ///
80.1834 + /// Gives back the name of labeled undirected edges section on the
80.1835 + /// indiced position.
80.1836 + std::string undirEdgesName(int index) const {
80.1837 + return undiredges[index].name;
80.1838 + }
80.1839 +
80.1840 + /// \brief Gives back the names of the labeled undirected edges in
80.1841 + /// the indiced section.
80.1842 + ///
80.1843 + /// Gives back the names of the labeled undirected edges in the
80.1844 + /// indiced section.
80.1845 + const std::vector<std::string>& undirEdgesItems(int index) const {
80.1846 + return undiredges[index].items;
80.1847 + }
80.1848 +
80.1849 +
80.1850 + /// \brief Gives back how many attributes section are in the file.
80.1851 + ///
80.1852 + /// Gives back how many attributes section are in the file.
80.1853 + int attributesNum() const {
80.1854 + return attributes.size();
80.1855 + }
80.1856 +
80.1857 + /// \brief Gives back the name of attributes section on the indiced
80.1858 + /// position.
80.1859 + ///
80.1860 + /// Gives back the name of attributes section on the indiced position.
80.1861 + std::string attributesName(int index) const {
80.1862 + return attributes[index].name;
80.1863 + }
80.1864 +
80.1865 + /// \brief Gives back the names of the attributes in the indiced section.
80.1866 + ///
80.1867 + /// Gives back the names of the attributes in the indiced section.
80.1868 + const std::vector<std::string>& attributesItems(int index) const {
80.1869 + return attributes[index].items;
80.1870 + }
80.1871 +
80.1872 + const std::vector<std::string>& otherSections() const {
80.1873 + return sections;
80.1874 + }
80.1875 +
80.1876 + protected:
80.1877 +
80.1878 + /// \brief Gives back true when the SectionReader can process
80.1879 + /// the section with the given header line.
80.1880 + ///
80.1881 + /// It gives back true when the section is common section.
80.1882 + bool header(const std::string& line) {
80.1883 + std::istringstream ls(line);
80.1884 + std::string command, name;
80.1885 + ls >> command >> name;
80.1886 + if (command == "@nodeset") {
80.1887 + current = command;
80.1888 + nodesets.push_back(SectionInfo(name));
80.1889 + } else if (command == "@edgeset") {
80.1890 + current = command;
80.1891 + edgesets.push_back(SectionInfo(name));
80.1892 + } else if (command == "@undiredgeset") {
80.1893 + current = command;
80.1894 + undiredgesets.push_back(SectionInfo(name));
80.1895 + } else if (command == "@nodes") {
80.1896 + current = command;
80.1897 + nodes.push_back(SectionInfo(name));
80.1898 + } else if (command == "@edges") {
80.1899 + current = command;
80.1900 + edges.push_back(SectionInfo(name));
80.1901 + } else if (command == "@undiredges") {
80.1902 + current = command;
80.1903 + undiredges.push_back(SectionInfo(name));
80.1904 + } else if (command == "@attributes") {
80.1905 + current = command;
80.1906 + attributes.push_back(SectionInfo(name));
80.1907 + } else {
80.1908 + sections.push_back(line);
80.1909 + return false;
80.1910 + }
80.1911 + return true;
80.1912 + }
80.1913 +
80.1914 + /// \brief Retrieve the items from various sections.
80.1915 + ///
80.1916 + /// Retrieve the items from various sections.
80.1917 + void read(std::istream& is) {
80.1918 + if (current == "@nodeset") {
80.1919 + readMapNames(is, nodesets.back().items);
80.1920 + } else if (current == "@edgeset") {
80.1921 + readMapNames(is, edgesets.back().items);
80.1922 + } else if (current == "@undiredgeset") {
80.1923 + readMapNames(is, undiredgesets.back().items);
80.1924 + } else if (current == "@nodes") {
80.1925 + readItemNames(is, nodes.back().items);
80.1926 + } else if (current == "@edges") {
80.1927 + readItemNames(is, edges.back().items);
80.1928 + } else if (current == "@undiredges") {
80.1929 + readItemNames(is, undiredges.back().items);
80.1930 + } else if (current == "@attributes") {
80.1931 + readItemNames(is, attributes.back().items);
80.1932 + }
80.1933 + }
80.1934 +
80.1935 + private:
80.1936 +
80.1937 + void readMapNames(std::istream& is, std::vector<std::string>& maps) {
80.1938 + std::string line, id;
80.1939 + std::getline(is, line);
80.1940 + std::istringstream ls(line);
80.1941 + while (ls >> id) {
80.1942 + maps.push_back(id);
80.1943 + }
80.1944 + while (getline(is, line));
80.1945 + }
80.1946 +
80.1947 + void readItemNames(std::istream& is, std::vector<std::string>& maps) {
80.1948 + std::string line, id;
80.1949 + while (std::getline(is, line)) {
80.1950 + std::istringstream ls(line);
80.1951 + ls >> id;
80.1952 + maps.push_back(id);
80.1953 + }
80.1954 + }
80.1955 +
80.1956 + struct SectionInfo {
80.1957 + std::string name;
80.1958 + std::vector<std::string> items;
80.1959 +
80.1960 + SectionInfo(const std::string& _name) : name(_name) {}
80.1961 + };
80.1962 +
80.1963 + std::vector<SectionInfo> nodesets;
80.1964 + std::vector<SectionInfo> edgesets;
80.1965 + std::vector<SectionInfo> undiredgesets;
80.1966 +
80.1967 + std::vector<SectionInfo> nodes;
80.1968 + std::vector<SectionInfo> edges;
80.1969 + std::vector<SectionInfo> undiredges;
80.1970 +
80.1971 + std::vector<SectionInfo> attributes;
80.1972 +
80.1973 + std::vector<std::string> sections;
80.1974 +
80.1975 + std::string current;
80.1976 +
80.1977 + };
80.1978 +
80.1979 +}
80.1980 +#endif
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
81.2 +++ b/lemon/lemon_writer.h Mon May 23 04:48:14 2005 +0000
81.3 @@ -0,0 +1,1129 @@
81.4 +/* -*- C++ -*-
81.5 + * lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
81.6 + *
81.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
81.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
81.9 + *
81.10 + * Permission to use, modify and distribute this software is granted
81.11 + * provided that this copyright notice appears in all copies. For
81.12 + * precise terms see the accompanying LICENSE file.
81.13 + *
81.14 + * This software is provided "AS IS" with no warranty of any kind,
81.15 + * express or implied, and with no claim as to its suitability for any
81.16 + * purpose.
81.17 + *
81.18 + */
81.19 +
81.20 +///\ingroup io_group
81.21 +///\file
81.22 +///\brief Lemon Format writer.
81.23 +
81.24 +#ifndef LEMON_LEMON_WRITER_H
81.25 +#define LEMON_LEMON_WRITER_H
81.26 +
81.27 +#include <iostream>
81.28 +#include <fstream>
81.29 +#include <string>
81.30 +#include <vector>
81.31 +#include <algorithm>
81.32 +#include <map>
81.33 +#include <memory>
81.34 +
81.35 +#include <lemon/error.h>
81.36 +#include <lemon/invalid.h>
81.37 +#include <lemon/graph_utils.h>
81.38 +#include <lemon/bits/item_writer.h>
81.39 +#include <lemon/utility.h>
81.40 +#include <lemon/maps.h>
81.41 +
81.42 +
81.43 +namespace lemon {
81.44 +
81.45 + /// \ingroup io_group
81.46 + /// \brief Lemon Format writer class.
81.47 + ///
81.48 + /// The Lemon Format contains several sections. We do not want to
81.49 + /// determine what sections are in a lemon file we give only a framework
81.50 + /// to write a section oriented format.
81.51 + ///
81.52 + /// In the Lemon Format each section starts with a line contains a \c \@
81.53 + /// character on the first not white space position. This line is the
81.54 + /// header line of the section. Each next lines belong to this section
81.55 + /// while it does not starts with \c \@ character. This line can start a
81.56 + /// new section or if it can close the file with the \c \@end line.
81.57 + /// The file format ignore the empty lines and it may contain comments
81.58 + /// started with a \c # character to the end of the line.
81.59 + ///
81.60 + /// The framework provides an abstract LemonWriter::SectionWriter class
81.61 + /// what defines the interface of a SectionWriter. The SectionWriter
81.62 + /// has the \c header() member function what gives back the header of the
81.63 + /// section. After that it will be called the \c write() member which
81.64 + /// should write the content of the section.
81.65 + ///
81.66 + /// \relates GraphWriter
81.67 + /// \relates NodeSetWriter
81.68 + /// \relates EdgeSetWriter
81.69 + /// \relates NodesWriter
81.70 + /// \relates EdgesWriter
81.71 + /// \relates AttributeWriter
81.72 + class LemonWriter {
81.73 + public:
81.74 +
81.75 + /// \brief Abstract base class for writing a section.
81.76 + ///
81.77 + /// This class has an \c header() member function what gives back
81.78 + /// the header line of the section. The \c write() member should
81.79 + /// write the content of the section to the stream.
81.80 + class SectionWriter {
81.81 + friend class LemonWriter;
81.82 + protected:
81.83 + /// \brief Constructor for SectionWriter.
81.84 + ///
81.85 + /// Constructor for SectionWriter. It attach this writer to
81.86 + /// the given LemonWriter.
81.87 + SectionWriter(LemonWriter& writer) {
81.88 + writer.attach(*this);
81.89 + }
81.90 +
81.91 + /// \brief The header of section.
81.92 + ///
81.93 + /// It gives back the header of the section.
81.94 + virtual std::string header() = 0;
81.95 +
81.96 + /// \brief Writer function of the section.
81.97 + ///
81.98 + /// Write the content of the section.
81.99 + virtual void write(std::ostream& os) = 0;
81.100 + };
81.101 +
81.102 + /// \brief Constructor for LemonWriter.
81.103 + ///
81.104 + /// Constructor for LemonWriter which writes to the given stream.
81.105 + LemonWriter(std::ostream& _os)
81.106 + : os(&_os), own_os(false) {}
81.107 +
81.108 + /// \brief Constructor for LemonWriter.
81.109 + ///
81.110 + /// Constructor for LemonWriter which writes to the given file.
81.111 + LemonWriter(const std::string& filename)
81.112 + : os(0), own_os(true) {
81.113 + os = new std::ofstream(filename.c_str());
81.114 + }
81.115 +
81.116 + /// \brief Desctructor for LemonWriter.
81.117 + ///
81.118 + /// Desctructor for LemonWriter.
81.119 + ~LemonWriter() {
81.120 + if (own_os) {
81.121 + delete os;
81.122 + }
81.123 + }
81.124 +
81.125 + private:
81.126 + LemonWriter(const LemonWriter&);
81.127 + void operator=(const LemonWriter&);
81.128 +
81.129 + void attach(SectionWriter& writer) {
81.130 + writers.push_back(&writer);
81.131 + }
81.132 +
81.133 + public:
81.134 +
81.135 + /// \brief Executes the LemonWriter.
81.136 + ///
81.137 + /// It executes the LemonWriter.
81.138 + void run() {
81.139 + SectionWriters::iterator it;
81.140 + for (it = writers.begin(); it != writers.end(); ++it) {
81.141 + *os << (*it)->header() << std::endl;
81.142 + (*it)->write(*os);
81.143 + }
81.144 + *os << "@end" << std::endl;
81.145 + }
81.146 +
81.147 +
81.148 + private:
81.149 +
81.150 + std::ostream* os;
81.151 + bool own_os;
81.152 +
81.153 + typedef std::vector<SectionWriter*> SectionWriters;
81.154 + SectionWriters writers;
81.155 +
81.156 + };
81.157 +
81.158 + /// \brief Helper class for implementing the common SectionWriters.
81.159 + ///
81.160 + /// Helper class for implementing the common SectionWriters.
81.161 + class CommonSectionWriterBase : public LemonWriter::SectionWriter {
81.162 + typedef LemonWriter::SectionWriter Parent;
81.163 + protected:
81.164 +
81.165 + /// \brief Constructor for CommonSectionWriterBase.
81.166 + ///
81.167 + /// Constructor for CommonSectionWriterBase. It attach this writer to
81.168 + /// the given LemonWriter.
81.169 + CommonSectionWriterBase(LemonWriter& _writer)
81.170 + : Parent(_writer) {}
81.171 +
81.172 + template <typename _Item>
81.173 + class WriterBase {
81.174 + public:
81.175 + typedef _Item Item;
81.176 +
81.177 + virtual ~WriterBase() {}
81.178 +
81.179 + virtual void write(std::ostream& os, const Item& item) = 0;
81.180 + };
81.181 +
81.182 +
81.183 + template <typename _Item, typename _Map, typename _Writer>
81.184 + class MapWriter : public WriterBase<_Item> {
81.185 + public:
81.186 + typedef _Map Map;
81.187 + typedef _Writer Writer;
81.188 + typedef typename Writer::Value Value;
81.189 + typedef _Item Item;
81.190 +
81.191 + typename SmartConstReference<Map>::Type map;
81.192 + Writer writer;
81.193 +
81.194 + MapWriter(const Map& _map, const Writer& _writer)
81.195 + : map(_map), writer(_writer) {}
81.196 +
81.197 + virtual ~MapWriter() {}
81.198 +
81.199 + virtual void write(std::ostream& os, const Item& item) {
81.200 + Value value = map[item];
81.201 + writer.write(os, value);
81.202 + }
81.203 +
81.204 + };
81.205 +
81.206 +
81.207 + class ValueWriterBase {
81.208 + public:
81.209 + virtual void write(std::ostream&) = 0;
81.210 + };
81.211 +
81.212 + template <typename _Value, typename _Writer>
81.213 + class ValueWriter : public ValueWriterBase {
81.214 + public:
81.215 + typedef _Value Value;
81.216 + typedef _Writer Writer;
81.217 +
81.218 + ValueWriter(const Value& _value, const Writer& _writer)
81.219 + : value(_value), writer(_writer) {}
81.220 +
81.221 + virtual void write(std::ostream& os) {
81.222 + writer.write(os, value);
81.223 + }
81.224 + private:
81.225 + const Value& value;
81.226 + Writer writer;
81.227 + };
81.228 +
81.229 +
81.230 + template <typename _Item>
81.231 + class IdWriterBase {
81.232 + public:
81.233 + typedef _Item Item;
81.234 + virtual void write(std::ostream&, const Item&) const = 0;
81.235 + };
81.236 +
81.237 + template <typename _Item, typename _BoxedIdWriter>
81.238 + class IdWriter : public IdWriterBase<_Item> {
81.239 + public:
81.240 + typedef _Item Item;
81.241 + typedef _BoxedIdWriter BoxedIdWriter;
81.242 +
81.243 + const BoxedIdWriter& idWriter;
81.244 +
81.245 + IdWriter(const BoxedIdWriter& _idWriter)
81.246 + : idWriter(_idWriter) {}
81.247 +
81.248 + virtual void write(std::ostream& os, const Item& item) const {
81.249 + idWriter.writeId(os, item);
81.250 + }
81.251 + };
81.252 + };
81.253 +
81.254 + /// \ingroup io_group
81.255 + /// \brief SectionWriter for writing a graph's nodeset.
81.256 + ///
81.257 + /// The lemon format can store multiple graph nodesets with several maps.
81.258 + /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
81.259 + /// \c nodeset_id may be empty.
81.260 + ///
81.261 + /// The first line of the section contains the names of the maps separated
81.262 + /// with white spaces. Each next lines describes a node in the nodeset, and
81.263 + /// contains the mapped values for each map.
81.264 + ///
81.265 + /// If the nodeset contains an \c "id" named map then it will be regarded
81.266 + /// as id map. This map should contain only unique values and when the
81.267 + /// \c writeId() member will be called with a node it will write it's id.
81.268 + /// Otherwise if the \c _forceIdMap constructor parameter is true then
81.269 + /// the id map will be the id in the graph.
81.270 + ///
81.271 + /// \relates LemonWriter
81.272 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
81.273 + class NodeSetWriter : public CommonSectionWriterBase {
81.274 + typedef CommonSectionWriterBase Parent;
81.275 + public:
81.276 +
81.277 + typedef _Graph Graph;
81.278 + typedef _Traits Traits;
81.279 + typedef typename Graph::Node Node;
81.280 +
81.281 + /// \brief Constructor.
81.282 + ///
81.283 + /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
81.284 + /// attach it into the given LemonWriter. If the \c _forceIdMap
81.285 + /// parameter is true then the writer will write own id map when
81.286 + /// the user does not give "id" named map.
81.287 + NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
81.288 + const std::string& _id = std::string(),
81.289 + bool _forceIdMap = true)
81.290 + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
81.291 + graph(_graph), id(_id) {}
81.292 +
81.293 + /// \brief Destructor.
81.294 + ///
81.295 + /// Destructor for NodeSetWriter.
81.296 + virtual ~NodeSetWriter() {
81.297 + typename MapWriters::iterator it;
81.298 + for (it = writers.begin(); it != writers.end(); ++it) {
81.299 + delete it->second;
81.300 + }
81.301 + }
81.302 +
81.303 + private:
81.304 + NodeSetWriter(const NodeSetWriter&);
81.305 + void operator=(const NodeSetWriter&);
81.306 +
81.307 + public:
81.308 +
81.309 + /// \brief Add a new node map writer command for the writer.
81.310 + ///
81.311 + /// Add a new node map writer command for the writer.
81.312 + template <typename Map>
81.313 + NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
81.314 + return writeNodeMap<typename Traits::
81.315 + template Writer<typename Map::Value>, Map>(name, map);
81.316 + }
81.317 +
81.318 + /// \brief Add a new node map writer command for the writer.
81.319 + ///
81.320 + /// Add a new node map writer command for the writer.
81.321 + template <typename Writer, typename Map>
81.322 + NodeSetWriter& writeNodeMap(std::string name, const Map& map,
81.323 + const Writer& writer = Writer()) {
81.324 + writers.push_back(
81.325 + make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
81.326 + return *this;
81.327 + }
81.328 +
81.329 + protected:
81.330 +
81.331 + /// \brief The header of the section.
81.332 + ///
81.333 + /// It gives back the header of the section.
81.334 + virtual std::string header() {
81.335 + return "@nodeset " + id;
81.336 + }
81.337 +
81.338 + /// \brief Writer function of the section.
81.339 + ///
81.340 + /// Write the content of the section.
81.341 + virtual void write(std::ostream& os) {
81.342 + for (int i = 0; i < (int)writers.size(); ++i) {
81.343 + if (writers[i].first == "id") {
81.344 + idMap = writers[i].second;
81.345 + forceIdMap = false;
81.346 + break;
81.347 + }
81.348 + }
81.349 + if (forceIdMap) {
81.350 + os << "id\t";
81.351 + }
81.352 + for (int i = 0; i < (int)writers.size(); ++i) {
81.353 + os << writers[i].first << '\t';
81.354 + }
81.355 + os << std::endl;
81.356 + for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
81.357 + if (forceIdMap) {
81.358 + os << graph.id(it) << '\t';
81.359 + }
81.360 + for (int i = 0; i < (int)writers.size(); ++i) {
81.361 + writers[i].second->write(os, it);
81.362 + os << '\t';
81.363 + }
81.364 + os << std::endl;
81.365 + }
81.366 + }
81.367 +
81.368 + public:
81.369 +
81.370 + /// \brief Returns true if the nodeset can write the ids of the nodes.
81.371 + ///
81.372 + /// Returns true if the nodeset can write the ids of the nodes.
81.373 + /// It is possible only if an "id" named map was written or the
81.374 + /// \c _forceIdMap constructor parameter was true.
81.375 + bool isIdWriter() const {
81.376 + return idMap != 0 || forceIdMap;
81.377 + }
81.378 +
81.379 + /// \brief Write the id of the given node.
81.380 + ///
81.381 + /// It writes the id of the given node. If there was written an "id"
81.382 + /// named map then it will write the map value belongs to the node.
81.383 + /// Otherwise if the \c forceId parameter was true it will write
81.384 + /// its id in the graph.
81.385 + void writeId(std::ostream& os, const Node& item) const {
81.386 + if (forceIdMap) {
81.387 + os << graph.id(item);
81.388 + } else {
81.389 + idMap->write(os, item);
81.390 + }
81.391 + }
81.392 +
81.393 + private:
81.394 +
81.395 + typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
81.396 + MapWriters writers;
81.397 +
81.398 + WriterBase<Node>* idMap;
81.399 + bool forceIdMap;
81.400 +
81.401 + typename SmartConstReference<Graph>::Type graph;
81.402 + std::string id;
81.403 +
81.404 + };
81.405 +
81.406 + /// \ingroup io_group
81.407 + /// \brief SectionWriter for writing a graph's edgesets.
81.408 + ///
81.409 + /// The lemon format can store multiple graph edgesets with several maps.
81.410 + /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
81.411 + /// \c edgeset_id may be empty.
81.412 + ///
81.413 + /// The first line of the section contains the names of the maps separated
81.414 + /// with white spaces. Each next lines describes a edge in the edgeset. The
81.415 + /// line contains the source and the target nodes' id and the mapped
81.416 + /// values for each map.
81.417 + ///
81.418 + /// If the edgeset contains an \c "id" named map then it will be regarded
81.419 + /// as id map. This map should contain only unique values and when the
81.420 + /// \c writeId() member will be called with an edge it will write it's id.
81.421 + /// Otherwise if the \c _forceIdMap constructor parameter is true then
81.422 + /// the id map will be the id in the graph.
81.423 + ///
81.424 + /// The edgeset writer needs a node id writer to identify which nodes
81.425 + /// have to be connected. If a NodeSetWriter can write the nodes' id,
81.426 + /// it will be able to use with this class.
81.427 + ///
81.428 + /// \relates LemonWriter
81.429 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
81.430 + class EdgeSetWriter : public CommonSectionWriterBase {
81.431 + typedef CommonSectionWriterBase Parent;
81.432 + public:
81.433 +
81.434 + typedef _Graph Graph;
81.435 + typedef _Traits Traits;
81.436 + typedef typename Graph::Node Node;
81.437 + typedef typename Graph::Edge Edge;
81.438 +
81.439 + /// \brief Constructor.
81.440 + ///
81.441 + /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
81.442 + /// attach it into the given LemonWriter. It will write node ids by
81.443 + /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
81.444 + /// then the writer will write own id map if the user does not give
81.445 + /// "id" named map.
81.446 + template <typename NodeIdWriter>
81.447 + EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
81.448 + const NodeIdWriter& _nodeIdWriter,
81.449 + const std::string& _id = std::string(),
81.450 + bool _forceIdMap = true)
81.451 + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
81.452 + graph(_graph), id(_id),
81.453 + nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
81.454 +
81.455 + /// \brief Destructor.
81.456 + ///
81.457 + /// Destructor for EdgeSetWriter.
81.458 + virtual ~EdgeSetWriter() {
81.459 + typename MapWriters::iterator it;
81.460 + for (it = writers.begin(); it != writers.end(); ++it) {
81.461 + delete it->second;
81.462 + }
81.463 + }
81.464 +
81.465 + private:
81.466 + EdgeSetWriter(const EdgeSetWriter&);
81.467 + void operator=(const EdgeSetWriter&);
81.468 +
81.469 + public:
81.470 +
81.471 + /// \brief Add a new edge map writer command for the writer.
81.472 + ///
81.473 + /// Add a new edge map writer command for the writer.
81.474 + template <typename Map>
81.475 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
81.476 + return writeEdgeMap<typename Traits::
81.477 + template Writer<typename Map::Value>, Map>(name, map);
81.478 + }
81.479 +
81.480 + /// \brief Add a new edge map writer command for the writer.
81.481 + ///
81.482 + /// Add a new edge map writer command for the writer.
81.483 + template <typename Writer, typename Map>
81.484 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
81.485 + const Writer& writer = Writer()) {
81.486 + writers.push_back(
81.487 + make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
81.488 + return *this;
81.489 + }
81.490 +
81.491 + protected:
81.492 +
81.493 + /// \brief The header of the section.
81.494 + ///
81.495 + /// It gives back the header of the section.
81.496 + virtual std::string header() {
81.497 + return "@edgeset " + id;
81.498 + }
81.499 +
81.500 + /// \brief Writer function of the section.
81.501 + ///
81.502 + /// Write the content of the section.
81.503 + virtual void write(std::ostream& os) {
81.504 + for (int i = 0; i < (int)writers.size(); ++i) {
81.505 + if (writers[i].first == "id") {
81.506 + idMap = writers[i].second;
81.507 + forceIdMap = false;
81.508 + break;
81.509 + }
81.510 + }
81.511 + os << "\t\t";
81.512 + if (forceIdMap) {
81.513 + os << "id\t";
81.514 + }
81.515 + for (int i = 0; i < (int)writers.size(); ++i) {
81.516 + os << writers[i].first << '\t';
81.517 + }
81.518 + os << std::endl;
81.519 + for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
81.520 + nodeIdWriter->write(os, graph.source(it));
81.521 + os << '\t';
81.522 + nodeIdWriter->write(os, graph.target(it));
81.523 + os << '\t';
81.524 + if (forceIdMap) {
81.525 + os << graph.id(it) << '\t';
81.526 + }
81.527 + for (int i = 0; i < (int)writers.size(); ++i) {
81.528 + writers[i].second->write(os, it);
81.529 + os << '\t';
81.530 + }
81.531 + os << std::endl;
81.532 + }
81.533 + }
81.534 +
81.535 + public:
81.536 +
81.537 + /// \brief Returns true if the edgeset can write the ids of the edges.
81.538 + ///
81.539 + /// Returns true if the edgeset can write the ids of the edges.
81.540 + /// It is possible only if an "id" named map was written or the
81.541 + /// \c _forceIdMap constructor parameter was true.
81.542 + bool isIdWriter() const {
81.543 + return forceIdMap || idMap != 0;
81.544 + }
81.545 +
81.546 + /// \brief Write the id of the given edge.
81.547 + ///
81.548 + /// It writes the id of the given edge. If there was written an "id"
81.549 + /// named map then it will write the map value belongs to the edge.
81.550 + /// Otherwise if the \c forceId parameter was true it will write
81.551 + /// its id in the graph.
81.552 + void writeId(std::ostream& os, const Edge& item) const {
81.553 + if (forceIdMap) {
81.554 + os << graph.id(item);
81.555 + } else {
81.556 + idMap->write(os, item);
81.557 + }
81.558 + }
81.559 +
81.560 + private:
81.561 +
81.562 + typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
81.563 + MapWriters writers;
81.564 +
81.565 + WriterBase<Edge>* idMap;
81.566 + bool forceIdMap;
81.567 +
81.568 + typename SmartConstReference<Graph>::Type graph;
81.569 + std::string id;
81.570 +
81.571 + std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
81.572 + };
81.573 +
81.574 + /// \ingroup io_group
81.575 + /// \brief SectionWriter for writing a undirected edgeset.
81.576 + ///
81.577 + /// The lemon format can store multiple undirected edgesets with several
81.578 + /// maps. The undirected edgeset section's header line is \c \@undiredgeset
81.579 + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
81.580 + ///
81.581 + /// The first line of the section contains the names of the maps separated
81.582 + /// with white spaces. Each next lines describes an undirected edge in the
81.583 + /// edgeset. The line contains the two connected nodes' id and the mapped
81.584 + /// values for each undirected map.
81.585 + ///
81.586 + /// The section can handle the directed as a syntactical sugar. Two
81.587 + /// undirected edge map describes one directed edge map. This two maps
81.588 + /// are the forward map and the backward map and the names of this map
81.589 + /// is near the same just with a prefix \c '+' or \c '-' character
81.590 + /// difference.
81.591 + ///
81.592 + /// If the edgeset contains an \c "id" named map then it will be regarded
81.593 + /// as id map. This map should contain only unique values and when the
81.594 + /// \c writeId() member will be called with an undirected edge it will
81.595 + /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
81.596 + /// is true then the id map will be the id in the graph.
81.597 + ///
81.598 + /// The undirected edgeset writer needs a node id writer to identify
81.599 + /// which nodes have to be connected. If a NodeSetWriter can write the
81.600 + /// nodes' id, it will be able to use with this class.
81.601 + ///
81.602 + /// \relates LemonWriter
81.603 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
81.604 + class UndirEdgeSetWriter : public CommonSectionWriterBase {
81.605 + typedef CommonSectionWriterBase Parent;
81.606 + public:
81.607 +
81.608 + typedef _Graph Graph;
81.609 + typedef _Traits Traits;
81.610 + typedef typename Graph::Node Node;
81.611 + typedef typename Graph::Edge Edge;
81.612 + typedef typename Graph::UndirEdge UndirEdge;
81.613 +
81.614 + /// \brief Constructor.
81.615 + ///
81.616 + /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
81.617 + /// and attach it into the given LemonWriter. It will write node ids by
81.618 + /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
81.619 + /// then the writer will write own id map if the user does not give
81.620 + /// "id" named map.
81.621 + template <typename NodeIdWriter>
81.622 + UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
81.623 + const NodeIdWriter& _nodeIdWriter,
81.624 + const std::string& _id = std::string(),
81.625 + bool _forceIdMap = true)
81.626 + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
81.627 + graph(_graph), id(_id),
81.628 + nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
81.629 +
81.630 + /// \brief Destructor.
81.631 + ///
81.632 + /// Destructor for UndirEdgeSetWriter.
81.633 + virtual ~UndirEdgeSetWriter() {
81.634 + typename MapWriters::iterator it;
81.635 + for (it = writers.begin(); it != writers.end(); ++it) {
81.636 + delete it->second;
81.637 + }
81.638 + }
81.639 +
81.640 + private:
81.641 + UndirEdgeSetWriter(const UndirEdgeSetWriter&);
81.642 + void operator=(const UndirEdgeSetWriter&);
81.643 +
81.644 + public:
81.645 +
81.646 + /// \brief Add a new undirected edge map writer command for the writer.
81.647 + ///
81.648 + /// Add a new undirected map writer command for the writer.
81.649 + template <typename Map>
81.650 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
81.651 + return writeUndirEdgeMap<typename Traits::
81.652 + template Writer<typename Map::Value>, Map>(name, map);
81.653 + }
81.654 +
81.655 + /// \brief Add a new undirected map writer command for the writer.
81.656 + ///
81.657 + /// Add a new undirected map writer command for the writer.
81.658 + template <typename Writer, typename Map>
81.659 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
81.660 + const Writer& writer = Writer()) {
81.661 + writers.push_back(
81.662 + make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
81.663 + return *this;
81.664 + }
81.665 +
81.666 + /// \brief Add a new directed edge map writer command for the writer.
81.667 + ///
81.668 + /// Add a new directed map writer command for the writer.
81.669 + template <typename Map>
81.670 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
81.671 + writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
81.672 + writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
81.673 + return *this;
81.674 + }
81.675 +
81.676 + /// \brief Add a new directed map writer command for the writer.
81.677 + ///
81.678 + /// Add a new directed map writer command for the writer.
81.679 + template <typename Writer, typename Map>
81.680 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
81.681 + const Writer& writer = Writer()) {
81.682 + writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
81.683 + writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
81.684 + return *this;
81.685 + }
81.686 +
81.687 + protected:
81.688 +
81.689 + /// \brief The header of the section.
81.690 + ///
81.691 + /// It gives back the header of the section.
81.692 + virtual std::string header() {
81.693 + return "@undiredgeset " + id;
81.694 + }
81.695 +
81.696 + /// \brief Writer function of the section.
81.697 + ///
81.698 + /// Write the content of the section.
81.699 + virtual void write(std::ostream& os) {
81.700 + for (int i = 0; i < (int)writers.size(); ++i) {
81.701 + if (writers[i].first == "id") {
81.702 + idMap = writers[i].second;
81.703 + forceIdMap = false;
81.704 + break;
81.705 + }
81.706 + }
81.707 + os << "\t\t";
81.708 + if (forceIdMap) {
81.709 + os << "id\t";
81.710 + }
81.711 + for (int i = 0; i < (int)writers.size(); ++i) {
81.712 + os << writers[i].first << '\t';
81.713 + }
81.714 + os << std::endl;
81.715 + for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
81.716 + nodeIdWriter->write(os, graph.source(it));
81.717 + os << '\t';
81.718 + nodeIdWriter->write(os, graph.target(it));
81.719 + os << '\t';
81.720 + if (forceIdMap) {
81.721 + os << graph.id(it) << '\t';
81.722 + }
81.723 + for (int i = 0; i < (int)writers.size(); ++i) {
81.724 + writers[i].second->write(os, it);
81.725 + os << '\t';
81.726 + }
81.727 + os << std::endl;
81.728 + }
81.729 + }
81.730 +
81.731 + public:
81.732 +
81.733 + /// \brief Returns true if the undirected edgeset can write the ids of
81.734 + /// the edges.
81.735 + ///
81.736 + /// Returns true if the undirected edgeset can write the ids of the
81.737 + /// undirected edges. It is possible only if an "id" named map was
81.738 + /// written or the \c _forceIdMap constructor parameter was true.
81.739 + bool isIdWriter() const {
81.740 + return forceIdMap || idMap != 0;
81.741 + }
81.742 +
81.743 + /// \brief Write the id of the given undirected edge.
81.744 + ///
81.745 + /// It writes the id of the given undirected edge. If there was written
81.746 + /// an "id" named map then it will write the map value belongs to the
81.747 + /// undirected edge. Otherwise if the \c forceId parameter was true it
81.748 + /// will write its id in the graph.
81.749 + void writeId(std::ostream& os, const UndirEdge& item) const {
81.750 + if (forceIdMap) {
81.751 + os << graph.id(item);
81.752 + } else {
81.753 + idMap->write(os, item);
81.754 + }
81.755 + }
81.756 +
81.757 + /// \brief Write the id of the given edge.
81.758 + ///
81.759 + /// It writes the id of the given edge. If there was written
81.760 + /// an "id" named map then it will write the map value belongs to the
81.761 + /// edge. Otherwise if the \c forceId parameter was true it
81.762 + /// will write its id in the graph. If the edge is forward map
81.763 + /// then its prefix character is \c '+' elsewhere \c '-'.
81.764 + void writeId(std::ostream& os, const Edge& item) const {
81.765 + if (graph.forward(item)) {
81.766 + os << "+ ";
81.767 + } else {
81.768 + os << "- ";
81.769 + }
81.770 + if (forceIdMap) {
81.771 + os << graph.id(item);
81.772 + } else {
81.773 + idMap->write(os, item);
81.774 + }
81.775 + }
81.776 +
81.777 + private:
81.778 +
81.779 + typedef std::vector<std::pair<std::string,
81.780 + WriterBase<UndirEdge>*> > MapWriters;
81.781 + MapWriters writers;
81.782 +
81.783 + WriterBase<UndirEdge>* idMap;
81.784 + bool forceIdMap;
81.785 +
81.786 + typename SmartConstReference<Graph>::Type graph;
81.787 + std::string id;
81.788 +
81.789 + std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
81.790 + };
81.791 +
81.792 + /// \ingroup io_group
81.793 + /// \brief SectionWriter for writing labeled nodes.
81.794 + ///
81.795 + /// The nodes section's header line is \c \@nodes \c nodes_id, but the
81.796 + /// \c nodes_id may be empty.
81.797 + ///
81.798 + /// Each line in the section contains the label of the node and
81.799 + /// then the node id.
81.800 + ///
81.801 + /// \relates LemonWriter
81.802 + template <typename _Graph>
81.803 + class NodeWriter : public CommonSectionWriterBase {
81.804 + typedef CommonSectionWriterBase Parent;
81.805 + typedef _Graph Graph;
81.806 + typedef typename Graph::Node Node;
81.807 + public:
81.808 +
81.809 + /// \brief Constructor.
81.810 + ///
81.811 + /// Constructor for NodeWriter. It creates the NodeWriter and
81.812 + /// attach it into the given LemonWriter. The given \c _IdWriter
81.813 + /// will write the nodes' id what can be a nodeset writer.
81.814 + template <typename _IdWriter>
81.815 + NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
81.816 + const std::string& _id = std::string())
81.817 + : Parent(_writer), id(_id),
81.818 + idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
81.819 +
81.820 + /// \brief Destructor.
81.821 + ///
81.822 + /// Destructor for NodeWriter.
81.823 + virtual ~NodeWriter() {}
81.824 +
81.825 + private:
81.826 + NodeWriter(const NodeWriter&);
81.827 + void operator=(const NodeWriter&);
81.828 +
81.829 + public:
81.830 +
81.831 + /// \brief Add a node writer command for the NodeWriter.
81.832 + ///
81.833 + /// Add a node writer command for the NodeWriter.
81.834 + void writeNode(const std::string& name, const Node& item) {
81.835 + writers.push_back(make_pair(name, &item));
81.836 + }
81.837 +
81.838 + protected:
81.839 +
81.840 + /// \brief Header checking function.
81.841 + ///
81.842 + /// It gives back true when the header line start with \c \@nodes,
81.843 + /// and the header line's id and the writer's id are the same.
81.844 + virtual std::string header() {
81.845 + return "@nodes " + id;
81.846 + }
81.847 +
81.848 + /// \brief Writer function of the section.
81.849 + ///
81.850 + /// Write the content of the section.
81.851 + virtual void write(std::ostream& os) {
81.852 + for (int i = 0; i < (int)writers.size(); ++i) {
81.853 + os << writers[i].first << ' ';
81.854 + idWriter->write(os, *(writers[i].second));
81.855 + os << std::endl;
81.856 + }
81.857 + }
81.858 +
81.859 + private:
81.860 +
81.861 + std::string id;
81.862 +
81.863 + typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
81.864 + NodeWriters writers;
81.865 + std::auto_ptr<IdWriterBase<Node> > idWriter;
81.866 + };
81.867 +
81.868 + /// \ingroup io_group
81.869 + /// \brief SectionWriter for writing labeled edges.
81.870 + ///
81.871 + /// The edges section's header line is \c \@edges \c edges_id, but the
81.872 + /// \c edges_id may be empty.
81.873 + ///
81.874 + /// Each line in the section contains the label of the edge and
81.875 + /// then the edge id.
81.876 + ///
81.877 + /// \relates LemonWriter
81.878 + template <typename _Graph>
81.879 + class EdgeWriter : public CommonSectionWriterBase {
81.880 + typedef CommonSectionWriterBase Parent;
81.881 + typedef _Graph Graph;
81.882 + typedef typename Graph::Edge Edge;
81.883 + public:
81.884 +
81.885 + /// \brief Constructor.
81.886 + ///
81.887 + /// Constructor for EdgeWriter. It creates the EdgeWriter and
81.888 + /// attach it into the given LemonWriter. The given \c _IdWriter
81.889 + /// will write the edges' id what can be a edgeset writer.
81.890 + template <typename _IdWriter>
81.891 + EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
81.892 + const std::string& _id = std::string())
81.893 + : Parent(_writer), id(_id),
81.894 + idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
81.895 +
81.896 + /// \brief Destructor.
81.897 + ///
81.898 + /// Destructor for EdgeWriter.
81.899 + virtual ~EdgeWriter() {}
81.900 + private:
81.901 + EdgeWriter(const EdgeWriter&);
81.902 + void operator=(const EdgeWriter&);
81.903 +
81.904 + public:
81.905 +
81.906 + /// \brief Add an edge writer command for the EdgeWriter.
81.907 + ///
81.908 + /// Add an edge writer command for the EdgeWriter.
81.909 + void writeEdge(const std::string& name, const Edge& item) {
81.910 + writers.push_back(make_pair(name, &item));
81.911 + }
81.912 +
81.913 + protected:
81.914 +
81.915 + /// \brief Header checking function.
81.916 + ///
81.917 + /// It gives back true when the header line start with \c \@edges,
81.918 + /// and the header line's id and the writer's id are the same.
81.919 + virtual std::string header() {
81.920 + return "@edges " + id;
81.921 + }
81.922 +
81.923 + /// \brief Writer function of the section.
81.924 + ///
81.925 + /// Write the content of the section.
81.926 + virtual void write(std::ostream& os) {
81.927 + for (int i = 0; i < (int)writers.size(); ++i) {
81.928 + os << writers[i].first << ' ';
81.929 + idWriter->write(os, *(writers[i].second));
81.930 + os << std::endl;
81.931 + }
81.932 + }
81.933 +
81.934 + private:
81.935 +
81.936 + std::string id;
81.937 +
81.938 + typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
81.939 + EdgeWriters writers;
81.940 +
81.941 + std::auto_ptr<IdWriterBase<Edge> > idWriter;
81.942 + };
81.943 +
81.944 + /// \ingroup io_group
81.945 + /// \brief SectionWriter for writing labeled undirected edges.
81.946 + ///
81.947 + /// The undirected edges section's header line is \c \@undiredges
81.948 + /// \c undiredges_id, but the \c undiredges_id may be empty.
81.949 + ///
81.950 + /// Each line in the section contains the label of the undirected edge and
81.951 + /// then the undirected edge id.
81.952 + ///
81.953 + /// \relates LemonWriter
81.954 + template <typename _Graph>
81.955 + class UndirEdgeWriter : public CommonSectionWriterBase {
81.956 + typedef CommonSectionWriterBase Parent;
81.957 + typedef _Graph Graph;
81.958 + typedef typename Graph::Node Node;
81.959 + typedef typename Graph::Edge Edge;
81.960 + typedef typename Graph::UndirEdge UndirEdge;
81.961 + public:
81.962 +
81.963 + /// \brief Constructor.
81.964 + ///
81.965 + /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
81.966 + /// attach it into the given LemonWriter. The given \c _IdWriter
81.967 + /// will write the undirected edges' id what can be an undirected
81.968 + /// edgeset writer.
81.969 + template <typename _IdWriter>
81.970 + UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
81.971 + const std::string& _id = std::string())
81.972 + : Parent(_writer), id(_id),
81.973 + undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
81.974 + edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
81.975 +
81.976 + /// \brief Destructor.
81.977 + ///
81.978 + /// Destructor for UndirEdgeWriter.
81.979 + virtual ~UndirEdgeWriter() {}
81.980 + private:
81.981 + UndirEdgeWriter(const UndirEdgeWriter&);
81.982 + void operator=(const UndirEdgeWriter&);
81.983 +
81.984 + public:
81.985 +
81.986 + /// \brief Add an edge writer command for the UndirEdgeWriter.
81.987 + ///
81.988 + /// Add an edge writer command for the UndirEdgeWriter.
81.989 + void writeEdge(const std::string& name, const Edge& item) {
81.990 + edgeWriters.push_back(make_pair(name, &item));
81.991 + }
81.992 +
81.993 + /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
81.994 + ///
81.995 + /// Add an undirected edge writer command for the UndirEdgeWriter.
81.996 + void writeUndirEdge(const std::string& name, const UndirEdge& item) {
81.997 + undirEdgeWriters.push_back(make_pair(name, &item));
81.998 + }
81.999 +
81.1000 + protected:
81.1001 +
81.1002 + /// \brief Header checking function.
81.1003 + ///
81.1004 + /// It gives back true when the header line start with \c \@undiredges,
81.1005 + /// and the header line's id and the writer's id are the same.
81.1006 + virtual std::string header() {
81.1007 + return "@undiredges " + id;
81.1008 + }
81.1009 +
81.1010 + /// \brief Writer function of the section.
81.1011 + ///
81.1012 + /// Write the content of the section.
81.1013 + virtual void write(std::ostream& os) {
81.1014 + for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
81.1015 + os << undirEdgeWriters[i].first << ' ';
81.1016 + undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
81.1017 + os << std::endl;
81.1018 + }
81.1019 + for (int i = 0; i < (int)edgeWriters.size(); ++i) {
81.1020 + os << edgeWriters[i].first << ' ';
81.1021 + edgeIdWriter->write(os, *(edgeWriters[i].second));
81.1022 + os << std::endl;
81.1023 + }
81.1024 + }
81.1025 +
81.1026 + private:
81.1027 +
81.1028 + std::string id;
81.1029 +
81.1030 + typedef std::vector<std::pair<std::string,
81.1031 + const UndirEdge*> > UndirEdgeWriters;
81.1032 + UndirEdgeWriters undirEdgeWriters;
81.1033 + std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
81.1034 +
81.1035 + typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
81.1036 + EdgeWriters edgeWriters;
81.1037 + std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
81.1038 +
81.1039 + };
81.1040 +
81.1041 + /// \ingroup io_group
81.1042 + /// \brief SectionWriter for attributes.
81.1043 + ///
81.1044 + /// The lemon format can store multiple attribute set. Each set has
81.1045 + /// the header line \c \@attributes \c attributeset_id, but the
81.1046 + /// attributeset_id may be empty.
81.1047 + ///
81.1048 + /// The attributeset section contains several lines. Each of them starts
81.1049 + /// with the name of attribute and then the value.
81.1050 + ///
81.1051 + /// \relates LemonWriter
81.1052 + template <typename _Traits = DefaultWriterTraits>
81.1053 + class AttributeWriter : public CommonSectionWriterBase {
81.1054 + typedef CommonSectionWriterBase Parent;
81.1055 + typedef _Traits Traits;
81.1056 + public:
81.1057 + /// \brief Constructor.
81.1058 + ///
81.1059 + /// Constructor for AttributeWriter. It creates the AttributeWriter and
81.1060 + /// attach it into the given LemonWriter.
81.1061 + AttributeWriter(LemonWriter& _writer,
81.1062 + const std::string& _id = std::string())
81.1063 + : Parent(_writer), id(_id) {}
81.1064 +
81.1065 + /// \brief Destructor.
81.1066 + ///
81.1067 + /// Destructor for AttributeWriter.
81.1068 + virtual ~AttributeWriter() {
81.1069 + typename Writers::iterator it;
81.1070 + for (it = writers.begin(); it != writers.end(); ++it) {
81.1071 + delete it->second;
81.1072 + }
81.1073 + }
81.1074 +
81.1075 + private:
81.1076 + AttributeWriter(const AttributeWriter&);
81.1077 + void operator=(AttributeWriter&);
81.1078 +
81.1079 + public:
81.1080 + /// \brief Add an attribute writer command for the writer.
81.1081 + ///
81.1082 + /// Add an attribute writer command for the writer.
81.1083 + template <typename Value>
81.1084 + AttributeWriter& writeAttribute(const std::string& id,
81.1085 + const Value& value) {
81.1086 + return
81.1087 + writeAttribute<typename Traits::template Writer<Value> >(id, value);
81.1088 + }
81.1089 +
81.1090 + /// \brief Add an attribute writer command for the writer.
81.1091 + ///
81.1092 + /// Add an attribute writer command for the writer.
81.1093 + template <typename Writer, typename Value>
81.1094 + AttributeWriter& writeAttribute(const std::string& name,
81.1095 + const Value& value,
81.1096 + const Writer& writer = Writer()) {
81.1097 + writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
81.1098 + (value, writer)));
81.1099 + return *this;
81.1100 + }
81.1101 +
81.1102 + protected:
81.1103 +
81.1104 + /// \brief The header of section.
81.1105 + ///
81.1106 + /// It gives back the header of the section.
81.1107 + std::string header() {
81.1108 + return "@attributes " + id;
81.1109 + }
81.1110 +
81.1111 + /// \brief Writer function of the section.
81.1112 + ///
81.1113 + /// Write the content of the section.
81.1114 + void write(std::ostream& os) {
81.1115 + typename Writers::iterator it;
81.1116 + for (it = writers.begin(); it != writers.end(); ++it) {
81.1117 + os << it->first << ' ';
81.1118 + it->second->write(os);
81.1119 + os << std::endl;
81.1120 + }
81.1121 + }
81.1122 +
81.1123 + private:
81.1124 + std::string id;
81.1125 +
81.1126 + typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;
81.1127 + Writers writers;
81.1128 + };
81.1129 +
81.1130 +
81.1131 +}
81.1132 +#endif
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
82.2 +++ b/lemon/list_graph.h Mon May 23 04:48:14 2005 +0000
82.3 @@ -0,0 +1,565 @@
82.4 +/* -*- C++ -*-
82.5 + * lemon/list_graph.h - Part of LEMON, a generic C++ optimization library
82.6 + *
82.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
82.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
82.9 + *
82.10 + * Permission to use, modify and distribute this software is granted
82.11 + * provided that this copyright notice appears in all copies. For
82.12 + * precise terms see the accompanying LICENSE file.
82.13 + *
82.14 + * This software is provided "AS IS" with no warranty of any kind,
82.15 + * express or implied, and with no claim as to its suitability for any
82.16 + * purpose.
82.17 + *
82.18 + */
82.19 +
82.20 +#ifndef LEMON_LIST_GRAPH_H
82.21 +#define LEMON_LIST_GRAPH_H
82.22 +
82.23 +///\ingroup graphs
82.24 +///\file
82.25 +///\brief ListGraph, SymListGraph classes.
82.26 +
82.27 +#include <lemon/bits/erasable_graph_extender.h>
82.28 +#include <lemon/bits/clearable_graph_extender.h>
82.29 +#include <lemon/bits/extendable_graph_extender.h>
82.30 +#include <lemon/bits/iterable_graph_extender.h>
82.31 +#include <lemon/bits/alteration_notifier.h>
82.32 +#include <lemon/bits/default_map.h>
82.33 +
82.34 +#include <lemon/bits/undir_graph_extender.h>
82.35 +
82.36 +#include <list>
82.37 +
82.38 +namespace lemon {
82.39 +
82.40 + class ListGraphBase {
82.41 +
82.42 + protected:
82.43 + struct NodeT {
82.44 + int first_in,first_out;
82.45 + int prev, next;
82.46 + };
82.47 +
82.48 + struct EdgeT {
82.49 + int target, source;
82.50 + int prev_in, prev_out;
82.51 + int next_in, next_out;
82.52 + };
82.53 +
82.54 + std::vector<NodeT> nodes;
82.55 +
82.56 + int first_node;
82.57 +
82.58 + int first_free_node;
82.59 +
82.60 + std::vector<EdgeT> edges;
82.61 +
82.62 + int first_free_edge;
82.63 +
82.64 + public:
82.65 +
82.66 + typedef ListGraphBase Graph;
82.67 +
82.68 + class Node {
82.69 + friend class ListGraphBase;
82.70 + protected:
82.71 +
82.72 + int id;
82.73 + Node(int pid) { id = pid;}
82.74 +
82.75 + public:
82.76 + Node() {}
82.77 + Node (Invalid) { id = -1; }
82.78 + bool operator==(const Node& node) const {return id == node.id;}
82.79 + bool operator!=(const Node& node) const {return id != node.id;}
82.80 + bool operator<(const Node& node) const {return id < node.id;}
82.81 + };
82.82 +
82.83 + class Edge {
82.84 + friend class ListGraphBase;
82.85 + protected:
82.86 +
82.87 + int id;
82.88 + Edge(int pid) { id = pid;}
82.89 +
82.90 + public:
82.91 + Edge() {}
82.92 + Edge (Invalid) { id = -1; }
82.93 + bool operator==(const Edge& edge) const {return id == edge.id;}
82.94 + bool operator!=(const Edge& edge) const {return id != edge.id;}
82.95 + bool operator<(const Edge& edge) const {return id < edge.id;}
82.96 + };
82.97 +
82.98 +
82.99 +
82.100 + ListGraphBase()
82.101 + : nodes(), first_node(-1),
82.102 + first_free_node(-1), edges(), first_free_edge(-1) {}
82.103 +
82.104 +
82.105 + /// Maximum node ID.
82.106 +
82.107 + /// Maximum node ID.
82.108 + ///\sa id(Node)
82.109 + int maxId(Node = INVALID) const { return nodes.size()-1; }
82.110 +
82.111 + /// Maximum edge ID.
82.112 +
82.113 + /// Maximum edge ID.
82.114 + ///\sa id(Edge)
82.115 + int maxId(Edge = INVALID) const { return edges.size()-1; }
82.116 +
82.117 + Node source(Edge e) const { return edges[e.id].source; }
82.118 + Node target(Edge e) const { return edges[e.id].target; }
82.119 +
82.120 +
82.121 + void first(Node& node) const {
82.122 + node.id = first_node;
82.123 + }
82.124 +
82.125 + void next(Node& node) const {
82.126 + node.id = nodes[node.id].next;
82.127 + }
82.128 +
82.129 +
82.130 + void first(Edge& e) const {
82.131 + int n;
82.132 + for(n = first_node;
82.133 + n!=-1 && nodes[n].first_in == -1;
82.134 + n = nodes[n].next);
82.135 + e.id = (n == -1) ? -1 : nodes[n].first_in;
82.136 + }
82.137 +
82.138 + void next(Edge& edge) const {
82.139 + if (edges[edge.id].next_in != -1) {
82.140 + edge.id = edges[edge.id].next_in;
82.141 + } else {
82.142 + int n;
82.143 + for(n = nodes[edges[edge.id].target].next;
82.144 + n!=-1 && nodes[n].first_in == -1;
82.145 + n = nodes[n].next);
82.146 + edge.id = (n == -1) ? -1 : nodes[n].first_in;
82.147 + }
82.148 + }
82.149 +
82.150 + void firstOut(Edge &e, const Node& v) const {
82.151 + e.id = nodes[v.id].first_out;
82.152 + }
82.153 + void nextOut(Edge &e) const {
82.154 + e.id=edges[e.id].next_out;
82.155 + }
82.156 +
82.157 + void firstIn(Edge &e, const Node& v) const {
82.158 + e.id = nodes[v.id].first_in;
82.159 + }
82.160 + void nextIn(Edge &e) const {
82.161 + e.id=edges[e.id].next_in;
82.162 + }
82.163 +
82.164 +
82.165 + static int id(Node v) { return v.id; }
82.166 + static int id(Edge e) { return e.id; }
82.167 +
82.168 + static Node fromId(int id, Node) { return Node(id);}
82.169 + static Edge fromId(int id, Edge) { return Edge(id);}
82.170 +
82.171 + /// Adds a new node to the graph.
82.172 +
82.173 + /// \warning It adds the new node to the front of the list.
82.174 + /// (i.e. the lastly added node becomes the first.)
82.175 + Node addNode() {
82.176 + int n;
82.177 +
82.178 + if(first_free_node==-1) {
82.179 + n = nodes.size();
82.180 + nodes.push_back(NodeT());
82.181 + } else {
82.182 + n = first_free_node;
82.183 + first_free_node = nodes[n].next;
82.184 + }
82.185 +
82.186 + nodes[n].next = first_node;
82.187 + if(first_node != -1) nodes[first_node].prev = n;
82.188 + first_node = n;
82.189 + nodes[n].prev = -1;
82.190 +
82.191 + nodes[n].first_in = nodes[n].first_out = -1;
82.192 +
82.193 + return Node(n);
82.194 + }
82.195 +
82.196 + Edge addEdge(Node u, Node v) {
82.197 + int n;
82.198 +
82.199 + if (first_free_edge == -1) {
82.200 + n = edges.size();
82.201 + edges.push_back(EdgeT());
82.202 + } else {
82.203 + n = first_free_edge;
82.204 + first_free_edge = edges[n].next_in;
82.205 + }
82.206 +
82.207 + edges[n].source = u.id;
82.208 + edges[n].target = v.id;
82.209 +
82.210 + edges[n].next_out = nodes[u.id].first_out;
82.211 + if(nodes[u.id].first_out != -1) {
82.212 + edges[nodes[u.id].first_out].prev_out = n;
82.213 + }
82.214 +
82.215 + edges[n].next_in = nodes[v.id].first_in;
82.216 + if(nodes[v.id].first_in != -1) {
82.217 + edges[nodes[v.id].first_in].prev_in = n;
82.218 + }
82.219 +
82.220 + edges[n].prev_in = edges[n].prev_out = -1;
82.221 +
82.222 + nodes[u.id].first_out = nodes[v.id].first_in = n;
82.223 +
82.224 + return Edge(n);
82.225 + }
82.226 +
82.227 + void erase(const Node& node) {
82.228 + int n = node.id;
82.229 +
82.230 + if(nodes[n].next != -1) {
82.231 + nodes[nodes[n].next].prev = nodes[n].prev;
82.232 + }
82.233 +
82.234 + if(nodes[n].prev != -1) {
82.235 + nodes[nodes[n].prev].next = nodes[n].next;
82.236 + } else {
82.237 + first_node = nodes[n].next;
82.238 + }
82.239 +
82.240 + nodes[n].next = first_free_node;
82.241 + first_free_node = n;
82.242 +
82.243 + }
82.244 +
82.245 + void erase(const Edge& edge) {
82.246 + int n = edge.id;
82.247 +
82.248 + if(edges[n].next_in!=-1) {
82.249 + edges[edges[n].next_in].prev_in = edges[n].prev_in;
82.250 + }
82.251 +
82.252 + if(edges[n].prev_in!=-1) {
82.253 + edges[edges[n].prev_in].next_in = edges[n].next_in;
82.254 + } else {
82.255 + nodes[edges[n].target].first_in = edges[n].next_in;
82.256 + }
82.257 +
82.258 +
82.259 + if(edges[n].next_out!=-1) {
82.260 + edges[edges[n].next_out].prev_out = edges[n].prev_out;
82.261 + }
82.262 +
82.263 + if(edges[n].prev_out!=-1) {
82.264 + edges[edges[n].prev_out].next_out = edges[n].next_out;
82.265 + } else {
82.266 + nodes[edges[n].source].first_out = edges[n].next_out;
82.267 + }
82.268 +
82.269 + edges[n].next_in = first_free_edge;
82.270 + first_free_edge = n;
82.271 +
82.272 + }
82.273 +
82.274 + void clear() {
82.275 + edges.clear();
82.276 + nodes.clear();
82.277 + first_node = first_free_node = first_free_edge = -1;
82.278 + }
82.279 +
82.280 + protected:
82.281 + void _moveTarget(Edge e, Node n)
82.282 + {
82.283 + if(edges[e.id].next_in != -1)
82.284 + edges[edges[e.id].next_in].prev_in = edges[e.id].prev_in;
82.285 + if(edges[e.id].prev_in != -1)
82.286 + edges[edges[e.id].prev_in].next_in = edges[e.id].next_in;
82.287 + else nodes[edges[e.id].target].first_in = edges[e.id].next_in;
82.288 + edges[e.id].target = n.id;
82.289 + edges[e.id].prev_in = -1;
82.290 + edges[e.id].next_in = nodes[n.id].first_in;
82.291 + nodes[n.id].first_in = e.id;
82.292 + }
82.293 + void _moveSource(Edge e, Node n)
82.294 + {
82.295 + if(edges[e.id].next_out != -1)
82.296 + edges[edges[e.id].next_out].prev_out = edges[e.id].prev_out;
82.297 + if(edges[e.id].prev_out != -1)
82.298 + edges[edges[e.id].prev_out].next_out = edges[e.id].next_out;
82.299 + else nodes[edges[e.id].source].first_out = edges[e.id].next_out;
82.300 + edges[e.id].source = n.id;
82.301 + edges[e.id].prev_out = -1;
82.302 + edges[e.id].next_out = nodes[n.id].first_out;
82.303 + nodes[n.id].first_out = e.id;
82.304 + }
82.305 +
82.306 + };
82.307 +
82.308 + typedef AlterableGraphExtender<ListGraphBase> AlterableListGraphBase;
82.309 + typedef IterableGraphExtender<AlterableListGraphBase> IterableListGraphBase;
82.310 + typedef DefaultMappableGraphExtender<IterableListGraphBase> MappableListGraphBase;
82.311 + typedef ExtendableGraphExtender<MappableListGraphBase> ExtendableListGraphBase;
82.312 + typedef ClearableGraphExtender<ExtendableListGraphBase> ClearableListGraphBase;
82.313 + typedef ErasableGraphExtender<ClearableListGraphBase> ErasableListGraphBase;
82.314 +
82.315 +/// \addtogroup graphs
82.316 +/// @{
82.317 +
82.318 + ///A list graph class.
82.319 +
82.320 + ///This is a simple and fast erasable graph implementation.
82.321 + ///
82.322 + ///It addition that it conforms to the
82.323 + ///\ref concept::ErasableGraph "ErasableGraph" concept,
82.324 + ///it also provides several additional useful extra functionalities.
82.325 + ///\sa concept::ErasableGraph.
82.326 +
82.327 + class ListGraph : public ErasableListGraphBase
82.328 + {
82.329 + public:
82.330 + /// Moves the target of \c e to \c n
82.331 +
82.332 + /// Moves the target of \c e to \c n
82.333 + ///
82.334 + ///\note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
82.335 + ///referencing the moved edge remain
82.336 + ///valid. However <tt>InEdge</tt>'s are invalidated.
82.337 + void moveTarget(Edge e, Node n) { _moveTarget(e,n); }
82.338 + /// Moves the source of \c e to \c n
82.339 +
82.340 + /// Moves the source of \c e to \c n
82.341 + ///
82.342 + ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
82.343 + ///referencing the moved edge remain
82.344 + ///valid. However <tt>OutEdge</tt>'s are invalidated.
82.345 + void moveSource(Edge e, Node n) { _moveSource(e,n); }
82.346 +
82.347 + /// Invert the direction of an edge.
82.348 +
82.349 + ///\note The <tt>Edge</tt>'s
82.350 + ///referencing the moved edge remain
82.351 + ///valid. However <tt>OutEdge</tt>'s and <tt>InEdge</tt>'s are invalidated.
82.352 + void reverseEdge(Edge e) {
82.353 + Node t=target(e);
82.354 + _moveTarget(e,source(e));
82.355 + _moveSource(e,t);
82.356 + }
82.357 +
82.358 + ///Using this it possible to avoid the superfluous memory allocation.
82.359 +
82.360 + ///Using this it possible to avoid the superfluous memory allocation.
82.361 + ///\todo more docs...
82.362 + void reserveEdge(int n) { edges.reserve(n); };
82.363 +
82.364 + ///Contract two nodes.
82.365 +
82.366 + ///This function contracts two nodes.
82.367 + ///
82.368 + ///Node \p b will be removed but instead of deleting
82.369 + ///its neighboring edges, they will be joined to \p a.
82.370 + ///The last parameter \p r controls whether to remove loops. \c true
82.371 + ///means that loops will be removed.
82.372 + ///
82.373 + ///\note The <tt>Edge</tt>s
82.374 + ///referencing a moved edge remain
82.375 + ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
82.376 + ///may be invalidated.
82.377 + void contract(Node a,Node b,bool r=true)
82.378 + {
82.379 + for(OutEdgeIt e(*this,b);e!=INVALID;) {
82.380 + OutEdgeIt f=e;
82.381 + ++f;
82.382 + if(r && target(e)==a) erase(e);
82.383 + else moveSource(e,a);
82.384 + e=f;
82.385 + }
82.386 + for(InEdgeIt e(*this,b);e!=INVALID;) {
82.387 + InEdgeIt f=e;
82.388 + ++f;
82.389 + if(r && source(e)==a) erase(e);
82.390 + else moveTarget(e,a);
82.391 + e=f;
82.392 + }
82.393 + erase(b);
82.394 + }
82.395 +
82.396 + ///Split a node.
82.397 +
82.398 + ///This function splits a node. First a new node is added to the graph,
82.399 + ///then the source of each outgoing edge of \c n is moved to this new node.
82.400 + ///If \c connect is \c true (this is the default value), then a new edge
82.401 + ///from \c n to the newly created node is also added.
82.402 + ///\return The newly created node.
82.403 + ///
82.404 + ///\note The <tt>Edge</tt>s
82.405 + ///referencing a moved edge remain
82.406 + ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
82.407 + ///may be invalidated.
82.408 + ///\warning This functionality cannot be used together with the SnapShot
82.409 + ///feature.
82.410 + ///\todo It could be implemented in a bit faster way.
82.411 + Node split(Node n, bool connect = true)
82.412 + {
82.413 + Node b = addNode();
82.414 + for(OutEdgeIt e(*this,n);e!=INVALID;) {
82.415 + OutEdgeIt f=e;
82.416 + ++f;
82.417 + moveSource(e,b);
82.418 + e=f;
82.419 + }
82.420 + if(connect) addEdge(n,b);
82.421 + return b;
82.422 + }
82.423 +
82.424 + ///Class to make a snapshot of the graph and to restrore to it later.
82.425 +
82.426 + ///Class to make a snapshot of the graph and to restrore to it later.
82.427 + ///
82.428 + ///The newly added nodes and edges can be removed using the
82.429 + ///restore() function.
82.430 + ///
82.431 + ///\warning Edge and node deletions cannot be restored.
82.432 + ///\warning SnapShots cannot be nested.
82.433 + ///\todo \c SnapShot or \c Snapshot?
82.434 + class SnapShot : protected AlterationNotifier<Node>::ObserverBase,
82.435 + protected AlterationNotifier<Edge>::ObserverBase
82.436 + {
82.437 + protected:
82.438 +
82.439 + ListGraph *g;
82.440 + std::list<Node> added_nodes;
82.441 + std::list<Edge> added_edges;
82.442 +
82.443 + bool active;
82.444 + virtual void add(const Node& n) {
82.445 + added_nodes.push_back(n);
82.446 + };
82.447 + ///\bug Exception...
82.448 + ///
82.449 + virtual void erase(const Node&)
82.450 + {
82.451 + exit(1);
82.452 + }
82.453 + virtual void add(const Edge& n) {
82.454 + added_edges.push_back(n);
82.455 + };
82.456 + ///\bug Exception...
82.457 + ///
82.458 + virtual void erase(const Edge&)
82.459 + {
82.460 + exit(1);
82.461 + }
82.462 +
82.463 + void regist(ListGraph &_g) {
82.464 + g=&_g;
82.465 + AlterationNotifier<Node>::ObserverBase::
82.466 + attach(g->getNotifier(Node()));
82.467 + AlterationNotifier<Edge>::ObserverBase::
82.468 + attach(g->getNotifier(Edge()));
82.469 + }
82.470 +
82.471 + void deregist() {
82.472 + AlterationNotifier<Node>::ObserverBase::
82.473 + detach();
82.474 + AlterationNotifier<Edge>::ObserverBase::
82.475 + detach();
82.476 + g=0;
82.477 + }
82.478 +
82.479 + public:
82.480 + ///Default constructur.
82.481 +
82.482 + ///Default constructur.
82.483 + ///To actually make a snapshot you must call save().
82.484 + ///
82.485 + SnapShot() : g(0) {}
82.486 + ///Constructor that immediately makes a snapshot.
82.487 +
82.488 + ///This constructor immediately makes a snapshot of the graph.
82.489 + ///\param _g The graph we make a snapshot of.
82.490 + SnapShot(ListGraph &_g) {
82.491 + regist(_g);
82.492 + }
82.493 + ///\bug Is it necessary?
82.494 + ///
82.495 + ~SnapShot()
82.496 + {
82.497 + if(g) deregist();
82.498 + }
82.499 +
82.500 + ///Make a snapshot.
82.501 +
82.502 + ///Make a snapshot of the graph.
82.503 + ///
82.504 + ///This function can be called more than once. In case of a repeated
82.505 + ///call, the previous snapshot gets lost.
82.506 + ///\param _g The graph we make the snapshot of.
82.507 + void save(ListGraph &_g)
82.508 + {
82.509 + if(g!=&_g) {
82.510 + if(g) deregist();
82.511 + regist(_g);
82.512 + }
82.513 + added_nodes.clear();
82.514 + added_edges.clear();
82.515 + }
82.516 +
82.517 + ///Undo the changes until the last snapshot.
82.518 +
82.519 + ///Undo the changes until last snapshot created by save().
82.520 + ///
82.521 + ///\todo This function might be called undo().
82.522 + void restore() {
82.523 + deregist();
82.524 + while(!added_edges.empty()) {
82.525 + g->erase(added_edges.front());
82.526 + added_edges.pop_front();
82.527 + }
82.528 + while(!added_nodes.empty()) {
82.529 + g->erase(added_nodes.front());
82.530 + added_nodes.pop_front();
82.531 + }
82.532 + }
82.533 + };
82.534 +
82.535 + };
82.536 +
82.537 +
82.538 + /**************** Undirected List Graph ****************/
82.539 +
82.540 + typedef ErasableUndirGraphExtender<
82.541 + ClearableUndirGraphExtender<
82.542 + ExtendableUndirGraphExtender<
82.543 + MappableUndirGraphExtender<
82.544 + IterableUndirGraphExtender<
82.545 + AlterableUndirGraphExtender<
82.546 + UndirGraphExtender<ListGraphBase> > > > > > > ErasableUndirListGraphBase;
82.547 +
82.548 + ///An undirected list graph class.
82.549 +
82.550 + ///This is a simple and fast erasable undirected graph implementation.
82.551 + ///
82.552 + ///It conforms to the
82.553 + ///\ref concept::UndirGraph "UndirGraph" concept.
82.554 + ///
82.555 + ///\sa concept::UndirGraph.
82.556 + ///
82.557 + ///\todo SnapShot, reverseEdge(), moveTarget(), moveSource(), contract()
82.558 + ///haven't been implemented yet.
82.559 + ///
82.560 + class UndirListGraph : public ErasableUndirListGraphBase {
82.561 + };
82.562 +
82.563 +
82.564 + /// @}
82.565 +} //namespace lemon
82.566 +
82.567 +
82.568 +#endif
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
83.2 +++ b/lemon/lp_base.cc Mon May 23 04:48:14 2005 +0000
83.3 @@ -0,0 +1,33 @@
83.4 +/* -*- C++ -*-
83.5 + * lemon/lp_base.cc - Part of LEMON, a generic C++ optimization library
83.6 + *
83.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
83.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
83.9 + *
83.10 + * Permission to use, modify and distribute this software is granted
83.11 + * provided that this copyright notice appears in all copies. For
83.12 + * precise terms see the accompanying LICENSE file.
83.13 + *
83.14 + * This software is provided "AS IS" with no warranty of any kind,
83.15 + * express or implied, and with no claim as to its suitability for any
83.16 + * purpose.
83.17 + *
83.18 + */
83.19 +
83.20 +///\file
83.21 +///\brief The implementation of the LP solver interface.
83.22 +
83.23 +#include <lemon/lp_base.h>
83.24 +namespace lemon {
83.25 +
83.26 + const LpSolverBase::Value
83.27 + LpSolverBase::INF = std::numeric_limits<Value>::infinity();
83.28 + const LpSolverBase::Value
83.29 + LpSolverBase::NaN = std::numeric_limits<Value>::quiet_NaN();
83.30 +
83.31 +// const LpSolverBase::Constr::Value
83.32 +// LpSolverBase::Constr::INF = std::numeric_limits<Value>::infinity();
83.33 +// const LpSolverBase::Constr::Value
83.34 +// LpSolverBase::Constr::NaN = std::numeric_limits<Value>::quiet_NaN();
83.35 +
83.36 +} //namespace lemon
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
84.2 +++ b/lemon/lp_base.h Mon May 23 04:48:14 2005 +0000
84.3 @@ -0,0 +1,907 @@
84.4 +/* -*- C++ -*-
84.5 + * lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
84.6 + *
84.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
84.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
84.9 + *
84.10 + * Permission to use, modify and distribute this software is granted
84.11 + * provided that this copyright notice appears in all copies. For
84.12 + * precise terms see the accompanying LICENSE file.
84.13 + *
84.14 + * This software is provided "AS IS" with no warranty of any kind,
84.15 + * express or implied, and with no claim as to its suitability for any
84.16 + * purpose.
84.17 + *
84.18 + */
84.19 +
84.20 +#ifndef LEMON_LP_BASE_H
84.21 +#define LEMON_LP_BASE_H
84.22 +
84.23 +#include<vector>
84.24 +#include<map>
84.25 +#include<limits>
84.26 +#include<cmath>
84.27 +
84.28 +#include<lemon/utility.h>
84.29 +#include<lemon/error.h>
84.30 +#include<lemon/invalid.h>
84.31 +
84.32 +//#include"lin_expr.h"
84.33 +
84.34 +///\file
84.35 +///\brief The interface of the LP solver interface.
84.36 +///\ingroup gen_opt_group
84.37 +namespace lemon {
84.38 +
84.39 + ///Internal data structure to convert floating id's to fix one's
84.40 +
84.41 + ///\todo This might be implemented to be also usable in other places.
84.42 + class _FixId
84.43 + {
84.44 + std::vector<int> index;
84.45 + std::vector<int> cross;
84.46 + int first_free;
84.47 + public:
84.48 + _FixId() : first_free(-1) {};
84.49 + ///Convert a floating id to a fix one
84.50 +
84.51 + ///\param n is a floating id
84.52 + ///\return the corresponding fix id
84.53 + int fixId(int n) {return cross[n];}
84.54 + ///Convert a fix id to a floating one
84.55 +
84.56 + ///\param n is a fix id
84.57 + ///\return the corresponding floating id
84.58 + int floatingId(int n) { return index[n];}
84.59 + ///Add a new floating id.
84.60 +
84.61 + ///\param n is a floating id
84.62 + ///\return the fix id of the new value
84.63 + ///\todo Multiple additions should also be handled.
84.64 + int insert(int n)
84.65 + {
84.66 + if(n>=int(cross.size())) {
84.67 + cross.resize(n+1);
84.68 + if(first_free==-1) {
84.69 + cross[n]=index.size();
84.70 + index.push_back(n);
84.71 + }
84.72 + else {
84.73 + cross[n]=first_free;
84.74 + int next=index[first_free];
84.75 + index[first_free]=n;
84.76 + first_free=next;
84.77 + }
84.78 + return cross[n];
84.79 + }
84.80 + ///\todo Create an own exception type.
84.81 + else throw LogicError(); //floatingId-s must form a continuous range;
84.82 + }
84.83 + ///Remove a fix id.
84.84 +
84.85 + ///\param n is a fix id
84.86 + ///
84.87 + void erase(int n)
84.88 + {
84.89 + int fl=index[n];
84.90 + index[n]=first_free;
84.91 + first_free=n;
84.92 + for(int i=fl+1;i<int(cross.size());++i) {
84.93 + cross[i-1]=cross[i];
84.94 + index[cross[i]]--;
84.95 + }
84.96 + cross.pop_back();
84.97 + }
84.98 + ///An upper bound on the largest fix id.
84.99 +
84.100 + ///\todo Do we need this?
84.101 + ///
84.102 + std::size_t maxFixId() { return cross.size()-1; }
84.103 +
84.104 + };
84.105 +
84.106 + ///Common base class for LP solvers
84.107 +
84.108 + ///\todo Much more docs
84.109 + ///\ingroup gen_opt_group
84.110 + class LpSolverBase {
84.111 +
84.112 + public:
84.113 +
84.114 + ///\e
84.115 + enum SolveExitStatus {
84.116 + ///\e
84.117 + SOLVED = 0,
84.118 + ///\e
84.119 + UNSOLVED = 1
84.120 + };
84.121 +
84.122 + ///\e
84.123 + enum SolutionStatus {
84.124 + ///Feasible solution has'n been found (but may exist).
84.125 +
84.126 + ///\todo NOTFOUND might be a better name.
84.127 + ///
84.128 + UNDEFINED = 0,
84.129 + ///The problem has no feasible solution
84.130 + INFEASIBLE = 1,
84.131 + ///Feasible solution found
84.132 + FEASIBLE = 2,
84.133 + ///Optimal solution exists and found
84.134 + OPTIMAL = 3,
84.135 + ///The cost function is unbounded
84.136 +
84.137 + ///\todo Give a feasible solution and an infinite ray (and the
84.138 + ///corresponding bases)
84.139 + INFINITE = 4
84.140 + };
84.141 +
84.142 + ///The floating point type used by the solver
84.143 + typedef double Value;
84.144 + ///The infinity constant
84.145 + static const Value INF;
84.146 + ///The not a number constant
84.147 + static const Value NaN;
84.148 +
84.149 + ///Refer to a column of the LP.
84.150 +
84.151 + ///This type is used to refer to a column of the LP.
84.152 + ///
84.153 + ///Its value remains valid and correct even after the addition or erase of
84.154 + ///other columns.
84.155 + ///
84.156 + ///\todo Document what can one do with a Col (INVALID, comparing,
84.157 + ///it is similar to Node/Edge)
84.158 + class Col {
84.159 + protected:
84.160 + int id;
84.161 + friend class LpSolverBase;
84.162 + public:
84.163 + typedef Value ExprValue;
84.164 + typedef True LpSolverCol;
84.165 + Col() {}
84.166 + Col(const Invalid&) : id(-1) {}
84.167 + bool operator<(Col c) const {return id<c.id;}
84.168 + bool operator==(Col c) const {return id==c.id;}
84.169 + bool operator!=(Col c) const {return id==c.id;}
84.170 + };
84.171 +
84.172 + ///Refer to a row of the LP.
84.173 +
84.174 + ///This type is used to refer to a row of the LP.
84.175 + ///
84.176 + ///Its value remains valid and correct even after the addition or erase of
84.177 + ///other rows.
84.178 + ///
84.179 + ///\todo Document what can one do with a Row (INVALID, comparing,
84.180 + ///it is similar to Node/Edge)
84.181 + class Row {
84.182 + protected:
84.183 + int id;
84.184 + friend class LpSolverBase;
84.185 + public:
84.186 + typedef Value ExprValue;
84.187 + typedef True LpSolverRow;
84.188 + Row() {}
84.189 + Row(const Invalid&) : id(-1) {}
84.190 + typedef True LpSolverRow;
84.191 + bool operator<(Row c) const {return id<c.id;}
84.192 + bool operator==(Row c) const {return id==c.id;}
84.193 + bool operator!=(Row c) const {return id==c.id;}
84.194 + };
84.195 +
84.196 + ///Linear expression of variables and a constant component
84.197 +
84.198 + ///This data structure strores a linear expression of the variables
84.199 + ///(\ref Col "Col"s) and also has a constant component.
84.200 + ///
84.201 + ///There are several ways to access and modify the contents of this
84.202 + ///container.
84.203 + ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
84.204 + ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
84.205 + ///read and modify the coefficients like
84.206 + ///these.
84.207 + ///\code
84.208 + ///e[v]=5;
84.209 + ///e[v]+=12;
84.210 + ///e.erase(v);
84.211 + ///\endcode
84.212 + ///or you can also iterate through its elements.
84.213 + ///\code
84.214 + ///double s=0;
84.215 + ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
84.216 + /// s+=i->second;
84.217 + ///\endcode
84.218 + ///(This code computes the sum of all coefficients).
84.219 + ///- Numbers (<tt>double</tt>'s)
84.220 + ///and variables (\ref Col "Col"s) directly convert to an
84.221 + ///\ref Expr and the usual linear operations are defined so
84.222 + ///\code
84.223 + ///v+w
84.224 + ///2*v-3.12*(v-w/2)+2
84.225 + ///v*2.1+(3*v+(v*12+w+6)*3)/2
84.226 + ///\endcode
84.227 + ///are valid \ref Expr "Expr"essions.
84.228 + ///The usual assignment operations are also defined.
84.229 + ///\code
84.230 + ///e=v+w;
84.231 + ///e+=2*v-3.12*(v-w/2)+2;
84.232 + ///e*=3.4;
84.233 + ///e/=5;
84.234 + ///\endcode
84.235 + ///- The constant member can be set and read by \ref constComp()
84.236 + ///\code
84.237 + ///e.constComp()=12;
84.238 + ///double c=e.constComp();
84.239 + ///\endcode
84.240 + ///
84.241 + ///\note \ref clear() not only sets all coefficients to 0 but also
84.242 + ///clears the constant components.
84.243 + ///
84.244 + ///\sa Constr
84.245 + ///
84.246 + class Expr : public std::map<Col,Value>
84.247 + {
84.248 + public:
84.249 + typedef LpSolverBase::Col Key;
84.250 + typedef LpSolverBase::Value Value;
84.251 +
84.252 + protected:
84.253 + typedef std::map<Col,Value> Base;
84.254 +
84.255 + Value const_comp;
84.256 + public:
84.257 + typedef True IsLinExpression;
84.258 + ///\e
84.259 + Expr() : Base(), const_comp(0) { }
84.260 + ///\e
84.261 + Expr(const Key &v) : const_comp(0) {
84.262 + Base::insert(std::make_pair(v, 1));
84.263 + }
84.264 + ///\e
84.265 + Expr(const Value &v) : const_comp(v) {}
84.266 + ///\e
84.267 + void set(const Key &v,const Value &c) {
84.268 + Base::insert(std::make_pair(v, c));
84.269 + }
84.270 + ///\e
84.271 + Value &constComp() { return const_comp; }
84.272 + ///\e
84.273 + const Value &constComp() const { return const_comp; }
84.274 +
84.275 + ///Removes the components with zero coefficient.
84.276 + void simplify() {
84.277 + for (Base::iterator i=Base::begin(); i!=Base::end();) {
84.278 + Base::iterator j=i;
84.279 + ++j;
84.280 + if ((*i).second==0) Base::erase(i);
84.281 + j=i;
84.282 + }
84.283 + }
84.284 +
84.285 + ///Sets all coefficients and the constant component to 0.
84.286 + void clear() {
84.287 + Base::clear();
84.288 + const_comp=0;
84.289 + }
84.290 +
84.291 + ///\e
84.292 + Expr &operator+=(const Expr &e) {
84.293 + for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
84.294 + (*this)[j->first]+=j->second;
84.295 + ///\todo it might be speeded up using "hints"
84.296 + const_comp+=e.const_comp;
84.297 + return *this;
84.298 + }
84.299 + ///\e
84.300 + Expr &operator-=(const Expr &e) {
84.301 + for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
84.302 + (*this)[j->first]-=j->second;
84.303 + const_comp-=e.const_comp;
84.304 + return *this;
84.305 + }
84.306 + ///\e
84.307 + Expr &operator*=(const Value &c) {
84.308 + for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
84.309 + j->second*=c;
84.310 + const_comp*=c;
84.311 + return *this;
84.312 + }
84.313 + ///\e
84.314 + Expr &operator/=(const Value &c) {
84.315 + for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
84.316 + j->second/=c;
84.317 + const_comp/=c;
84.318 + return *this;
84.319 + }
84.320 + };
84.321 +
84.322 + ///Linear constraint
84.323 +
84.324 + ///This data stucture represents a linear constraint in the LP.
84.325 + ///Basically it is a linear expression with a lower or an upper bound
84.326 + ///(or both). These parts of the constraint can be obtained by the member
84.327 + ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
84.328 + ///respectively.
84.329 + ///There are two ways to construct a constraint.
84.330 + ///- You can set the linear expression and the bounds directly
84.331 + /// by the functions above.
84.332 + ///- The operators <tt>\<=</tt>, <tt>==</tt> and <tt>\>=</tt>
84.333 + /// are defined between expressions, or even between constraints whenever
84.334 + /// it makes sense. Therefore if \c e and \c f are linear expressions and
84.335 + /// \c s and \c t are numbers, then the followings are valid expressions
84.336 + /// and thus they can be used directly e.g. in \ref addRow() whenever
84.337 + /// it makes sense.
84.338 + /// \code
84.339 + /// e<=s
84.340 + /// e<=f
84.341 + /// s<=e<=t
84.342 + /// e>=t
84.343 + /// \endcode
84.344 + ///\warning The validity of a constraint is checked only at run time, so
84.345 + ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
84.346 + ///\ref LogicError exception.
84.347 + class Constr
84.348 + {
84.349 + public:
84.350 + typedef LpSolverBase::Expr Expr;
84.351 + typedef Expr::Key Key;
84.352 + typedef Expr::Value Value;
84.353 +
84.354 +// static const Value INF;
84.355 +// static const Value NaN;
84.356 +
84.357 + protected:
84.358 + Expr _expr;
84.359 + Value _lb,_ub;
84.360 + public:
84.361 + ///\e
84.362 + Constr() : _expr(), _lb(NaN), _ub(NaN) {}
84.363 + ///\e
84.364 + Constr(Value lb,const Expr &e,Value ub) :
84.365 + _expr(e), _lb(lb), _ub(ub) {}
84.366 + ///\e
84.367 + Constr(const Expr &e,Value ub) :
84.368 + _expr(e), _lb(NaN), _ub(ub) {}
84.369 + ///\e
84.370 + Constr(Value lb,const Expr &e) :
84.371 + _expr(e), _lb(lb), _ub(NaN) {}
84.372 + ///\e
84.373 + Constr(const Expr &e) :
84.374 + _expr(e), _lb(NaN), _ub(NaN) {}
84.375 + ///\e
84.376 + void clear()
84.377 + {
84.378 + _expr.clear();
84.379 + _lb=_ub=NaN;
84.380 + }
84.381 +
84.382 + ///Reference to the linear expression
84.383 + Expr &expr() { return _expr; }
84.384 + ///Cont reference to the linear expression
84.385 + const Expr &expr() const { return _expr; }
84.386 + ///Reference to the lower bound.
84.387 +
84.388 + ///\return
84.389 + ///- -\ref INF: the constraint is lower unbounded.
84.390 + ///- -\ref NaN: lower bound has not been set.
84.391 + ///- finite number: the lower bound
84.392 + Value &lowerBound() { return _lb; }
84.393 + ///The const version of \ref lowerBound()
84.394 + const Value &lowerBound() const { return _lb; }
84.395 + ///Reference to the upper bound.
84.396 +
84.397 + ///\return
84.398 + ///- -\ref INF: the constraint is upper unbounded.
84.399 + ///- -\ref NaN: upper bound has not been set.
84.400 + ///- finite number: the upper bound
84.401 + Value &upperBound() { return _ub; }
84.402 + ///The const version of \ref upperBound()
84.403 + const Value &upperBound() const { return _ub; }
84.404 + ///Is the constraint lower bounded?
84.405 + bool lowerBounded() const {
84.406 + using namespace std;
84.407 + return finite(_lb);
84.408 + }
84.409 + ///Is the constraint upper bounded?
84.410 + bool upperBounded() const {
84.411 + using namespace std;
84.412 + return finite(_ub);
84.413 + }
84.414 + };
84.415 +
84.416 +
84.417 + protected:
84.418 + _FixId rows;
84.419 + _FixId cols;
84.420 +
84.421 + //Abstract virtual functions
84.422 + virtual LpSolverBase &_newLp() = 0;
84.423 + virtual LpSolverBase &_copyLp() = 0;
84.424 +
84.425 + virtual int _addCol() = 0;
84.426 + virtual int _addRow() = 0;
84.427 + virtual void _setRowCoeffs(int i,
84.428 + int length,
84.429 + int const * indices,
84.430 + Value const * values ) = 0;
84.431 + virtual void _setColCoeffs(int i,
84.432 + int length,
84.433 + int const * indices,
84.434 + Value const * values ) = 0;
84.435 + virtual void _setCoeff(int row, int col, Value value) = 0;
84.436 + virtual void _setColLowerBound(int i, Value value) = 0;
84.437 + virtual void _setColUpperBound(int i, Value value) = 0;
84.438 +// virtual void _setRowLowerBound(int i, Value value) = 0;
84.439 +// virtual void _setRowUpperBound(int i, Value value) = 0;
84.440 + virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
84.441 + virtual void _setObjCoeff(int i, Value obj_coef) = 0;
84.442 + virtual void _clearObj()=0;
84.443 +// virtual void _setObj(int length,
84.444 +// int const * indices,
84.445 +// Value const * values ) = 0;
84.446 + virtual SolveExitStatus _solve() = 0;
84.447 + virtual Value _getPrimal(int i) = 0;
84.448 + virtual Value _getPrimalValue() = 0;
84.449 + virtual SolutionStatus _getPrimalStatus() = 0;
84.450 + virtual void _setMax() = 0;
84.451 + virtual void _setMin() = 0;
84.452 +
84.453 + //Own protected stuff
84.454 +
84.455 + //Constant component of the objective function
84.456 + Value obj_const_comp;
84.457 +
84.458 +
84.459 +
84.460 +
84.461 + public:
84.462 +
84.463 + ///\e
84.464 + LpSolverBase() : obj_const_comp(0) {}
84.465 +
84.466 + ///\e
84.467 + virtual ~LpSolverBase() {}
84.468 +
84.469 + ///Creates a new LP problem
84.470 + LpSolverBase &newLp() {return _newLp();}
84.471 + ///Makes a copy of the LP problem
84.472 + LpSolverBase ©Lp() {return _copyLp();}
84.473 +
84.474 + ///\name Build up and modify of the LP
84.475 +
84.476 + ///@{
84.477 +
84.478 + ///Add a new empty column (i.e a new variable) to the LP
84.479 + Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
84.480 +
84.481 + ///\brief Adds several new columns
84.482 + ///(i.e a variables) at once
84.483 + ///
84.484 + ///This magic function takes a container as its argument
84.485 + ///and fills its elements
84.486 + ///with new columns (i.e. variables)
84.487 + ///\param t can be
84.488 + ///- a standard STL compatible iterable container with
84.489 + ///\ref Col as its \c values_type
84.490 + ///like
84.491 + ///\code
84.492 + ///std::vector<LpSolverBase::Col>
84.493 + ///std::list<LpSolverBase::Col>
84.494 + ///\endcode
84.495 + ///- a standard STL compatible iterable container with
84.496 + ///\ref Col as its \c mapped_type
84.497 + ///like
84.498 + ///\code
84.499 + ///std::map<AnyType,LpSolverBase::Col>
84.500 + ///\endcode
84.501 + ///- an iterable lemon \ref concept::WriteMap "write map" like
84.502 + ///\code
84.503 + ///ListGraph::NodeMap<LpSolverBase::Col>
84.504 + ///ListGraph::EdgeMap<LpSolverBase::Col>
84.505 + ///\endcode
84.506 + ///\return The number of the created column.
84.507 +#ifdef DOXYGEN
84.508 + template<class T>
84.509 + int addColSet(T &t) { return 0;}
84.510 +#else
84.511 + template<class T>
84.512 + typename enable_if<typename T::value_type::LpSolverCol,int>::type
84.513 + addColSet(T &t,dummy<0> = 0) {
84.514 + int s=0;
84.515 + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
84.516 + return s;
84.517 + }
84.518 + template<class T>
84.519 + typename enable_if<typename T::value_type::second_type::LpSolverCol,
84.520 + int>::type
84.521 + addColSet(T &t,dummy<1> = 1) {
84.522 + int s=0;
84.523 + for(typename T::iterator i=t.begin();i!=t.end();++i) {
84.524 + i->second=addCol();
84.525 + s++;
84.526 + }
84.527 + return s;
84.528 + }
84.529 + template<class T>
84.530 + typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
84.531 + int>::type
84.532 + addColSet(T &t,dummy<2> = 2) {
84.533 + ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
84.534 + int s=0;
84.535 + for(typename T::ValueSet::iterator i=t.valueSet().begin();
84.536 + i!=t.valueSet().end();
84.537 + ++i)
84.538 + {
84.539 + *i=addCol();
84.540 + s++;
84.541 + }
84.542 + return s;
84.543 + }
84.544 +#endif
84.545 +
84.546 + ///Add a new empty row (i.e a new constaint) to the LP
84.547 +
84.548 + ///This function adds a new empty row (i.e a new constaint) to the LP.
84.549 + ///\return The created row
84.550 + Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
84.551 +
84.552 + ///Set a row (i.e a constaint) of the LP
84.553 +
84.554 + ///\param r is the row to be modified
84.555 + ///\param l is lower bound (-\ref INF means no bound)
84.556 + ///\param e is a linear expression (see \ref Expr)
84.557 + ///\param u is the upper bound (\ref INF means no bound)
84.558 + ///\bug This is a temportary function. The interface will change to
84.559 + ///a better one.
84.560 + ///\todo Option to control whether a constraint with a single variable is
84.561 + ///added or not.
84.562 + void setRow(Row r, Value l,const Expr &e, Value u) {
84.563 + std::vector<int> indices;
84.564 + std::vector<Value> values;
84.565 + indices.push_back(0);
84.566 + values.push_back(0);
84.567 + for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
84.568 + if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
84.569 + indices.push_back(cols.floatingId((*i).first.id));
84.570 + values.push_back((*i).second);
84.571 + }
84.572 + _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
84.573 + &indices[0],&values[0]);
84.574 +// _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
84.575 +// _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
84.576 + _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
84.577 + }
84.578 +
84.579 + ///Set a row (i.e a constaint) of the LP
84.580 +
84.581 + ///\param r is the row to be modified
84.582 + ///\param c is a linear expression (see \ref Constr)
84.583 + void setRow(Row r, const Constr &c) {
84.584 + setRow(r,
84.585 + c.lowerBounded()?c.lowerBound():-INF,
84.586 + c.expr(),
84.587 + c.upperBounded()?c.upperBound():INF);
84.588 + }
84.589 +
84.590 + ///Add a new row (i.e a new constaint) to the LP
84.591 +
84.592 + ///\param l is the lower bound (-\ref INF means no bound)
84.593 + ///\param e is a linear expression (see \ref Expr)
84.594 + ///\param u is the upper bound (\ref INF means no bound)
84.595 + ///\return The created row.
84.596 + ///\bug This is a temportary function. The interface will change to
84.597 + ///a better one.
84.598 + Row addRow(Value l,const Expr &e, Value u) {
84.599 + Row r=addRow();
84.600 + setRow(r,l,e,u);
84.601 + return r;
84.602 + }
84.603 +
84.604 + ///Add a new row (i.e a new constaint) to the LP
84.605 +
84.606 + ///\param c is a linear expression (see \ref Constr)
84.607 + ///\return The created row.
84.608 + Row addRow(const Constr &c) {
84.609 + Row r=addRow();
84.610 + setRow(r,c);
84.611 + return r;
84.612 + }
84.613 +
84.614 + /// Set the lower bound of a column (i.e a variable)
84.615 +
84.616 + /// The upper bound of a variable (column) has to be given by an
84.617 + /// extended number of type Value, i.e. a finite number of type
84.618 + /// Value or -\ref INF.
84.619 + void colLowerBound(Col c, Value value) {
84.620 + _setColLowerBound(cols.floatingId(c.id),value);
84.621 + }
84.622 + /// Set the upper bound of a column (i.e a variable)
84.623 +
84.624 + /// The upper bound of a variable (column) has to be given by an
84.625 + /// extended number of type Value, i.e. a finite number of type
84.626 + /// Value or \ref INF.
84.627 + void colUpperBound(Col c, Value value) {
84.628 + _setColUpperBound(cols.floatingId(c.id),value);
84.629 + };
84.630 + /// Set the lower and the upper bounds of a column (i.e a variable)
84.631 +
84.632 + /// The lower and the upper bounds of
84.633 + /// a variable (column) have to be given by an
84.634 + /// extended number of type Value, i.e. a finite number of type
84.635 + /// Value, -\ref INF or \ref INF.
84.636 + void colBounds(Col c, Value lower, Value upper) {
84.637 + _setColLowerBound(cols.floatingId(c.id),lower);
84.638 + _setColUpperBound(cols.floatingId(c.id),upper);
84.639 + }
84.640 +
84.641 +// /// Set the lower bound of a row (i.e a constraint)
84.642 +
84.643 +// /// The lower bound of a linear expression (row) has to be given by an
84.644 +// /// extended number of type Value, i.e. a finite number of type
84.645 +// /// Value or -\ref INF.
84.646 +// void rowLowerBound(Row r, Value value) {
84.647 +// _setRowLowerBound(rows.floatingId(r.id),value);
84.648 +// };
84.649 +// /// Set the upper bound of a row (i.e a constraint)
84.650 +
84.651 +// /// The upper bound of a linear expression (row) has to be given by an
84.652 +// /// extended number of type Value, i.e. a finite number of type
84.653 +// /// Value or \ref INF.
84.654 +// void rowUpperBound(Row r, Value value) {
84.655 +// _setRowUpperBound(rows.floatingId(r.id),value);
84.656 +// };
84.657 +
84.658 + /// Set the lower and the upper bounds of a row (i.e a constraint)
84.659 +
84.660 + /// The lower and the upper bounds of
84.661 + /// a constraint (row) have to be given by an
84.662 + /// extended number of type Value, i.e. a finite number of type
84.663 + /// Value, -\ref INF or \ref INF.
84.664 + void rowBounds(Row c, Value lower, Value upper) {
84.665 + _setRowBounds(rows.floatingId(c.id),lower, upper);
84.666 + // _setRowUpperBound(rows.floatingId(c.id),upper);
84.667 + }
84.668 +
84.669 + ///Set an element of the objective function
84.670 + void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
84.671 + ///Set the objective function
84.672 +
84.673 + ///\param e is a linear expression of type \ref Expr.
84.674 + ///\bug The previous objective function is not cleared!
84.675 + void setObj(Expr e) {
84.676 + _clearObj();
84.677 + for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
84.678 + objCoeff((*i).first,(*i).second);
84.679 + obj_const_comp=e.constComp();
84.680 + }
84.681 +
84.682 + ///Maximize
84.683 + void max() { _setMax(); }
84.684 + ///Minimize
84.685 + void min() { _setMin(); }
84.686 +
84.687 +
84.688 + ///@}
84.689 +
84.690 +
84.691 + ///\name Solve the LP
84.692 +
84.693 + ///@{
84.694 +
84.695 + ///\e
84.696 + SolveExitStatus solve() { return _solve(); }
84.697 +
84.698 + ///@}
84.699 +
84.700 + ///\name Obtain the solution
84.701 +
84.702 + ///@{
84.703 +
84.704 + ///\e
84.705 + SolutionStatus primalStatus() {
84.706 + return _getPrimalStatus();
84.707 + }
84.708 +
84.709 + ///\e
84.710 + Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
84.711 +
84.712 + ///\e
84.713 +
84.714 + ///\return
84.715 + ///- \ref INF or -\ref INF means either infeasibility or unboundedness
84.716 + /// of the primal problem, depending on whether we minimize or maximize.
84.717 + ///- \ref NaN if no primal solution is found.
84.718 + ///- The (finite) objective value if an optimal solution is found.
84.719 + Value primalValue() { return _getPrimalValue()+obj_const_comp;}
84.720 + ///@}
84.721 +
84.722 + };
84.723 +
84.724 + ///\e
84.725 +
84.726 + ///\relates LpSolverBase::Expr
84.727 + ///
84.728 + inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
84.729 + const LpSolverBase::Expr &b)
84.730 + {
84.731 + LpSolverBase::Expr tmp(a);
84.732 + tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
84.733 + return tmp;
84.734 + }
84.735 + ///\e
84.736 +
84.737 + ///\relates LpSolverBase::Expr
84.738 + ///
84.739 + inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
84.740 + const LpSolverBase::Expr &b)
84.741 + {
84.742 + LpSolverBase::Expr tmp(a);
84.743 + tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
84.744 + return tmp;
84.745 + }
84.746 + ///\e
84.747 +
84.748 + ///\relates LpSolverBase::Expr
84.749 + ///
84.750 + inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
84.751 + const LpSolverBase::Value &b)
84.752 + {
84.753 + LpSolverBase::Expr tmp(a);
84.754 + tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
84.755 + return tmp;
84.756 + }
84.757 +
84.758 + ///\e
84.759 +
84.760 + ///\relates LpSolverBase::Expr
84.761 + ///
84.762 + inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
84.763 + const LpSolverBase::Expr &b)
84.764 + {
84.765 + LpSolverBase::Expr tmp(b);
84.766 + tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
84.767 + return tmp;
84.768 + }
84.769 + ///\e
84.770 +
84.771 + ///\relates LpSolverBase::Expr
84.772 + ///
84.773 + inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
84.774 + const LpSolverBase::Value &b)
84.775 + {
84.776 + LpSolverBase::Expr tmp(a);
84.777 + tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
84.778 + return tmp;
84.779 + }
84.780 +
84.781 + ///\e
84.782 +
84.783 + ///\relates LpSolverBase::Constr
84.784 + ///
84.785 + inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
84.786 + const LpSolverBase::Expr &f)
84.787 + {
84.788 + return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
84.789 + }
84.790 +
84.791 + ///\e
84.792 +
84.793 + ///\relates LpSolverBase::Constr
84.794 + ///
84.795 + inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
84.796 + const LpSolverBase::Expr &f)
84.797 + {
84.798 + return LpSolverBase::Constr(e,f);
84.799 + }
84.800 +
84.801 + ///\e
84.802 +
84.803 + ///\relates LpSolverBase::Constr
84.804 + ///
84.805 + inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
84.806 + const LpSolverBase::Value &f)
84.807 + {
84.808 + return LpSolverBase::Constr(e,f);
84.809 + }
84.810 +
84.811 + ///\e
84.812 +
84.813 + ///\relates LpSolverBase::Constr
84.814 + ///
84.815 + inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
84.816 + const LpSolverBase::Expr &f)
84.817 + {
84.818 + return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
84.819 + }
84.820 +
84.821 +
84.822 + ///\e
84.823 +
84.824 + ///\relates LpSolverBase::Constr
84.825 + ///
84.826 + inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
84.827 + const LpSolverBase::Expr &f)
84.828 + {
84.829 + return LpSolverBase::Constr(f,e);
84.830 + }
84.831 +
84.832 +
84.833 + ///\e
84.834 +
84.835 + ///\relates LpSolverBase::Constr
84.836 + ///
84.837 + inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
84.838 + const LpSolverBase::Value &f)
84.839 + {
84.840 + return LpSolverBase::Constr(f,e);
84.841 + }
84.842 +
84.843 + ///\e
84.844 +
84.845 + ///\relates LpSolverBase::Constr
84.846 + ///
84.847 + inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
84.848 + const LpSolverBase::Expr &f)
84.849 + {
84.850 + return LpSolverBase::Constr(0,e-f,0);
84.851 + }
84.852 +
84.853 + ///\e
84.854 +
84.855 + ///\relates LpSolverBase::Constr
84.856 + ///
84.857 + inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
84.858 + const LpSolverBase::Constr&c)
84.859 + {
84.860 + LpSolverBase::Constr tmp(c);
84.861 + ///\todo Create an own exception type.
84.862 + if(!isnan(tmp.lowerBound())) throw LogicError();
84.863 + else tmp.lowerBound()=n;
84.864 + return tmp;
84.865 + }
84.866 + ///\e
84.867 +
84.868 + ///\relates LpSolverBase::Constr
84.869 + ///
84.870 + inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
84.871 + const LpSolverBase::Value &n)
84.872 + {
84.873 + LpSolverBase::Constr tmp(c);
84.874 + ///\todo Create an own exception type.
84.875 + if(!isnan(tmp.upperBound())) throw LogicError();
84.876 + else tmp.upperBound()=n;
84.877 + return tmp;
84.878 + }
84.879 +
84.880 + ///\e
84.881 +
84.882 + ///\relates LpSolverBase::Constr
84.883 + ///
84.884 + inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
84.885 + const LpSolverBase::Constr&c)
84.886 + {
84.887 + LpSolverBase::Constr tmp(c);
84.888 + ///\todo Create an own exception type.
84.889 + if(!isnan(tmp.upperBound())) throw LogicError();
84.890 + else tmp.upperBound()=n;
84.891 + return tmp;
84.892 + }
84.893 + ///\e
84.894 +
84.895 + ///\relates LpSolverBase::Constr
84.896 + ///
84.897 + inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
84.898 + const LpSolverBase::Value &n)
84.899 + {
84.900 + LpSolverBase::Constr tmp(c);
84.901 + ///\todo Create an own exception type.
84.902 + if(!isnan(tmp.lowerBound())) throw LogicError();
84.903 + else tmp.lowerBound()=n;
84.904 + return tmp;
84.905 + }
84.906 +
84.907 +
84.908 +} //namespace lemon
84.909 +
84.910 +#endif //LEMON_LP_BASE_H
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/lemon/lp_cplex.cc Mon May 23 04:48:14 2005 +0000
85.3 @@ -0,0 +1,407 @@
85.4 +/* -*- C++ -*-
85.5 + * lemon/lp_cplex.cc - Part of LEMON, a generic C++ optimization library
85.6 + *
85.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
85.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
85.9 + *
85.10 + * Permission to use, modify and distribute this software is granted
85.11 + * provided that this copyright notice appears in all copies. For
85.12 + * precise terms see the accompanying LICENSE file.
85.13 + *
85.14 + * This software is provided "AS IS" with no warranty of any kind,
85.15 + * express or implied, and with no claim as to its suitability for any
85.16 + * purpose.
85.17 + *
85.18 + */
85.19 +#include <iostream>
85.20 +#include<lemon/lp_cplex.h>
85.21 +
85.22 +///\file
85.23 +///\brief Implementation of the LEMON-CPLEX lp solver interface.
85.24 +namespace lemon {
85.25 +
85.26 + LpCplex::LpCplex() : LpSolverBase() {
85.27 + env = NULL;
85.28 + lp = NULL;
85.29 + env = CPXopenCPLEXdevelop(&status);
85.30 +// if (Env == NULL)
85.31 +// {
85.32 +// fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
85.33 +// CPXgeterrorstring(Env, Status, ErrorMsg);
85.34 +// fprintf(stderr,"%s",ErrorMsg);
85.35 +// goto Terminate;
85.36 +// }
85.37 +
85.38 + // *** A problema létrehozása ***
85.39 + lp = CPXcreateprob(env, &status, "LP problem");
85.40 +
85.41 + // if (Problem == NULL)
85.42 +// {
85.43 +// fprintf(stderr,"Az LP létrehozása sikertelen");
85.44 +// goto Terminate;
85.45 +// }
85.46 +
85.47 + }
85.48 +
85.49 + LpCplex::~LpCplex() {
85.50 + status = CPXfreeprob(env,&lp);
85.51 + // if (Status != 0)
85.52 + // {
85.53 +// fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
85.54 +// CPXgeterrorstring(Env, Status, ErrorMsg);
85.55 +// fprintf(stderr,"%s",ErrorMsg);
85.56 +// goto Terminate;
85.57 +// }
85.58 +
85.59 + status = CPXcloseCPLEX(&env);
85.60 + // if (Status != 0)
85.61 + // {
85.62 + // fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
85.63 +// CPXgeterrorstring(Env, Status, ErrorMsg);
85.64 +// fprintf(stderr,"%s",ErrorMsg);
85.65 +// goto Terminate;
85.66 +// }
85.67 +
85.68 + }
85.69 +
85.70 + LpSolverBase &LpCplex::_newLp()
85.71 + {
85.72 + return *(LpSolverBase*)0;
85.73 + }
85.74 + LpSolverBase &LpCplex::_copyLp() {
85.75 + return *(LpSolverBase*)0;
85.76 + //Ez lesz majd CPXcloneprob (env, lp, &status);
85.77 + }
85.78 +
85.79 + int LpCplex::_addCol()
85.80 + {
85.81 + int i = CPXgetnumcols (env, lp);
85.82 + Value lb[1],ub[1];
85.83 + lb[0]=-INF;//-CPX_INFBOUND;
85.84 + ub[0]=INF;//CPX_INFBOUND;
85.85 + status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
85.86 + return i;
85.87 + }
85.88 +
85.89 + int LpCplex::_addRow()
85.90 + {
85.91 + //We want a row that is not constrained
85.92 + char sense[1];
85.93 + sense[0]='L';//<= constraint
85.94 + Value rhs[1];
85.95 + rhs[0]=INF;
85.96 + int i = CPXgetnumrows (env, lp);
85.97 + status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
85.98 + return i;
85.99 + }
85.100 +
85.101 +
85.102 + void LpCplex::_eraseCol(int i) {
85.103 + ///\todo Not implemented yet
85.104 + }
85.105 +
85.106 + void LpCplex::_eraseRow(int i) {
85.107 + ///\todo Not implemented yet
85.108 + }
85.109 +
85.110 +
85.111 + ///\warning Data at index 0 is ignored in the arrays.
85.112 + void LpCplex::_setRowCoeffs(int i,
85.113 + int length,
85.114 + int const * indices,
85.115 + Value const * values )
85.116 + {
85.117 + int rowlist[length+1];
85.118 + int* p=rowlist;
85.119 + for (int k=1;k<=length;++k){
85.120 + rowlist[k]=i;
85.121 + }
85.122 + status = CPXchgcoeflist(env, lp,
85.123 + length,
85.124 + p+1,
85.125 + const_cast<int * >(indices+1),
85.126 + const_cast<Value * >(values+1));
85.127 + }
85.128 +
85.129 + void LpCplex::_setColCoeffs(int i,
85.130 + int length,
85.131 + int const * indices,
85.132 + Value const * values)
85.133 + {
85.134 + int collist[length+1];
85.135 + int* p=collist;
85.136 + for (int k=1;k<=length;++k){
85.137 + collist[k]=i;
85.138 + }
85.139 + status = CPXchgcoeflist(env, lp,
85.140 + length,
85.141 + const_cast<int * >(indices+1),
85.142 + p+1,
85.143 + const_cast<Value * >(values+1));
85.144 + }
85.145 +
85.146 + void LpCplex::_setCoeff(int row, int col, Value value)
85.147 + {
85.148 + CPXchgcoef (env, lp, row, col, value);
85.149 + }
85.150 +
85.151 + void LpCplex::_setColLowerBound(int i, Value value)
85.152 + {
85.153 + int indices[1];
85.154 + indices[0]=i;
85.155 + char lu[1];
85.156 + lu[0]='L';
85.157 + Value bd[1];
85.158 + bd[0]=value;
85.159 + status = CPXchgbds (env, lp, 1, indices, lu, bd);
85.160 +
85.161 + }
85.162 +
85.163 + void LpCplex::_setColUpperBound(int i, Value value)
85.164 + {
85.165 + int indices[1];
85.166 + indices[0]=i;
85.167 + char lu[1];
85.168 + lu[0]='U';
85.169 + Value bd[1];
85.170 + bd[0]=value;
85.171 + status = CPXchgbds (env, lp, 1, indices, lu, bd);
85.172 + }
85.173 +
85.174 + //This will be easier to implement
85.175 + void LpCplex::_setRowBounds(int i, Value lb, Value ub)
85.176 + {
85.177 + //Bad parameter
85.178 + if (lb==INF || ub==-INF) {
85.179 + //FIXME error
85.180 + }
85.181 +
85.182 + int cnt=1;
85.183 + int indices[1];
85.184 + indices[0]=i;
85.185 + char sense[1];
85.186 +
85.187 + if (lb==-INF){
85.188 + sense[0]='L';
85.189 + CPXchgsense (env, lp, cnt, indices, sense);
85.190 + CPXchgcoef (env, lp, i, -1, ub);
85.191 +
85.192 + }
85.193 + else{
85.194 + if (ub==INF){
85.195 + sense[0]='G';
85.196 + CPXchgsense (env, lp, cnt, indices, sense);
85.197 + CPXchgcoef (env, lp, i, -1, lb);
85.198 + }
85.199 + else{
85.200 + if (lb == ub){
85.201 + sense[0]='E';
85.202 + CPXchgsense (env, lp, cnt, indices, sense);
85.203 + CPXchgcoef (env, lp, i, -1, lb);
85.204 + }
85.205 + else{
85.206 + sense[0]='R';
85.207 + CPXchgsense (env, lp, cnt, indices, sense);
85.208 + CPXchgcoef (env, lp, i, -1, lb);
85.209 + CPXchgcoef (env, lp, i, -2, ub-lb);
85.210 + }
85.211 + }
85.212 + }
85.213 + }
85.214 +
85.215 +// void LpCplex::_setRowLowerBound(int i, Value value)
85.216 +// {
85.217 +// //Not implemented, obsolete
85.218 +// }
85.219 +
85.220 +// void LpCplex::_setRowUpperBound(int i, Value value)
85.221 +// {
85.222 +// //Not implemented, obsolete
85.223 +// // //TODO Ezt kell meg megirni
85.224 +// // //type of the problem
85.225 +// // char sense[1];
85.226 +// // status = CPXgetsense (env, lp, sense, i, i);
85.227 +// // Value rhs[1];
85.228 +// // status = CPXgetrhs (env, lp, rhs, i, i);
85.229 +
85.230 +// // switch (sense[0]) {
85.231 +// // case 'L'://<= constraint
85.232 +// // break;
85.233 +// // case 'E'://= constraint
85.234 +// // break;
85.235 +// // case 'G'://>= constraint
85.236 +// // break;
85.237 +// // case 'R'://ranged constraint
85.238 +// // break;
85.239 +// // default: ;
85.240 +// // //FIXME error
85.241 +// // }
85.242 +
85.243 +// // status = CPXchgcoef (env, lp, i, -2, value_rng);
85.244 +// }
85.245 +
85.246 + void LpCplex::_setObjCoeff(int i, Value obj_coef)
85.247 + {
85.248 + CPXchgcoef (env, lp, -1, i, obj_coef);
85.249 + }
85.250 +
85.251 + void LpCplex::_clearObj()
85.252 + {
85.253 + for (int i=0;i< CPXgetnumcols (env, lp);++i){
85.254 + CPXchgcoef (env, lp, -1, i, 0);
85.255 + }
85.256 +
85.257 + }
85.258 +
85.259 + LpCplex::SolveExitStatus LpCplex::_solve()
85.260 + {
85.261 +
85.262 + status = CPXlpopt (env, lp);
85.263 + if (status == 0){
85.264 + return SOLVED;
85.265 + }
85.266 + else{
85.267 + return UNSOLVED;
85.268 + }
85.269 +// int i= lpx_simplex(lp);
85.270 +// switch (i) {
85.271 +// case LPX_E_OK:
85.272 +// return SOLVED;
85.273 +// break;
85.274 +// default:
85.275 +// return UNSOLVED;
85.276 +// }
85.277 + }
85.278 +
85.279 + LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
85.280 + {
85.281 +//7.5-os cplex statusai
85.282 +// #define CPX_OPTIMAL 1
85.283 +// #define CPX_INFEASIBLE 2
85.284 +// #define CPX_UNBOUNDED 3
85.285 +// #define CPX_OBJ_LIM 4
85.286 +// #define CPX_IT_LIM_FEAS 5
85.287 +// #define CPX_IT_LIM_INFEAS 6
85.288 +// #define CPX_TIME_LIM_FEAS 7
85.289 +// #define CPX_TIME_LIM_INFEAS 8
85.290 +// #define CPX_NUM_BEST_FEAS 9
85.291 +// #define CPX_NUM_BEST_INFEAS 10
85.292 +// #define CPX_OPTIMAL_INFEAS 11
85.293 +// #define CPX_ABORT_FEAS 12
85.294 +// #define CPX_ABORT_INFEAS 13
85.295 +// #define CPX_ABORT_DUAL_INFEAS 14
85.296 +// #define CPX_ABORT_PRIM_INFEAS 15
85.297 +// #define CPX_ABORT_PRIM_DUAL_INFEAS 16
85.298 +// #define CPX_ABORT_PRIM_DUAL_FEAS 17
85.299 +// #define CPX_ABORT_CROSSOVER 18
85.300 +// #define CPX_INForUNBD 19
85.301 +// #define CPX_PIVOT 20
85.302 +
85.303 +// Ezeket hova tegyem:
85.304 +// ??case CPX_ABORT_DUAL_INFEAS
85.305 +// ??case CPX_ABORT_CROSSOVER
85.306 +// ??case CPX_INForUNBD
85.307 +// ??case CPX_PIVOT
85.308 +
85.309 + int stat = CPXgetstat (env, lp);
85.310 + switch (stat) {
85.311 + case 0:
85.312 + return UNDEFINED; //Undefined
85.313 + break;
85.314 + case CPX_OPTIMAL://Optimal
85.315 + return OPTIMAL;
85.316 + break;
85.317 + case CPX_UNBOUNDED://Unbounded
85.318 + return INFINITE;
85.319 + break;
85.320 + case CPX_INFEASIBLE://Infeasible
85.321 + case CPX_IT_LIM_INFEAS:
85.322 + case CPX_TIME_LIM_INFEAS:
85.323 + case CPX_NUM_BEST_INFEAS:
85.324 + case CPX_OPTIMAL_INFEAS:
85.325 + case CPX_ABORT_INFEAS:
85.326 + case CPX_ABORT_PRIM_INFEAS:
85.327 + case CPX_ABORT_PRIM_DUAL_INFEAS:
85.328 + return INFEASIBLE;
85.329 + break;
85.330 + case CPX_OBJ_LIM:
85.331 + case CPX_IT_LIM_FEAS:
85.332 + case CPX_TIME_LIM_FEAS:
85.333 + case CPX_NUM_BEST_FEAS:
85.334 + case CPX_ABORT_FEAS:
85.335 + case CPX_ABORT_PRIM_DUAL_FEAS:
85.336 + return FEASIBLE;
85.337 + break;
85.338 + default:
85.339 + return UNDEFINED; //Everything else comes here
85.340 + //FIXME error
85.341 + }
85.342 +
85.343 +
85.344 + //Nem tudom, hanyas cplex verzio statusai
85.345 +// CPX_STAT_ABORT_DUAL_OBJ_LIM
85.346 +// CPX_STAT_ABORT_IT_LIM
85.347 +// CPX_STAT_ABORT_OBJ_LIM
85.348 +// CPX_STAT_ABORT_PRIM_OBJ_LIM
85.349 +// CPX_STAT_ABORT_TIME_LIM
85.350 +// CPX_STAT_ABORT_USER
85.351 +// CPX_STAT_FEASIBLE_RELAXED
85.352 +// CPX_STAT_INFEASIBLE
85.353 +// CPX_STAT_INForUNBD
85.354 +// CPX_STAT_NUM_BEST
85.355 +// CPX_STAT_OPTIMAL
85.356 +// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
85.357 +// CPX_STAT_OPTIMAL_INFEAS
85.358 +// CPX_STAT_OPTIMAL_RELAXED
85.359 +// CPX_STAT_UNBOUNDED
85.360 +
85.361 +// int stat = CPXgetstat (env, lp);
85.362 +// switch (stat) {
85.363 +// case CPX_STAT_OPTIMAL://Optimal
85.364 +// return OPTIMAL;
85.365 +// break;
85.366 +// case CPX_STAT_INFEASIBLE://Infeasible
85.367 +// return INFEASIBLE;
85.368 +// break;
85.369 +// case CPX_STAT_UNBOUNDED://Unbounded
85.370 +// return INFINITE;
85.371 +// break;
85.372 +// case CPX_STAT_NUM_BEST://Feasible
85.373 +// return FEASIBLE;
85.374 +// break;
85.375 +// default:
85.376 +// return UNDEFINED; //Everything else comes here
85.377 +// //FIXME error
85.378 +// }
85.379 +
85.380 + }
85.381 +
85.382 + LpCplex::Value LpCplex::_getPrimal(int i)
85.383 + {
85.384 + Value x;
85.385 + CPXgetx (env, lp, &x, i, i);
85.386 + return x;
85.387 + }
85.388 +
85.389 + LpCplex::Value LpCplex::_getPrimalValue()
85.390 + {
85.391 + Value objval;
85.392 + //method = CPXgetmethod (env, lp);
85.393 + status = CPXgetobjval (env, lp, &objval);
85.394 + return objval;
85.395 + }
85.396 +
85.397 +
85.398 +
85.399 +
85.400 + void LpCplex::_setMax()
85.401 + {
85.402 + CPXchgobjsen (env, lp, CPX_MAX);
85.403 + }
85.404 + void LpCplex::_setMin()
85.405 + {
85.406 + CPXchgobjsen (env, lp, CPX_MIN);
85.407 + }
85.408 +
85.409 +} //namespace lemon
85.410 +
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/lemon/lp_cplex.h Mon May 23 04:48:14 2005 +0000
86.3 @@ -0,0 +1,112 @@
86.4 +/* -*- C++ -*-
86.5 + * lemon/lp_cplex.h - Part of LEMON, a generic C++ optimization library
86.6 + *
86.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
86.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
86.9 + *
86.10 + * Permission to use, modify and distribute this software is granted
86.11 + * provided that this copyright notice appears in all copies. For
86.12 + * precise terms see the accompanying LICENSE file.
86.13 + *
86.14 + * This software is provided "AS IS" with no warranty of any kind,
86.15 + * express or implied, and with no claim as to its suitability for any
86.16 + * purpose.
86.17 + *
86.18 + */
86.19 +
86.20 +#ifndef LEMON_LP_CPLEX_H
86.21 +#define LEMON_LP_CPLEX_H
86.22 +
86.23 +///\file
86.24 +///\brief Header of the LEMON-CPLEX lp solver interface.
86.25 +
86.26 +#include <lemon/lp_base.h>
86.27 +
86.28 +extern "C" {
86.29 +#include <ilcplex/cplex.h>
86.30 +}
86.31 +
86.32 +namespace lemon {
86.33 +
86.34 +
86.35 + /// \brief Interface for the CPLEX solver
86.36 + ///
86.37 + /// This class implements an interface for the CPLEX LP solver.
86.38 + class LpCplex : public LpSolverBase {
86.39 +
86.40 + public:
86.41 +
86.42 + typedef LpSolverBase Parent;
86.43 +
86.44 + /// \e
86.45 + int status;
86.46 + CPXENVptr env;
86.47 + CPXLPptr lp;
86.48 +
86.49 +
86.50 + /// \e
86.51 + LpCplex();
86.52 + /// \e
86.53 + ~LpCplex();
86.54 +
86.55 + protected:
86.56 + virtual LpSolverBase &_newLp();
86.57 + virtual LpSolverBase &_copyLp();
86.58 +
86.59 + virtual int _addCol();
86.60 + virtual int _addRow();
86.61 + virtual void _eraseCol(int i);
86.62 + virtual void _eraseRow(int i);
86.63 + virtual void _setRowCoeffs(int i,
86.64 + int length,
86.65 + const int * indices,
86.66 + const Value * values );
86.67 + virtual void _setColCoeffs(int i,
86.68 + int length,
86.69 + const int * indices,
86.70 + const Value * values);
86.71 + virtual void _setCoeff(int row, int col, Value value);
86.72 + virtual void _setColLowerBound(int i, Value value);
86.73 + virtual void _setColUpperBound(int i, Value value);
86.74 +// virtual void _setRowLowerBound(int i, Value value);
86.75 +// virtual void _setRowUpperBound(int i, Value value);
86.76 + virtual void _setRowBounds(int i, Value lower, Value upper);
86.77 + virtual void _setObjCoeff(int i, Value obj_coef);
86.78 + virtual void _clearObj();
86.79 + ///\e
86.80 +
86.81 + ///\bug Unimplemented
86.82 + ///
86.83 + virtual SolveExitStatus _solve();
86.84 + ///\e
86.85 +
86.86 + ///\bug Unimplemented
86.87 + ///
86.88 + virtual Value _getPrimal(int i);
86.89 + ///\e
86.90 +
86.91 + ///\bug Unimplemented
86.92 + ///
86.93 + virtual Value _getPrimalValue();
86.94 + ///\e
86.95 +
86.96 + ///\bug Unimplemented
86.97 + ///
86.98 + virtual SolutionStatus _getPrimalStatus();
86.99 +
86.100 + ///\e
86.101 +
86.102 + ///\bug Unimplemented
86.103 + ///
86.104 + virtual void _setMax();
86.105 + ///\e
86.106 +
86.107 + ///\bug Unimplemented
86.108 + ///
86.109 + virtual void _setMin();
86.110 +
86.111 + };
86.112 +} //END OF NAMESPACE LEMON
86.113 +
86.114 +#endif //LEMON_LP_CPLEX_H
86.115 +
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/lemon/lp_glpk.cc Mon May 23 04:48:14 2005 +0000
87.3 @@ -0,0 +1,447 @@
87.4 +/* -*- C++ -*-
87.5 + * lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
87.6 + *
87.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
87.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
87.9 + *
87.10 + * Permission to use, modify and distribute this software is granted
87.11 + * provided that this copyright notice appears in all copies. For
87.12 + * precise terms see the accompanying LICENSE file.
87.13 + *
87.14 + * This software is provided "AS IS" with no warranty of any kind,
87.15 + * express or implied, and with no claim as to its suitability for any
87.16 + * purpose.
87.17 + *
87.18 + */
87.19 +
87.20 +#ifndef LEMON_LP_GLPK_CC
87.21 +#define LEMON_LP_GLPK_CC
87.22 +
87.23 +///\file
87.24 +///\brief Implementation of the LEMON-GLPK lp solver interface.
87.25 +
87.26 +#include <lemon/lp_glpk.h>
87.27 +
87.28 +namespace lemon {
87.29 +
87.30 + ///\e
87.31 +
87.32 + ///\bug Unimplemented!
87.33 + ///
87.34 + LpSolverBase &LpGlpk::_newLp()
87.35 + {
87.36 + LpSolverBase *tmp=0;
87.37 + return *tmp;
87.38 + }
87.39 +
87.40 + ///\e
87.41 +
87.42 + ///\bug Unimplemented!
87.43 + ///
87.44 + LpSolverBase &LpGlpk::_copyLp()
87.45 + {
87.46 + LpSolverBase *tmp=0;
87.47 + return *tmp;
87.48 + }
87.49 +
87.50 + LpGlpk::LpGlpk() : Parent(),
87.51 + lp(lpx_create_prob()) {
87.52 + ///\todo constrol function for this:
87.53 + lpx_set_int_parm(lp, LPX_K_DUAL, 1);
87.54 + messageLevel(0);
87.55 + }
87.56 +
87.57 + LpGlpk::~LpGlpk() {
87.58 + lpx_delete_prob(lp);
87.59 + }
87.60 +
87.61 + int LpGlpk::_addCol() {
87.62 + int i=lpx_add_cols(lp, 1);
87.63 + _setColLowerBound(i, -INF);
87.64 + _setColUpperBound(i, INF);
87.65 + return i;
87.66 + }
87.67 +
87.68 + int LpGlpk::_addRow() {
87.69 + int i=lpx_add_rows(lp, 1);
87.70 + return i;
87.71 + }
87.72 +
87.73 +
87.74 + void LpGlpk::_eraseCol(int i) {
87.75 + int cols[2];
87.76 + cols[1]=i;
87.77 + lpx_del_cols(lp, 1, cols);
87.78 + }
87.79 +
87.80 + void LpGlpk::_eraseRow(int i) {
87.81 + int rows[2];
87.82 + rows[1]=i;
87.83 + lpx_del_rows(lp, 1, rows);
87.84 + }
87.85 +
87.86 + void LpGlpk::_setRowCoeffs(int i,
87.87 + int length,
87.88 + const int * indices,
87.89 + const Value * values )
87.90 + {
87.91 + lpx_set_mat_row(lp, i, length,
87.92 + const_cast<int * >(indices) ,
87.93 + const_cast<Value * >(values));
87.94 + }
87.95 +
87.96 + void LpGlpk::_setColCoeffs(int i,
87.97 + int length,
87.98 + const int * indices,
87.99 + const Value * values)
87.100 + {
87.101 + lpx_set_mat_col(lp, i, length,
87.102 + const_cast<int * >(indices),
87.103 + const_cast<Value * >(values));
87.104 + }
87.105 +
87.106 +
87.107 + void LpGlpk::_setCoeff(int row, int col, Value value)
87.108 + {
87.109 + ///FIXME Of course this is not efficient at all, but GLPK knows not more.
87.110 + // First approach: get one row, apply changes and set it again
87.111 + //(one idea to improve this: maybe it is better to do this with 1 coloumn)
87.112 +
87.113 + int mem_length=2+lpx_get_num_cols(lp);
87.114 + int* indices = new int[mem_length];
87.115 + Value* values = new Value[mem_length];
87.116 +
87.117 +
87.118 + int length=lpx_get_mat_row(lp, row, indices, values);
87.119 +
87.120 + //The following code does not suppose that the elements of the array indices are sorted
87.121 + int i=1;
87.122 + bool found=false;
87.123 + while (i <= length && !found){
87.124 + if (indices[i]==col){
87.125 + found = true;
87.126 + values[i]=value;
87.127 + }
87.128 + ++i;
87.129 + }
87.130 + if (!found){
87.131 + ++length;
87.132 + indices[length]=col;
87.133 + values[length]=value;
87.134 + }
87.135 +
87.136 + lpx_set_mat_row(lp, row, length, indices, values);
87.137 + delete [] indices;
87.138 + delete [] values;
87.139 +
87.140 + }
87.141 +
87.142 + void LpGlpk::_setColLowerBound(int i, Value lo)
87.143 + {
87.144 + if (lo==INF) {
87.145 + //FIXME error
87.146 + }
87.147 + int b=lpx_get_col_type(lp, i);
87.148 + double up=lpx_get_col_ub(lp, i);
87.149 + if (lo==-INF) {
87.150 + switch (b) {
87.151 + case LPX_FR:
87.152 + case LPX_LO:
87.153 + lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
87.154 + break;
87.155 + case LPX_UP:
87.156 + break;
87.157 + case LPX_DB:
87.158 + case LPX_FX:
87.159 + lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
87.160 + break;
87.161 + default: ;
87.162 + //FIXME error
87.163 + }
87.164 + } else {
87.165 + switch (b) {
87.166 + case LPX_FR:
87.167 + case LPX_LO:
87.168 + lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
87.169 + break;
87.170 + case LPX_UP:
87.171 + case LPX_DB:
87.172 + case LPX_FX:
87.173 + if (lo==up)
87.174 + lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
87.175 + else
87.176 + lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
87.177 + break;
87.178 + default: ;
87.179 + //FIXME error
87.180 + }
87.181 + }
87.182 +
87.183 + }
87.184 +
87.185 + void LpGlpk::_setColUpperBound(int i, Value up)
87.186 + {
87.187 + if (up==-INF) {
87.188 + //FIXME error
87.189 + }
87.190 + int b=lpx_get_col_type(lp, i);
87.191 + double lo=lpx_get_col_lb(lp, i);
87.192 + if (up==INF) {
87.193 + switch (b) {
87.194 + case LPX_FR:
87.195 + case LPX_LO:
87.196 + break;
87.197 + case LPX_UP:
87.198 + lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
87.199 + break;
87.200 + case LPX_DB:
87.201 + case LPX_FX:
87.202 + lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
87.203 + break;
87.204 + default: ;
87.205 + //FIXME error
87.206 + }
87.207 + } else {
87.208 + switch (b) {
87.209 + case LPX_FR:
87.210 + lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
87.211 + break;
87.212 + case LPX_UP:
87.213 + lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
87.214 + break;
87.215 + case LPX_LO:
87.216 + case LPX_DB:
87.217 + case LPX_FX:
87.218 + if (lo==up)
87.219 + lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
87.220 + else
87.221 + lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
87.222 + break;
87.223 + default: ;
87.224 + //FIXME error
87.225 + }
87.226 + }
87.227 + }
87.228 +
87.229 +// void LpGlpk::_setRowLowerBound(int i, Value lo)
87.230 +// {
87.231 +// if (lo==INF) {
87.232 +// //FIXME error
87.233 +// }
87.234 +// int b=lpx_get_row_type(lp, i);
87.235 +// double up=lpx_get_row_ub(lp, i);
87.236 +// if (lo==-INF) {
87.237 +// switch (b) {
87.238 +// case LPX_FR:
87.239 +// case LPX_LO:
87.240 +// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
87.241 +// break;
87.242 +// case LPX_UP:
87.243 +// break;
87.244 +// case LPX_DB:
87.245 +// case LPX_FX:
87.246 +// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
87.247 +// break;
87.248 +// default: ;
87.249 +// //FIXME error
87.250 +// }
87.251 +// } else {
87.252 +// switch (b) {
87.253 +// case LPX_FR:
87.254 +// case LPX_LO:
87.255 +// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
87.256 +// break;
87.257 +// case LPX_UP:
87.258 +// case LPX_DB:
87.259 +// case LPX_FX:
87.260 +// if (lo==up)
87.261 +// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
87.262 +// else
87.263 +// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
87.264 +// break;
87.265 +// default: ;
87.266 +// //FIXME error
87.267 +// }
87.268 +// }
87.269 +// }
87.270 +
87.271 +// void LpGlpk::_setRowUpperBound(int i, Value up)
87.272 +// {
87.273 +// if (up==-INF) {
87.274 +// //FIXME error
87.275 +// }
87.276 +// int b=lpx_get_row_type(lp, i);
87.277 +// double lo=lpx_get_row_lb(lp, i);
87.278 +// if (up==INF) {
87.279 +// switch (b) {
87.280 +// case LPX_FR:
87.281 +// case LPX_LO:
87.282 +// break;
87.283 +// case LPX_UP:
87.284 +// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
87.285 +// break;
87.286 +// case LPX_DB:
87.287 +// case LPX_FX:
87.288 +// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
87.289 +// break;
87.290 +// default: ;
87.291 +// //FIXME error
87.292 +// }
87.293 +// } else {
87.294 +// switch (b) {
87.295 +// case LPX_FR:
87.296 +// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
87.297 +// break;
87.298 +// case LPX_UP:
87.299 +// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
87.300 +// break;
87.301 +// case LPX_LO:
87.302 +// case LPX_DB:
87.303 +// case LPX_FX:
87.304 +// if (lo==up)
87.305 +// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
87.306 +// else
87.307 +// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
87.308 +// break;
87.309 +// default: ;
87.310 +// //FIXME error
87.311 +// }
87.312 +// }
87.313 +// }
87.314 +
87.315 + void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
87.316 + {
87.317 + //Bad parameter
87.318 + if (lb==INF || ub==-INF) {
87.319 + //FIXME error
87.320 + }
87.321 +
87.322 + if (lb == -INF){
87.323 + if (ub == INF){
87.324 + lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
87.325 + }
87.326 + else{
87.327 + lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
87.328 + }
87.329 + }
87.330 + else{
87.331 + if (ub==INF){
87.332 + lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
87.333 +
87.334 + }
87.335 + else{
87.336 + if (lb == ub){
87.337 + lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
87.338 + }
87.339 + else{
87.340 + lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
87.341 + }
87.342 + }
87.343 + }
87.344 +
87.345 + }
87.346 +
87.347 + void LpGlpk::_setObjCoeff(int i, Value obj_coef)
87.348 + {
87.349 + //i=0 means the constant term (shift)
87.350 + lpx_set_obj_coef(lp, i, obj_coef);
87.351 + }
87.352 +
87.353 + void LpGlpk::_clearObj()
87.354 + {
87.355 + for (int i=0;i<=lpx_get_num_cols(lp);++i){
87.356 + lpx_set_obj_coef(lp, i, 0);
87.357 + }
87.358 + }
87.359 +// void LpGlpk::_setObj(int length,
87.360 +// int const * indices,
87.361 +// Value const * values )
87.362 +// {
87.363 +// Value new_values[1+lpx_num_cols()];
87.364 +// for (i=0;i<=lpx_num_cols();++i){
87.365 +// new_values[i]=0;
87.366 +// }
87.367 +// for (i=1;i<=length;++i){
87.368 +// new_values[indices[i]]=values[i];
87.369 +// }
87.370 +
87.371 +// for (i=0;i<=lpx_num_cols();++i){
87.372 +// lpx_set_obj_coef(lp, i, new_values[i]);
87.373 +// }
87.374 +// }
87.375 +
87.376 + LpGlpk::SolveExitStatus LpGlpk::_solve()
87.377 + {
87.378 + int i= lpx_simplex(lp);
87.379 + switch (i) {
87.380 + case LPX_E_OK:
87.381 + return SOLVED;
87.382 + break;
87.383 + default:
87.384 + return UNSOLVED;
87.385 + }
87.386 + }
87.387 +
87.388 + LpGlpk::Value LpGlpk::_getPrimal(int i)
87.389 + {
87.390 + return lpx_get_col_prim(lp,i);
87.391 + }
87.392 +
87.393 + LpGlpk::Value LpGlpk::_getPrimalValue()
87.394 + {
87.395 + return lpx_get_obj_val(lp);
87.396 + }
87.397 +
87.398 +
87.399 + LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
87.400 + {
87.401 + int stat= lpx_get_status(lp);
87.402 + switch (stat) {
87.403 + case LPX_UNDEF://Undefined (no solve has been run yet)
87.404 + return UNDEFINED;
87.405 + break;
87.406 + case LPX_NOFEAS://There is no feasible solution (primal, I guess)
87.407 + case LPX_INFEAS://Infeasible
87.408 + return INFEASIBLE;
87.409 + break;
87.410 + case LPX_UNBND://Unbounded
87.411 + return INFINITE;
87.412 + break;
87.413 + case LPX_FEAS://Feasible
87.414 + return FEASIBLE;
87.415 + break;
87.416 + case LPX_OPT://Feasible
87.417 + return OPTIMAL;
87.418 + break;
87.419 + default:
87.420 + return UNDEFINED; //to avoid gcc warning
87.421 + //FIXME error
87.422 + }
87.423 + }
87.424 +
87.425 +
87.426 + void LpGlpk::_setMax()
87.427 + {
87.428 + lpx_set_obj_dir(lp, LPX_MAX);
87.429 + }
87.430 +
87.431 + void LpGlpk::_setMin()
87.432 + {
87.433 + lpx_set_obj_dir(lp, LPX_MIN);
87.434 + }
87.435 +
87.436 +
87.437 + void LpGlpk::messageLevel(int m)
87.438 + {
87.439 + lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
87.440 + }
87.441 +
87.442 + void LpGlpk::presolver(bool b)
87.443 + {
87.444 + lpx_set_int_parm(lp, LPX_K_PRESOL, b);
87.445 + }
87.446 +
87.447 +
87.448 +} //END OF NAMESPACE LEMON
87.449 +
87.450 +#endif //LEMON_LP_GLPK_CC
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/lemon/lp_glpk.h Mon May 23 04:48:14 2005 +0000
88.3 @@ -0,0 +1,114 @@
88.4 +/* -*- C++ -*-
88.5 + * lemon/lp_glpk.h - Part of LEMON, a generic C++ optimization library
88.6 + *
88.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
88.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
88.9 + *
88.10 + * Permission to use, modify and distribute this software is granted
88.11 + * provided that this copyright notice appears in all copies. For
88.12 + * precise terms see the accompanying LICENSE file.
88.13 + *
88.14 + * This software is provided "AS IS" with no warranty of any kind,
88.15 + * express or implied, and with no claim as to its suitability for any
88.16 + * purpose.
88.17 + *
88.18 + */
88.19 +
88.20 +#ifndef LEMON_LP_GLPK_H
88.21 +#define LEMON_LP_GLPK_H
88.22 +
88.23 +///\file
88.24 +///\brief Header of the LEMON-GLPK lp solver interface.
88.25 +///\ingroup gen_opt_group
88.26 +
88.27 +#include <lemon/lp_base.h>
88.28 +extern "C" {
88.29 +#include <glpk.h>
88.30 +}
88.31 +
88.32 +namespace lemon {
88.33 +
88.34 +
88.35 + /// \brief Interface for the GLPK LP solver
88.36 + ///
88.37 + /// This class implements an interface for the GLPK LP solver.
88.38 + ///\ingroup gen_opt_group
88.39 + class LpGlpk : public LpSolverBase {
88.40 + protected:
88.41 + LPX* lp;
88.42 +
88.43 + public:
88.44 +
88.45 + typedef LpSolverBase Parent;
88.46 +
88.47 + LpGlpk();
88.48 + ~LpGlpk();
88.49 +
88.50 + protected:
88.51 + virtual LpSolverBase &_newLp();
88.52 + virtual LpSolverBase &_copyLp();
88.53 +
88.54 + virtual int _addCol();
88.55 + virtual int _addRow();
88.56 + virtual void _eraseCol(int i);
88.57 + virtual void _eraseRow(int i);
88.58 +
88.59 + virtual void _setRowCoeffs(int i,
88.60 + int length,
88.61 + const int * indices,
88.62 + const Value * values );
88.63 + virtual void _setColCoeffs(int i,
88.64 + int length,
88.65 + const int * indices,
88.66 + const Value * values);
88.67 + virtual void _setCoeff(int row, int col, Value value);
88.68 + virtual void _setColLowerBound(int i, Value value);
88.69 + virtual void _setColUpperBound(int i, Value value);
88.70 +// virtual void _setRowLowerBound(int i, Value value);
88.71 +// virtual void _setRowUpperBound(int i, Value value);
88.72 + virtual void _setRowBounds(int i, Value lower, Value upper);
88.73 + virtual void _setObjCoeff(int i, Value obj_coef);
88.74 + virtual void _clearObj();
88.75 +// virtual void _setObj(int length,
88.76 +// int const * indices,
88.77 +// Value const * values ) = 0;
88.78 +
88.79 + ///\e
88.80 +
88.81 + ///\todo It should be clarified
88.82 + ///
88.83 + virtual SolveExitStatus _solve();
88.84 + virtual Value _getPrimal(int i);
88.85 + virtual Value _getPrimalValue();
88.86 + ///\e
88.87 +
88.88 + ///\todo It should be clarified
88.89 + ///
88.90 + virtual SolutionStatus _getPrimalStatus();
88.91 + virtual void _setMax();
88.92 + virtual void _setMin();
88.93 +
88.94 + public:
88.95 + ///Set the verbosity of the messages
88.96 +
88.97 + ///Set the verbosity of the messages
88.98 + ///
88.99 + ///\param m is the level of the messages output by the solver routines.
88.100 + ///The possible values are:
88.101 + ///- 0 --- no output (default value)
88.102 + ///- 1 --- error messages only
88.103 + ///- 2 --- normal output
88.104 + ///- 3 --- full output (includes informational messages)
88.105 + void messageLevel(int m);
88.106 + ///Turns on or off the presolver
88.107 +
88.108 + ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
88.109 + ///
88.110 + ///The presolver is off by default.
88.111 + void presolver(bool b);
88.112 +
88.113 + };
88.114 +} //END OF NAMESPACE LEMON
88.115 +
88.116 +#endif //LEMON_LP_GLPK_H
88.117 +
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/lemon/lp_skeleton.cc Mon May 23 04:48:14 2005 +0000
89.3 @@ -0,0 +1,127 @@
89.4 +/* -*- C++ -*-
89.5 + * lemon/lp_skeleton.cc - Part of LEMON, a generic C++ optimization library
89.6 + *
89.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
89.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
89.9 + *
89.10 + * Permission to use, modify and distribute this software is granted
89.11 + * provided that this copyright notice appears in all copies. For
89.12 + * precise terms see the accompanying LICENSE file.
89.13 + *
89.14 + * This software is provided "AS IS" with no warranty of any kind,
89.15 + * express or implied, and with no claim as to its suitability for any
89.16 + * purpose.
89.17 + *
89.18 + */
89.19 +
89.20 +#include <lemon/lp_skeleton.h>
89.21 +
89.22 +///\file
89.23 +///\brief A skeleton file to implement LP solver interfaces
89.24 +namespace lemon {
89.25 +
89.26 + LpSolverBase &LpSkeleton::_newLp()
89.27 + {
89.28 + LpSolverBase *tmp=0;
89.29 + return *tmp;
89.30 + }
89.31 +
89.32 + LpSolverBase &LpSkeleton::_copyLp()
89.33 + {
89.34 + LpSolverBase *tmp=0;
89.35 + return *tmp;
89.36 + }
89.37 +
89.38 + int LpSkeleton::_addCol()
89.39 + {
89.40 + return ++col_num;
89.41 + }
89.42 +
89.43 + int LpSkeleton::_addRow()
89.44 + {
89.45 + return ++row_num;
89.46 + }
89.47 +
89.48 + void LpSkeleton::_eraseCol(int ) {
89.49 + }
89.50 +
89.51 + void LpSkeleton::_eraseRow(int) {
89.52 + }
89.53 +
89.54 + void LpSkeleton::_setRowCoeffs(int,
89.55 + int,
89.56 + int const *,
89.57 + Value const *)
89.58 + {
89.59 + }
89.60 +
89.61 + void LpSkeleton::_setColCoeffs(int,
89.62 + int,
89.63 + int const *,
89.64 + Value const *)
89.65 + {
89.66 + }
89.67 +
89.68 + void LpSkeleton::_setCoeff(int, int, Value )
89.69 + {
89.70 + }
89.71 +
89.72 +
89.73 + void LpSkeleton::_setColLowerBound(int, Value)
89.74 + {
89.75 + }
89.76 +
89.77 + void LpSkeleton::_setColUpperBound(int, Value)
89.78 + {
89.79 + }
89.80 +
89.81 +// void LpSkeleton::_setRowLowerBound(int, Value)
89.82 +// {
89.83 +// }
89.84 +
89.85 +// void LpSkeleton::_setRowUpperBound(int, Value)
89.86 +// {
89.87 +// }
89.88 +
89.89 + void LpSkeleton::_setRowBounds(int, Value, Value)
89.90 + {
89.91 + }
89.92 +
89.93 + void LpSkeleton::_setObjCoeff(int, Value)
89.94 + {
89.95 + }
89.96 +
89.97 + void LpSkeleton::_setMax()
89.98 + {
89.99 + }
89.100 +
89.101 + void LpSkeleton::_setMin()
89.102 + {
89.103 + }
89.104 +
89.105 + void LpSkeleton::_clearObj()
89.106 + {
89.107 + }
89.108 +
89.109 + LpSkeleton::SolveExitStatus LpSkeleton::_solve()
89.110 + {
89.111 + return SOLVED;
89.112 + }
89.113 +
89.114 + LpSkeleton::Value LpSkeleton::_getPrimal(int)
89.115 + {
89.116 + return 0;
89.117 + }
89.118 +
89.119 + LpSkeleton::Value LpSkeleton::_getPrimalValue()
89.120 + {
89.121 + return 0;
89.122 + }
89.123 +
89.124 + LpSkeleton::SolutionStatus LpSkeleton::_getPrimalStatus()
89.125 + {
89.126 + return OPTIMAL;
89.127 + }
89.128 +
89.129 +} //namespace lemon
89.130 +
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/lemon/lp_skeleton.h Mon May 23 04:48:14 2005 +0000
90.3 @@ -0,0 +1,133 @@
90.4 +/* -*- C++ -*-
90.5 + * lemon/lp_skeleton.h - Part of LEMON, a generic C++ optimization library
90.6 + *
90.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
90.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
90.9 + *
90.10 + * Permission to use, modify and distribute this software is granted
90.11 + * provided that this copyright notice appears in all copies. For
90.12 + * precise terms see the accompanying LICENSE file.
90.13 + *
90.14 + * This software is provided "AS IS" with no warranty of any kind,
90.15 + * express or implied, and with no claim as to its suitability for any
90.16 + * purpose.
90.17 + *
90.18 + */
90.19 +
90.20 +#ifndef LEMON_LP_SKELETON
90.21 +#define LEMON_LP_SKELETON
90.22 +
90.23 +#include <lemon/lp_base.h>
90.24 +
90.25 +///\file
90.26 +///\brief A skeleton file to implement LP solver interfaces
90.27 +namespace lemon {
90.28 +
90.29 + ///A skeleton class to implement LP solver interfaces
90.30 + class LpSkeleton :public LpSolverBase {
90.31 + int col_num,row_num;
90.32 +
90.33 + protected:
90.34 + ///\e
90.35 + virtual LpSolverBase &_newLp();
90.36 + ///\e
90.37 + virtual LpSolverBase &_copyLp();
90.38 + /// \e
90.39 + virtual int _addCol();
90.40 + /// \e
90.41 + virtual int _addRow();
90.42 + /// \e
90.43 + virtual void _eraseCol(int i);
90.44 + /// \e
90.45 + virtual void _eraseRow(int i);
90.46 + /// \e
90.47 +
90.48 + /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
90.49 + ///
90.50 + virtual void _setRowCoeffs(int i,
90.51 + int length,
90.52 + int const * indices,
90.53 + Value const * values );
90.54 + /// \e
90.55 +
90.56 + /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
90.57 + ///
90.58 + virtual void _setColCoeffs(int i,
90.59 + int length,
90.60 + int const * indices,
90.61 + Value const * values );
90.62 +
90.63 + /// Set one element of the coefficient matrix
90.64 + virtual void _setCoeff(int row, int col, Value value);
90.65 +
90.66 + /// The lower bound of a variable (column) have to be given by an
90.67 + /// extended number of type Value, i.e. a finite number of type
90.68 + /// Value or -\ref INF.
90.69 + virtual void _setColLowerBound(int i, Value value);
90.70 + /// \e
90.71 +
90.72 + /// The upper bound of a variable (column) have to be given by an
90.73 + /// extended number of type Value, i.e. a finite number of type
90.74 + /// Value or \ref INF.
90.75 + virtual void _setColUpperBound(int i, Value value);
90.76 + /// \e
90.77 +
90.78 +// /// The lower bound of a linear expression (row) have to be given by an
90.79 +// /// extended number of type Value, i.e. a finite number of type
90.80 +// /// Value or -\ref INF.
90.81 +// virtual void _setRowLowerBound(int i, Value value);
90.82 +// /// \e
90.83 +
90.84 +// /// The upper bound of a linear expression (row) have to be given by an
90.85 +// /// extended number of type Value, i.e. a finite number of type
90.86 +// /// Value or \ref INF.
90.87 +// virtual void _setRowUpperBound(int i, Value value);
90.88 +
90.89 + /// The lower and upper bound of a linear expression (row) have to be
90.90 + /// given by an
90.91 + /// extended number of type Value, i.e. a finite number of type
90.92 + /// Value or +/-\ref INF.
90.93 + virtual void _setRowBounds(int i, Value lb, Value ub);
90.94 + /// \e
90.95 +
90.96 +
90.97 + /// \e
90.98 + virtual void _clearObj();
90.99 + /// \e
90.100 + virtual void _setObjCoeff(int i, Value obj_coef);
90.101 +
90.102 + ///\e
90.103 +
90.104 + ///\bug Wrong interface
90.105 + ///
90.106 + virtual SolveExitStatus _solve();
90.107 +
90.108 + ///\e
90.109 +
90.110 + ///\bug Wrong interface
90.111 + ///
90.112 + virtual Value _getPrimal(int i);
90.113 + ///\e
90.114 +
90.115 + ///\bug Wrong interface
90.116 + ///
90.117 + virtual Value _getPrimalValue();
90.118 + ///\e
90.119 +
90.120 + ///\bug Wrong interface
90.121 + ///
90.122 + virtual SolutionStatus _getPrimalStatus();
90.123 +
90.124 + ///\e
90.125 + virtual void _setMax();
90.126 + ///\e
90.127 + virtual void _setMin();
90.128 +
90.129 +
90.130 + public:
90.131 + LpSkeleton() : LpSolverBase(), col_num(0), row_num(0) {}
90.132 + };
90.133 +
90.134 +} //namespace lemon
90.135 +
90.136 +#endif // LEMON_LP_SKELETON
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/lemon/maps.h Mon May 23 04:48:14 2005 +0000
91.3 @@ -0,0 +1,841 @@
91.4 +/* -*- C++ -*-
91.5 + * lemon/maps.h - Part of LEMON, a generic C++ optimization library
91.6 + *
91.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
91.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
91.9 + *
91.10 + * Permission to use, modify and distribute this software is granted
91.11 + * provided that this copyright notice appears in all copies. For
91.12 + * precise terms see the accompanying LICENSE file.
91.13 + *
91.14 + * This software is provided "AS IS" with no warranty of any kind,
91.15 + * express or implied, and with no claim as to its suitability for any
91.16 + * purpose.
91.17 + *
91.18 + */
91.19 +
91.20 +#ifndef LEMON_MAPS_H
91.21 +#define LEMON_MAPS_H
91.22 +
91.23 +#include <lemon/graph_utils.h>
91.24 +#include <lemon/utility.h>
91.25 +
91.26 +
91.27 +///\file
91.28 +///\ingroup maps
91.29 +///\brief Miscellaneous property maps
91.30 +///
91.31 +///\todo This file has the same name as the concept file in concept/,
91.32 +/// and this is not easily detectable in docs...
91.33 +
91.34 +#include <map>
91.35 +
91.36 +namespace lemon {
91.37 +
91.38 + /// \addtogroup maps
91.39 + /// @{
91.40 +
91.41 + /// Base class of maps.
91.42 +
91.43 + /// Base class of maps.
91.44 + /// It provides the necessary <tt>typedef</tt>s required by the map concept.
91.45 + template<typename K, typename T>
91.46 + class MapBase
91.47 + {
91.48 + public:
91.49 + ///\e
91.50 + typedef K Key;
91.51 + ///\e
91.52 + typedef T Value;
91.53 + };
91.54 +
91.55 + /// Null map. (a.k.a. DoNothingMap)
91.56 +
91.57 + /// If you have to provide a map only for its type definitions,
91.58 + /// or if you have to provide a writable map, but
91.59 + /// data written to it will sent to <tt>/dev/null</tt>...
91.60 + template<typename K, typename T>
91.61 + class NullMap : public MapBase<K,T>
91.62 + {
91.63 + public:
91.64 +
91.65 + typedef True NeedCopy;
91.66 +
91.67 + /// Gives back a default constructed element.
91.68 + T operator[](const K&) const { return T(); }
91.69 + /// Absorbs the value.
91.70 + void set(const K&, const T&) {}
91.71 + };
91.72 +
91.73 + template <typename K, typename V>
91.74 + NullMap<K, V> nullMap() {
91.75 + return NullMap<K, V>();
91.76 + }
91.77 +
91.78 +
91.79 + /// Constant map.
91.80 +
91.81 + /// This is a readable map which assigns a specified value to each key.
91.82 + /// In other aspects it is equivalent to the \ref NullMap.
91.83 + /// \todo set could be used to set the value.
91.84 + template<typename K, typename T>
91.85 + class ConstMap : public MapBase<K,T>
91.86 + {
91.87 + T v;
91.88 + public:
91.89 +
91.90 + typedef True NeedCopy;
91.91 +
91.92 + /// Default constructor
91.93 +
91.94 + /// The value of the map will be uninitialized.
91.95 + /// (More exactly it will be default constructed.)
91.96 + ConstMap() {}
91.97 + ///\e
91.98 +
91.99 + /// \param _v The initial value of the map.
91.100 + ///
91.101 + ConstMap(const T &_v) : v(_v) {}
91.102 +
91.103 + T operator[](const K&) const { return v; }
91.104 + void set(const K&, const T&) {}
91.105 +
91.106 + template<typename T1>
91.107 + struct rebind {
91.108 + typedef ConstMap<K,T1> other;
91.109 + };
91.110 +
91.111 + template<typename T1>
91.112 + ConstMap(const ConstMap<K,T1> &, const T &_v) : v(_v) {}
91.113 + };
91.114 +
91.115 + ///Returns a \ref ConstMap class
91.116 +
91.117 + ///This function just returns a \ref ConstMap class.
91.118 + ///\relates ConstMap
91.119 + template<class V,class K>
91.120 + inline ConstMap<V,K> constMap(const K &k)
91.121 + {
91.122 + return ConstMap<V,K>(k);
91.123 + }
91.124 +
91.125 +
91.126 + //to document later
91.127 + template<typename T, T v>
91.128 + struct Const { };
91.129 + //to document later
91.130 + template<typename K, typename V, V v>
91.131 + class ConstMap<K, Const<V, v> > : public MapBase<K, V>
91.132 + {
91.133 + public:
91.134 + ConstMap() { }
91.135 + V operator[](const K&) const { return v; }
91.136 + void set(const K&, const V&) { }
91.137 + };
91.138 +
91.139 + /// \c std::map wrapper
91.140 +
91.141 + /// This is essentially a wrapper for \c std::map. With addition that
91.142 + /// you can specify a default value different from \c Value() .
91.143 + ///
91.144 + /// \todo Provide allocator parameter...
91.145 + template <typename K, typename T, typename Compare = std::less<K> >
91.146 + class StdMap : public std::map<K,T,Compare> {
91.147 + typedef std::map<K,T,Compare> parent;
91.148 + T v;
91.149 + typedef typename parent::value_type PairType;
91.150 +
91.151 + public:
91.152 + typedef K Key;
91.153 + typedef T Value;
91.154 + typedef T& Reference;
91.155 + typedef const T& ConstReference;
91.156 +
91.157 +
91.158 + StdMap() : v() {}
91.159 + /// Constructor with specified default value
91.160 + StdMap(const T& _v) : v(_v) {}
91.161 +
91.162 + /// \brief Constructs the map from an appropriate std::map.
91.163 + ///
91.164 + /// \warning Inefficient: copies the content of \c m !
91.165 + StdMap(const parent &m) : parent(m) {}
91.166 + /// \brief Constructs the map from an appropriate std::map, and explicitly
91.167 + /// specifies a default value.
91.168 + ///
91.169 + /// \warning Inefficient: copies the content of \c m !
91.170 + StdMap(const parent &m, const T& _v) : parent(m), v(_v) {}
91.171 +
91.172 + template<typename T1, typename Comp1>
91.173 + StdMap(const StdMap<Key,T1,Comp1> &m, const T &_v) {
91.174 + //FIXME;
91.175 + }
91.176 +
91.177 + Reference operator[](const Key &k) {
91.178 + return insert(PairType(k,v)).first -> second;
91.179 + }
91.180 + ConstReference operator[](const Key &k) const {
91.181 + typename parent::iterator i = lower_bound(k);
91.182 + if (i == parent::end() || parent::key_comp()(k, (*i).first))
91.183 + return v;
91.184 + return (*i).second;
91.185 + }
91.186 + void set(const Key &k, const T &t) {
91.187 + parent::operator[](k) = t;
91.188 + }
91.189 +
91.190 + /// Changes the default value of the map.
91.191 + /// \return Returns the previous default value.
91.192 + ///
91.193 + /// \warning The value of some keys (which has already been queried, but
91.194 + /// the value has been unchanged from the default) may change!
91.195 + T setDefault(const T &_v) { T old=v; v=_v; return old; }
91.196 +
91.197 + template<typename T1>
91.198 + struct rebind {
91.199 + typedef StdMap<Key,T1,Compare> other;
91.200 + };
91.201 + };
91.202 +
91.203 + /// @}
91.204 +
91.205 + /// \addtogroup map_adaptors
91.206 + /// @{
91.207 +
91.208 +
91.209 + ///Convert the \c Value of a maps to another type.
91.210 +
91.211 + ///This \ref concept::ReadMap "read only map"
91.212 + ///converts the \c Value of a maps to type \c T.
91.213 + ///Its \c Value is inherited from \c M.
91.214 + ///
91.215 + ///Actually,
91.216 + ///\code
91.217 + /// ConvertMap<X> sh(x,v);
91.218 + ///\endcode
91.219 + ///it is equivalent with
91.220 + ///\code
91.221 + /// ConstMap<X::Key, X::Value> c_tmp(v);
91.222 + /// AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
91.223 + ///\endcode
91.224 + ///\bug wrong documentation
91.225 + template<class M, class T>
91.226 + class ConvertMap {
91.227 + typename SmartConstReference<M>::Type m;
91.228 + public:
91.229 +
91.230 + typedef True NeedCopy;
91.231 +
91.232 + typedef typename M::Key Key;
91.233 + typedef T Value;
91.234 +
91.235 + ///Constructor
91.236 +
91.237 + ///Constructor
91.238 + ///\param _m is the undelying map
91.239 + ///\param _v is the convert value
91.240 + ConvertMap(const M &_m) : m(_m) {};
91.241 +
91.242 + /// \brief The subscript operator.
91.243 + ///
91.244 + /// The subscript operator.
91.245 + /// \param edge The edge
91.246 + /// \return The target of the edge
91.247 + Value operator[](Key k) const {return m[k];}
91.248 + };
91.249 +
91.250 + ///Returns an \ref ConvertMap class
91.251 +
91.252 + ///This function just returns an \ref ConvertMap class.
91.253 + ///\relates ConvertMap
91.254 + ///\todo The order of the template parameters are changed.
91.255 + template<class T, class M>
91.256 + inline ConvertMap<M,T> convertMap(const M &m)
91.257 + {
91.258 + return ConvertMap<M,T>(m);
91.259 + }
91.260 +
91.261 + ///Sum of two maps
91.262 +
91.263 + ///This \ref concept::ReadMap "read only map" returns the sum of the two
91.264 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
91.265 + ///The \c Key and \c Value of M2 must be convertible to those of \c M1.
91.266 +
91.267 + template<class M1,class M2>
91.268 + class AddMap
91.269 + {
91.270 + typename SmartConstReference<M1>::Type m1;
91.271 + typename SmartConstReference<M2>::Type m2;
91.272 +
91.273 + public:
91.274 +
91.275 + typedef True NeedCopy;
91.276 +
91.277 + typedef typename M1::Key Key;
91.278 + typedef typename M1::Value Value;
91.279 +
91.280 + ///Constructor
91.281 +
91.282 + ///\e
91.283 + ///
91.284 + AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.285 + Value operator[](Key k) const {return m1[k]+m2[k];}
91.286 + };
91.287 +
91.288 + ///Returns an \ref AddMap class
91.289 +
91.290 + ///This function just returns an \ref AddMap class.
91.291 + ///\todo How to call these type of functions?
91.292 + ///
91.293 + ///\relates AddMap
91.294 + ///\todo Wrong scope in Doxygen when \c \\relates is used
91.295 + template<class M1,class M2>
91.296 + inline AddMap<M1,M2> addMap(const M1 &m1,const M2 &m2)
91.297 + {
91.298 + return AddMap<M1,M2>(m1,m2);
91.299 + }
91.300 +
91.301 + ///Shift a maps with a constant.
91.302 +
91.303 + ///This \ref concept::ReadMap "read only map" returns the sum of the
91.304 + ///given map and a constant value.
91.305 + ///Its \c Key and \c Value is inherited from \c M.
91.306 + ///
91.307 + ///Actually,
91.308 + ///\code
91.309 + /// ShiftMap<X> sh(x,v);
91.310 + ///\endcode
91.311 + ///it is equivalent with
91.312 + ///\code
91.313 + /// ConstMap<X::Key, X::Value> c_tmp(v);
91.314 + /// AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
91.315 + ///\endcode
91.316 + template<class M>
91.317 + class ShiftMap
91.318 + {
91.319 + typename SmartConstReference<M>::Type m;
91.320 + typename M::Value v;
91.321 + public:
91.322 +
91.323 + typedef True NeedCopy;
91.324 + typedef typename M::Key Key;
91.325 + typedef typename M::Value Value;
91.326 +
91.327 + ///Constructor
91.328 +
91.329 + ///Constructor
91.330 + ///\param _m is the undelying map
91.331 + ///\param _v is the shift value
91.332 + ShiftMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
91.333 + Value operator[](Key k) const {return m[k]+v;}
91.334 + };
91.335 +
91.336 + ///Returns an \ref ShiftMap class
91.337 +
91.338 + ///This function just returns an \ref ShiftMap class.
91.339 + ///\relates ShiftMap
91.340 + ///\todo A better name is required.
91.341 + template<class M>
91.342 + inline ShiftMap<M> shiftMap(const M &m,const typename M::Value &v)
91.343 + {
91.344 + return ShiftMap<M>(m,v);
91.345 + }
91.346 +
91.347 + ///Difference of two maps
91.348 +
91.349 + ///This \ref concept::ReadMap "read only map" returns the difference
91.350 + ///of the values returned by the two
91.351 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
91.352 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
91.353 +
91.354 + template<class M1,class M2>
91.355 + class SubMap
91.356 + {
91.357 + typename SmartConstReference<M1>::Type m1;
91.358 + typename SmartConstReference<M2>::Type m2;
91.359 + public:
91.360 +
91.361 + typedef True NeedCopy;
91.362 + typedef typename M1::Key Key;
91.363 + typedef typename M1::Value Value;
91.364 +
91.365 + ///Constructor
91.366 +
91.367 + ///\e
91.368 + ///
91.369 + SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.370 + Value operator[](Key k) const {return m1[k]-m2[k];}
91.371 + };
91.372 +
91.373 + ///Returns a \ref SubMap class
91.374 +
91.375 + ///This function just returns a \ref SubMap class.
91.376 + ///
91.377 + ///\relates SubMap
91.378 + template<class M1,class M2>
91.379 + inline SubMap<M1,M2> subMap(const M1 &m1,const M2 &m2)
91.380 + {
91.381 + return SubMap<M1,M2>(m1,m2);
91.382 + }
91.383 +
91.384 + ///Product of two maps
91.385 +
91.386 + ///This \ref concept::ReadMap "read only map" returns the product of the
91.387 + ///values returned by the two
91.388 + ///given
91.389 + ///maps. Its \c Key and \c Value will be inherited from \c M1.
91.390 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
91.391 +
91.392 + template<class M1,class M2>
91.393 + class MulMap
91.394 + {
91.395 + typename SmartConstReference<M1>::Type m1;
91.396 + typename SmartConstReference<M2>::Type m2;
91.397 + public:
91.398 +
91.399 + typedef True NeedCopy;
91.400 + typedef typename M1::Key Key;
91.401 + typedef typename M1::Value Value;
91.402 +
91.403 + ///Constructor
91.404 +
91.405 + ///\e
91.406 + ///
91.407 + MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.408 + Value operator[](Key k) const {return m1[k]*m2[k];}
91.409 + };
91.410 +
91.411 + ///Returns a \ref MulMap class
91.412 +
91.413 + ///This function just returns a \ref MulMap class.
91.414 + ///\relates MulMap
91.415 + template<class M1,class M2>
91.416 + inline MulMap<M1,M2> mulMap(const M1 &m1,const M2 &m2)
91.417 + {
91.418 + return MulMap<M1,M2>(m1,m2);
91.419 + }
91.420 +
91.421 + ///Scale a maps with a constant.
91.422 +
91.423 + ///This \ref concept::ReadMap "read only map" returns the value of the
91.424 + ///given map multipied with a constant value.
91.425 + ///Its \c Key and \c Value is inherited from \c M.
91.426 + ///
91.427 + ///Actually,
91.428 + ///\code
91.429 + /// ScaleMap<X> sc(x,v);
91.430 + ///\endcode
91.431 + ///it is equivalent with
91.432 + ///\code
91.433 + /// ConstMap<X::Key, X::Value> c_tmp(v);
91.434 + /// MulMap<X, ConstMap<X::Key, X::Value> > sc(x,v);
91.435 + ///\endcode
91.436 + template<class M>
91.437 + class ScaleMap
91.438 + {
91.439 + typename SmartConstReference<M>::Type m;
91.440 + typename M::Value v;
91.441 + public:
91.442 +
91.443 + typedef True NeedCopy;
91.444 + typedef typename M::Key Key;
91.445 + typedef typename M::Value Value;
91.446 +
91.447 + ///Constructor
91.448 +
91.449 + ///Constructor
91.450 + ///\param _m is the undelying map
91.451 + ///\param _v is the scaling value
91.452 + ScaleMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
91.453 + Value operator[](Key k) const {return m[k]*v;}
91.454 + };
91.455 +
91.456 + ///Returns an \ref ScaleMap class
91.457 +
91.458 + ///This function just returns an \ref ScaleMap class.
91.459 + ///\relates ScaleMap
91.460 + ///\todo A better name is required.
91.461 + template<class M>
91.462 + inline ScaleMap<M> scaleMap(const M &m,const typename M::Value &v)
91.463 + {
91.464 + return ScaleMap<M>(m,v);
91.465 + }
91.466 +
91.467 + ///Quotient of two maps
91.468 +
91.469 + ///This \ref concept::ReadMap "read only map" returns the quotient of the
91.470 + ///values returned by the two
91.471 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
91.472 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
91.473 +
91.474 + template<class M1,class M2>
91.475 + class DivMap
91.476 + {
91.477 + typename SmartConstReference<M1>::Type m1;
91.478 + typename SmartConstReference<M2>::Type m2;
91.479 + public:
91.480 +
91.481 + typedef True NeedCopy;
91.482 + typedef typename M1::Key Key;
91.483 + typedef typename M1::Value Value;
91.484 +
91.485 + ///Constructor
91.486 +
91.487 + ///\e
91.488 + ///
91.489 + DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.490 + Value operator[](Key k) const {return m1[k]/m2[k];}
91.491 + };
91.492 +
91.493 + ///Returns a \ref DivMap class
91.494 +
91.495 + ///This function just returns a \ref DivMap class.
91.496 + ///\relates DivMap
91.497 + template<class M1,class M2>
91.498 + inline DivMap<M1,M2> divMap(const M1 &m1,const M2 &m2)
91.499 + {
91.500 + return DivMap<M1,M2>(m1,m2);
91.501 + }
91.502 +
91.503 + ///Composition of two maps
91.504 +
91.505 + ///This \ref concept::ReadMap "read only map" returns the composition of
91.506 + ///two
91.507 + ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is
91.508 + ///of \c M2,
91.509 + ///then for
91.510 + ///\code
91.511 + /// ComposeMap<M1,M2> cm(m1,m2);
91.512 + ///\endcode
91.513 + /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>
91.514 + ///
91.515 + ///Its \c Key is inherited from \c M2 and its \c Value is from
91.516 + ///\c M1.
91.517 + ///The \c M2::Value must be convertible to \c M1::Key.
91.518 + ///\todo Check the requirements.
91.519 +
91.520 + template<class M1,class M2>
91.521 + class ComposeMap
91.522 + {
91.523 + typename SmartConstReference<M1>::Type m1;
91.524 + typename SmartConstReference<M2>::Type m2;
91.525 + public:
91.526 +
91.527 + typedef True NeedCopy;
91.528 + typedef typename M2::Key Key;
91.529 + typedef typename M1::Value Value;
91.530 +
91.531 + typedef True NeedCopy;
91.532 +
91.533 + ///Constructor
91.534 +
91.535 + ///\e
91.536 + ///
91.537 + ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.538 + Value operator[](Key k) const {return m1[m2[k]];}
91.539 + };
91.540 + ///Returns a \ref ComposeMap class
91.541 +
91.542 + ///This function just returns a \ref ComposeMap class.
91.543 + ///
91.544 + ///\relates ComposeMap
91.545 + template<class M1,class M2>
91.546 + inline ComposeMap<M1,M2> composeMap(const M1 &m1,const M2 &m2)
91.547 + {
91.548 + return ComposeMap<M1,M2>(m1,m2);
91.549 + }
91.550 +
91.551 + ///Combine of two maps using an STL (binary) functor.
91.552 +
91.553 + ///Combine of two maps using an STL (binary) functor.
91.554 + ///
91.555 + ///
91.556 + ///This \ref concept::ReadMap "read only map" takes to maps and a
91.557 + ///binary functor and returns the composition of
91.558 + ///two
91.559 + ///given maps unsing the functor.
91.560 + ///That is to say, if \c m1 and \c m2 is of type \c M1 and \c M2
91.561 + ///and \c f is of \c F,
91.562 + ///then for
91.563 + ///\code
91.564 + /// CombineMap<M1,M2,F,V> cm(m1,m2,f);
91.565 + ///\endcode
91.566 + /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>
91.567 + ///
91.568 + ///Its \c Key is inherited from \c M1 and its \c Value is \c V.
91.569 + ///The \c M2::Value and \c M1::Value must be convertible to the corresponding
91.570 + ///input parameter of \c F and the return type of \c F must be convertible
91.571 + ///to \c V.
91.572 + ///\todo Check the requirements.
91.573 +
91.574 + template<class M1,class M2,class F,class V = typename F::result_type>
91.575 + class CombineMap
91.576 + {
91.577 + typename SmartConstReference<M1>::Type m1;
91.578 + typename SmartConstReference<M2>::Type m2;
91.579 + F f;
91.580 + public:
91.581 +
91.582 + typedef True NeedCopy;
91.583 + typedef typename M1::Key Key;
91.584 + typedef V Value;
91.585 +
91.586 + ///Constructor
91.587 +
91.588 + ///\e
91.589 + ///
91.590 + CombineMap(const M1 &_m1,const M2 &_m2,const F &_f)
91.591 + : m1(_m1), m2(_m2), f(_f) {};
91.592 + Value operator[](Key k) const {return f(m1[k],m2[k]);}
91.593 + };
91.594 +
91.595 + ///Returns a \ref CombineMap class
91.596 +
91.597 + ///This function just returns a \ref CombineMap class.
91.598 + ///
91.599 + ///Only the first template parameter (the value type) must be given.
91.600 + ///
91.601 + ///For example if \c m1 and \c m2 are both \c double valued maps, then
91.602 + ///\code
91.603 + ///combineMap<double>(m1,m2,std::plus<double>)
91.604 + ///\endcode
91.605 + ///is equivalent with
91.606 + ///\code
91.607 + ///addMap(m1,m2)
91.608 + ///\endcode
91.609 + ///
91.610 + ///\relates CombineMap
91.611 + template<class M1,class M2,class F>
91.612 + inline CombineMap<M1,M2,F> combineMap(const M1 &m1,const M2 &m2,const F &f)
91.613 + {
91.614 + return CombineMap<M1,M2,F>(m1,m2,f);
91.615 + }
91.616 +
91.617 + ///Negative value of a map
91.618 +
91.619 + ///This \ref concept::ReadMap "read only map" returns the negative
91.620 + ///value of the
91.621 + ///value returned by the
91.622 + ///given map. Its \c Key and \c Value will be inherited from \c M.
91.623 + ///The unary \c - operator must be defined for \c Value, of course.
91.624 +
91.625 + template<class M>
91.626 + class NegMap
91.627 + {
91.628 + typename SmartConstReference<M>::Type m;
91.629 + public:
91.630 +
91.631 + typedef True NeedCopy;
91.632 + typedef typename M::Key Key;
91.633 + typedef typename M::Value Value;
91.634 +
91.635 + ///Constructor
91.636 +
91.637 + ///\e
91.638 + ///
91.639 + NegMap(const M &_m) : m(_m) {};
91.640 + Value operator[](Key k) const {return -m[k];}
91.641 + };
91.642 +
91.643 + ///Returns a \ref NegMap class
91.644 +
91.645 + ///This function just returns a \ref NegMap class.
91.646 + ///\relates NegMap
91.647 + template<class M>
91.648 + inline NegMap<M> negMap(const M &m)
91.649 + {
91.650 + return NegMap<M>(m);
91.651 + }
91.652 +
91.653 +
91.654 + ///Absolute value of a map
91.655 +
91.656 + ///This \ref concept::ReadMap "read only map" returns the absolute value
91.657 + ///of the
91.658 + ///value returned by the
91.659 + ///given map. Its \c Key and \c Value will be inherited
91.660 + ///from <tt>M</tt>. <tt>Value</tt>
91.661 + ///must be comparable to <tt>0</tt> and the unary <tt>-</tt>
91.662 + ///operator must be defined for it, of course.
91.663 + ///
91.664 + ///\bug We need a unified way to handle the situation below:
91.665 + ///\code
91.666 + /// struct _UnConvertible {};
91.667 + /// template<class A> inline A t_abs(A a) {return _UnConvertible();}
91.668 + /// template<> inline int t_abs<>(int n) {return abs(n);}
91.669 + /// template<> inline long int t_abs<>(long int n) {return labs(n);}
91.670 + /// template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);}
91.671 + /// template<> inline float t_abs<>(float n) {return fabsf(n);}
91.672 + /// template<> inline double t_abs<>(double n) {return fabs(n);}
91.673 + /// template<> inline long double t_abs<>(long double n) {return fabsl(n);}
91.674 + ///\endcode
91.675 +
91.676 +
91.677 + template<class M>
91.678 + class AbsMap
91.679 + {
91.680 + typename SmartConstReference<M>::Type m;
91.681 + public:
91.682 +
91.683 + typedef True NeedCopy;
91.684 + typedef typename M::Key Key;
91.685 + typedef typename M::Value Value;
91.686 +
91.687 + ///Constructor
91.688 +
91.689 + ///\e
91.690 + ///
91.691 + AbsMap(const M &_m) : m(_m) {};
91.692 + Value operator[](Key k) const {Value tmp=m[k]; return tmp>=0?tmp:-tmp;}
91.693 + };
91.694 +
91.695 + ///Returns a \ref AbsMap class
91.696 +
91.697 + ///This function just returns a \ref AbsMap class.
91.698 + ///\relates AbsMap
91.699 + template<class M>
91.700 + inline AbsMap<M> absMap(const M &m)
91.701 + {
91.702 + return AbsMap<M>(m);
91.703 + }
91.704 +
91.705 + ///Converts an STL style functor to a map
91.706 +
91.707 + ///This \ref concept::ReadMap "read only map" returns the value
91.708 + ///of a
91.709 + ///given map.
91.710 + ///
91.711 + ///Template parameters \c K and \c V will become its
91.712 + ///\c Key and \c Value. They must be given explicitely
91.713 + ///because a functor does not provide such typedefs.
91.714 + ///
91.715 + ///Parameter \c F is the type of the used functor.
91.716 +
91.717 +
91.718 + template<class K,class V,class F>
91.719 + class FunctorMap
91.720 + {
91.721 + const F &f;
91.722 + public:
91.723 +
91.724 + typedef True NeedCopy;
91.725 + typedef K Key;
91.726 + typedef V Value;
91.727 +
91.728 + ///Constructor
91.729 +
91.730 + ///\e
91.731 + ///
91.732 + FunctorMap(const F &_f) : f(_f) {};
91.733 + Value operator[](Key k) const {return f(k);}
91.734 + };
91.735 +
91.736 + ///Returns a \ref FunctorMap class
91.737 +
91.738 + ///This function just returns a \ref FunctorMap class.
91.739 + ///
91.740 + ///The third template parameter isn't necessary to be given.
91.741 + ///\relates FunctorMap
91.742 + template<class K,class V, class F>
91.743 + inline FunctorMap<K,V,F> functorMap(const F &f)
91.744 + {
91.745 + return FunctorMap<K,V,F>(f);
91.746 + }
91.747 +
91.748 + ///Converts a map to an STL style (unary) functor
91.749 +
91.750 + ///This class Converts a map to an STL style (unary) functor.
91.751 + ///that is it provides an <tt>operator()</tt> to read its values.
91.752 + ///
91.753 + ///For the sake of convenience it also works as
91.754 + ///a ususal \ref concept::ReadMap "readable map", i.e
91.755 + ///<tt>operator[]</tt> and the \c Key and \c Value typedefs also exist.
91.756 +
91.757 + template<class M>
91.758 + class MapFunctor
91.759 + {
91.760 + typename SmartConstReference<M>::Type m;
91.761 + public:
91.762 +
91.763 + typedef True NeedCopy;
91.764 + typedef typename M::Key argument_type;
91.765 + typedef typename M::Value result_type;
91.766 + typedef typename M::Key Key;
91.767 + typedef typename M::Value Value;
91.768 +
91.769 + ///Constructor
91.770 +
91.771 + ///\e
91.772 + ///
91.773 + MapFunctor(const M &_m) : m(_m) {};
91.774 + ///Returns a value of the map
91.775 +
91.776 + ///\e
91.777 + ///
91.778 + Value operator()(Key k) const {return m[k];}
91.779 + ///\e
91.780 + ///
91.781 + Value operator[](Key k) const {return m[k];}
91.782 + };
91.783 +
91.784 + ///Returns a \ref MapFunctor class
91.785 +
91.786 + ///This function just returns a \ref MapFunctor class.
91.787 + ///\relates MapFunctor
91.788 + template<class M>
91.789 + inline MapFunctor<M> mapFunctor(const M &m)
91.790 + {
91.791 + return MapFunctor<M>(m);
91.792 + }
91.793 +
91.794 +
91.795 + ///Apply all map setting operations to two maps
91.796 +
91.797 + ///This map has two \ref concept::WriteMap "writable map"
91.798 + ///parameters and each write request will be passed to both of them.
91.799 + ///If \c M1 is also \ref concept::ReadMap "readable",
91.800 + ///then the read operations will return the
91.801 + ///corresponding values of \c M1.
91.802 + ///
91.803 + ///The \c Key and \c Value will be inherited from \c M1.
91.804 + ///The \c Key and \c Value of M2 must be convertible from those of \c M1.
91.805 +
91.806 + template<class M1,class M2>
91.807 + class ForkMap
91.808 + {
91.809 + typename SmartConstReference<M1>::Type m1;
91.810 + typename SmartConstReference<M2>::Type m2;
91.811 + public:
91.812 +
91.813 + typedef True NeedCopy;
91.814 + typedef typename M1::Key Key;
91.815 + typedef typename M1::Value Value;
91.816 +
91.817 + ///Constructor
91.818 +
91.819 + ///\e
91.820 + ///
91.821 + ForkMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
91.822 + Value operator[](Key k) const {return m1[k];}
91.823 + void set(Key k,const Value &v) {m1.set(k,v); m2.set(k,v);}
91.824 + };
91.825 +
91.826 + ///Returns an \ref ForkMap class
91.827 +
91.828 + ///This function just returns an \ref ForkMap class.
91.829 + ///\todo How to call these type of functions?
91.830 + ///
91.831 + ///\relates ForkMap
91.832 + ///\todo Wrong scope in Doxygen when \c \\relates is used
91.833 + template<class M1,class M2>
91.834 + inline ForkMap<M1,M2> forkMap(const M1 &m1,const M2 &m2)
91.835 + {
91.836 + return ForkMap<M1,M2>(m1,m2);
91.837 + }
91.838 +
91.839 + /// @}
91.840 +
91.841 +}
91.842 +
91.843 +
91.844 +#endif // LEMON_MAPS_H
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/lemon/max_matching.h Mon May 23 04:48:14 2005 +0000
92.3 @@ -0,0 +1,583 @@
92.4 +/* -*- C++ -*-
92.5 + * lemon/max_matching.h - Part of LEMON, a generic C++ optimization library
92.6 + *
92.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
92.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
92.9 + *
92.10 + * Permission to use, modify and distribute this software is granted
92.11 + * provided that this copyright notice appears in all copies. For
92.12 + * precise terms see the accompanying LICENSE file.
92.13 + *
92.14 + * This software is provided "AS IS" with no warranty of any kind,
92.15 + * express or implied, and with no claim as to its suitability for any
92.16 + * purpose.
92.17 + *
92.18 + */
92.19 +
92.20 +#ifndef LEMON_MAX_MATCHING_H
92.21 +#define LEMON_MAX_MATCHING_H
92.22 +
92.23 +#include <queue>
92.24 +#include <lemon/invalid.h>
92.25 +#include <lemon/unionfind.h>
92.26 +#include <lemon/graph_utils.h>
92.27 +
92.28 +///\ingroup galgs
92.29 +///\file
92.30 +///\brief Maximum matching algorithm.
92.31 +
92.32 +namespace lemon {
92.33 +
92.34 + /// \addtogroup galgs
92.35 + /// @{
92.36 +
92.37 + ///Edmonds' alternating forest maximum matching algorithm.
92.38 +
92.39 + ///This class provides Edmonds' alternating forest matching
92.40 + ///algorithm. The starting matching (if any) can be passed to the
92.41 + ///algorithm using read-in functions \ref readNMapNode, \ref
92.42 + ///readNMapEdge or \ref readEMapBool depending on the container. The
92.43 + ///resulting maximum matching can be attained by write-out functions
92.44 + ///\ref writeNMapNode, \ref writeNMapEdge or \ref writeEMapBool
92.45 + ///depending on the preferred container.
92.46 + ///
92.47 + ///The dual side of a matching is a map of the nodes to
92.48 + ///MaxMatching::pos_enum, having values D, A and C showing the
92.49 + ///Gallai-Edmonds decomposition of the graph. The nodes in D induce
92.50 + ///a graph with factor-critical components, the nodes in A form the
92.51 + ///barrier, and the nodes in C induce a graph having a perfect
92.52 + ///matching. This decomposition can be attained by calling \ref
92.53 + ///writePos after running the algorithm.
92.54 + ///
92.55 + ///\param Graph The undirected graph type the algorithm runs on.
92.56 + ///
92.57 + ///\author Jacint Szabo
92.58 + template <typename Graph>
92.59 + class MaxMatching {
92.60 +
92.61 + protected:
92.62 +
92.63 + typedef typename Graph::Node Node;
92.64 + typedef typename Graph::Edge Edge;
92.65 + typedef typename Graph::UndirEdge UndirEdge;
92.66 + typedef typename Graph::UndirEdgeIt UndirEdgeIt;
92.67 + typedef typename Graph::NodeIt NodeIt;
92.68 + typedef typename Graph::IncEdgeIt IncEdgeIt;
92.69 +
92.70 + typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
92.71 +
92.72 + public:
92.73 +
92.74 + ///Indicates the Gallai-Edmonds decomposition of the graph.
92.75 +
92.76 + ///Indicates the Gallai-Edmonds decomposition of the graph, which
92.77 + ///shows an upper bound on the size of a maximum matching. The
92.78 + ///nodes with pos_enum \c D induce a graph with factor-critical
92.79 + ///components, the nodes in \c A form the canonical barrier, and the
92.80 + ///nodes in \c C induce a graph having a perfect matching.
92.81 + enum pos_enum {
92.82 + D=0,
92.83 + A=1,
92.84 + C=2
92.85 + };
92.86 +
92.87 + protected:
92.88 +
92.89 + static const int HEUR_density=2;
92.90 + const Graph& g;
92.91 + typename Graph::template NodeMap<Node> _mate;
92.92 + typename Graph::template NodeMap<pos_enum> position;
92.93 +
92.94 + public:
92.95 +
92.96 + MaxMatching(const Graph& _g) : g(_g), _mate(_g,INVALID), position(_g) {}
92.97 +
92.98 + ///Runs Edmonds' algorithm.
92.99 +
92.100 + ///Runs Edmonds' algorithm for sparse graphs (number of edges <
92.101 + ///2*number of nodes), and a heuristical Edmonds' algorithm with a
92.102 + ///heuristic of postponing shrinks for dense graphs.
92.103 + inline void run();
92.104 +
92.105 + ///Runs Edmonds' algorithm.
92.106 +
92.107 + ///If heur=0 it runs Edmonds' algorithm. If heur=1 it runs
92.108 + ///Edmonds' algorithm with a heuristic of postponing shrinks,
92.109 + ///giving a faster algorithm for dense graphs.
92.110 + void runEdmonds( int heur );
92.111 +
92.112 + ///Finds a greedy matching starting from the actual matching.
92.113 +
92.114 + ///Starting form the actual matching stored, it finds a maximal
92.115 + ///greedy matching.
92.116 + void greedyMatching();
92.117 +
92.118 + ///Returns the size of the actual matching stored.
92.119 +
92.120 + ///Returns the size of the actual matching stored. After \ref
92.121 + ///run() it returns the size of a maximum matching in the graph.
92.122 + int size() const;
92.123 +
92.124 + ///Resets the actual matching to the empty matching.
92.125 +
92.126 + ///Resets the actual matching to the empty matching.
92.127 + ///
92.128 + void resetMatching();
92.129 +
92.130 + ///Returns the mate of a node in the actual matching.
92.131 +
92.132 + ///Returns the mate of a \c node in the actual matching.
92.133 + ///Returns INVALID if the \c node is not covered by the actual matching.
92.134 + Node mate(Node& node) const {
92.135 + return _mate[node];
92.136 + }
92.137 +
92.138 + ///Reads a matching from a \c Node valued \c Node map.
92.139 +
92.140 + ///Reads a matching from a \c Node valued \c Node map. This map
92.141 + ///must be \e symmetric, i.e. if \c map[u]==v then \c map[v]==u
92.142 + ///must hold, and \c uv will be an edge of the matching.
92.143 + template<typename NMapN>
92.144 + void readNMapNode(NMapN& map) {
92.145 + for(NodeIt v(g); v!=INVALID; ++v) {
92.146 + _mate.set(v,map[v]);
92.147 + }
92.148 + }
92.149 +
92.150 + ///Writes the stored matching to a \c Node valued \c Node map.
92.151 +
92.152 + ///Writes the stored matching to a \c Node valued \c Node map. The
92.153 + ///resulting map will be \e symmetric, i.e. if \c map[u]==v then \c
92.154 + ///map[v]==u will hold, and now \c uv is an edge of the matching.
92.155 + template<typename NMapN>
92.156 + void writeNMapNode (NMapN& map) const {
92.157 + for(NodeIt v(g); v!=INVALID; ++v) {
92.158 + map.set(v,_mate[v]);
92.159 + }
92.160 + }
92.161 +
92.162 + ///Reads a matching from an \c UndirEdge valued \c Node map.
92.163 +
92.164 + ///Reads a matching from an \c UndirEdge valued \c Node map. \c
92.165 + ///map[v] must be an \c UndirEdge incident to \c v. This map must
92.166 + ///have the property that if \c g.oppositeNode(u,map[u])==v then
92.167 + ///\c \c g.oppositeNode(v,map[v])==u holds, and now some edge
92.168 + ///joining \c u to \c v will be an edge of the matching.
92.169 + template<typename NMapE>
92.170 + void readNMapEdge(NMapE& map) {
92.171 + for(NodeIt v(g); v!=INVALID; ++v) {
92.172 + UndirEdge e=map[v];
92.173 + if ( e!=INVALID )
92.174 + _mate.set(v,g.oppositeNode(v,e));
92.175 + }
92.176 + }
92.177 +
92.178 + ///Writes the matching stored to an \c UndirEdge valued \c Node map.
92.179 +
92.180 + ///Writes the stored matching to an \c UndirEdge valued \c Node
92.181 + ///map. \c map[v] will be an \c UndirEdge incident to \c v. This
92.182 + ///map will have the property that if \c g.oppositeNode(u,map[u])
92.183 + ///== v then \c map[u]==map[v] holds, and now this edge is an edge
92.184 + ///of the matching.
92.185 + template<typename NMapE>
92.186 + void writeNMapEdge (NMapE& map) const {
92.187 + typename Graph::template NodeMap<bool> todo(g,true);
92.188 + for(NodeIt v(g); v!=INVALID; ++v) {
92.189 + if ( todo[v] && _mate[v]!=INVALID ) {
92.190 + Node u=_mate[v];
92.191 + for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
92.192 + if ( g.runningNode(e) == u ) {
92.193 + map.set(u,e);
92.194 + map.set(v,e);
92.195 + todo.set(u,false);
92.196 + todo.set(v,false);
92.197 + break;
92.198 + }
92.199 + }
92.200 + }
92.201 + }
92.202 + }
92.203 +
92.204 +
92.205 + ///Reads a matching from a \c bool valued \c Edge map.
92.206 +
92.207 + ///Reads a matching from a \c bool valued \c Edge map. This map
92.208 + ///must have the property that there are no two incident edges \c
92.209 + ///e, \c f with \c map[e]==map[f]==true. The edges \c e with \c
92.210 + ///map[e]==true form the matching.
92.211 + template<typename EMapB>
92.212 + void readEMapBool(EMapB& map) {
92.213 + for(UndirEdgeIt e(g); e!=INVALID; ++e) {
92.214 + if ( map[e] ) {
92.215 + Node u=g.source(e);
92.216 + Node v=g.target(e);
92.217 + _mate.set(u,v);
92.218 + _mate.set(v,u);
92.219 + }
92.220 + }
92.221 + }
92.222 +
92.223 +
92.224 + ///Writes the matching stored to a \c bool valued \c Edge map.
92.225 +
92.226 + ///Writes the matching stored to a \c bool valued \c Edge
92.227 + ///map. This map will have the property that there are no two
92.228 + ///incident edges \c e, \c f with \c map[e]==map[f]==true. The
92.229 + ///edges \c e with \c map[e]==true form the matching.
92.230 + template<typename EMapB>
92.231 + void writeEMapBool (EMapB& map) const {
92.232 + for(UndirEdgeIt e(g); e!=INVALID; ++e) map.set(e,false);
92.233 +
92.234 + typename Graph::template NodeMap<bool> todo(g,true);
92.235 + for(NodeIt v(g); v!=INVALID; ++v) {
92.236 + if ( todo[v] && _mate[v]!=INVALID ) {
92.237 + Node u=_mate[v];
92.238 + for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
92.239 + if ( g.runningNode(e) == u ) {
92.240 + map.set(e,true);
92.241 + todo.set(u,false);
92.242 + todo.set(v,false);
92.243 + break;
92.244 + }
92.245 + }
92.246 + }
92.247 + }
92.248 + }
92.249 +
92.250 +
92.251 + ///Writes the canonical decomposition of the graph after running
92.252 + ///the algorithm.
92.253 +
92.254 + ///After calling any run methods of the class, it writes the
92.255 + ///Gallai-Edmonds canonical decomposition of the graph. \c map
92.256 + ///must be a node map of \ref pos_enum 's.
92.257 + template<typename NMapEnum>
92.258 + void writePos (NMapEnum& map) const {
92.259 + for(NodeIt v(g); v!=INVALID; ++v) map.set(v,position[v]);
92.260 + }
92.261 +
92.262 + private:
92.263 +
92.264 +
92.265 + void lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,
92.266 + UFE& blossom, UFE& tree);
92.267 +
92.268 + void normShrink(Node v, typename Graph::template NodeMap<Node>& ear,
92.269 + UFE& blossom, UFE& tree);
92.270 +
92.271 + bool noShrinkStep(Node x, typename Graph::template NodeMap<Node>& ear,
92.272 + UFE& blossom, UFE& tree, std::queue<Node>& Q);
92.273 +
92.274 + void shrinkStep(Node& top, Node& middle, Node& bottom,
92.275 + typename Graph::template NodeMap<Node>& ear,
92.276 + UFE& blossom, UFE& tree, std::queue<Node>& Q);
92.277 +
92.278 + void augment(Node x, typename Graph::template NodeMap<Node>& ear,
92.279 + UFE& blossom, UFE& tree);
92.280 +
92.281 + };
92.282 +
92.283 +
92.284 + // **********************************************************************
92.285 + // IMPLEMENTATIONS
92.286 + // **********************************************************************
92.287 +
92.288 +
92.289 + template <typename Graph>
92.290 + void MaxMatching<Graph>::run() {
92.291 + if ( countUndirEdges(g) < HEUR_density*countNodes(g) ) {
92.292 + greedyMatching();
92.293 + runEdmonds(0);
92.294 + } else runEdmonds(1);
92.295 + }
92.296 +
92.297 +
92.298 + template <typename Graph>
92.299 + void MaxMatching<Graph>::runEdmonds( int heur=1 ) {
92.300 +
92.301 + for(NodeIt v(g); v!=INVALID; ++v)
92.302 + position.set(v,C);
92.303 +
92.304 + typename Graph::template NodeMap<Node> ear(g,INVALID);
92.305 + //undefined for the base nodes of the blossoms (i.e. for the
92.306 + //representative elements of UFE blossom) and for the nodes in C
92.307 +
92.308 + typename UFE::MapType blossom_base(g);
92.309 + UFE blossom(blossom_base);
92.310 + typename UFE::MapType tree_base(g);
92.311 + UFE tree(tree_base);
92.312 + //If these UFE's would be members of the class then also
92.313 + //blossom_base and tree_base should be a member.
92.314 +
92.315 + for(NodeIt v(g); v!=INVALID; ++v) {
92.316 + if ( position[v]==C && _mate[v]==INVALID ) {
92.317 + blossom.insert(v);
92.318 + tree.insert(v);
92.319 + position.set(v,D);
92.320 + if ( heur == 1 ) lateShrink( v, ear, blossom, tree );
92.321 + else normShrink( v, ear, blossom, tree );
92.322 + }
92.323 + }
92.324 + }
92.325 +
92.326 +
92.327 + template <typename Graph>
92.328 + void MaxMatching<Graph>::lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,
92.329 + UFE& blossom, UFE& tree) {
92.330 +
92.331 + std::queue<Node> Q; //queue of the totally unscanned nodes
92.332 + Q.push(v);
92.333 + std::queue<Node> R;
92.334 + //queue of the nodes which must be scanned for a possible shrink
92.335 +
92.336 + while ( !Q.empty() ) {
92.337 + Node x=Q.front();
92.338 + Q.pop();
92.339 + if ( noShrinkStep( x, ear, blossom, tree, Q ) ) return;
92.340 + else R.push(x);
92.341 + }
92.342 +
92.343 + while ( !R.empty() ) {
92.344 + Node x=R.front();
92.345 + R.pop();
92.346 +
92.347 + for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) {
92.348 + Node y=g.runningNode(e);
92.349 +
92.350 + if ( position[y] == D && blossom.find(x) != blossom.find(y) ) {
92.351 + //x and y must be in the same tree
92.352 +
92.353 + typename Graph::template NodeMap<bool> path(g,false);
92.354 +
92.355 + Node b=blossom.find(x);
92.356 + path.set(b,true);
92.357 + b=_mate[b];
92.358 + while ( b!=INVALID ) {
92.359 + b=blossom.find(ear[b]);
92.360 + path.set(b,true);
92.361 + b=_mate[b];
92.362 + } //going till the root
92.363 +
92.364 + Node top=y;
92.365 + Node middle=blossom.find(top);
92.366 + Node bottom=x;
92.367 + while ( !path[middle] )
92.368 + shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
92.369 +
92.370 + Node base=middle;
92.371 + top=x;
92.372 + middle=blossom.find(top);
92.373 + bottom=y;
92.374 + Node blossom_base=blossom.find(base);
92.375 + while ( middle!=blossom_base )
92.376 + shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
92.377 +
92.378 + blossom.makeRep(base);
92.379 + } // if shrink is needed
92.380 +
92.381 + while ( !Q.empty() ) {
92.382 + Node x=Q.front();
92.383 + Q.pop();
92.384 + if ( noShrinkStep(x, ear, blossom, tree, Q) ) return;
92.385 + else R.push(x);
92.386 + }
92.387 + } //for e
92.388 + } // while ( !R.empty() )
92.389 + }
92.390 +
92.391 +
92.392 + template <typename Graph>
92.393 + void MaxMatching<Graph>::normShrink(Node v,
92.394 + typename Graph::template
92.395 + NodeMap<Node>& ear,
92.396 + UFE& blossom, UFE& tree) {
92.397 + std::queue<Node> Q; //queue of the unscanned nodes
92.398 + Q.push(v);
92.399 + while ( !Q.empty() ) {
92.400 +
92.401 + Node x=Q.front();
92.402 + Q.pop();
92.403 +
92.404 + for( IncEdgeIt e(g,x); e!=INVALID; ++e ) {
92.405 + Node y=g.runningNode(e);
92.406 +
92.407 + switch ( position[y] ) {
92.408 + case D: //x and y must be in the same tree
92.409 +
92.410 + if ( blossom.find(x) != blossom.find(y) ) { //shrink
92.411 + typename Graph::template NodeMap<bool> path(g,false);
92.412 +
92.413 + Node b=blossom.find(x);
92.414 + path.set(b,true);
92.415 + b=_mate[b];
92.416 + while ( b!=INVALID ) {
92.417 + b=blossom.find(ear[b]);
92.418 + path.set(b,true);
92.419 + b=_mate[b];
92.420 + } //going till the root
92.421 +
92.422 + Node top=y;
92.423 + Node middle=blossom.find(top);
92.424 + Node bottom=x;
92.425 + while ( !path[middle] )
92.426 + shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
92.427 +
92.428 + Node base=middle;
92.429 + top=x;
92.430 + middle=blossom.find(top);
92.431 + bottom=y;
92.432 + Node blossom_base=blossom.find(base);
92.433 + while ( middle!=blossom_base )
92.434 + shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
92.435 +
92.436 + blossom.makeRep(base);
92.437 + }
92.438 + break;
92.439 + case C:
92.440 + if ( _mate[y]!=INVALID ) { //grow
92.441 +
92.442 + ear.set(y,x);
92.443 + Node w=_mate[y];
92.444 + blossom.insert(w);
92.445 + position.set(y,A);
92.446 + position.set(w,D);
92.447 + tree.insert(y);
92.448 + tree.insert(w);
92.449 + tree.join(y,blossom.find(x));
92.450 + tree.join(w,y);
92.451 + Q.push(w);
92.452 + } else { //augment
92.453 + augment(x, ear, blossom, tree);
92.454 + _mate.set(x,y);
92.455 + _mate.set(y,x);
92.456 + return;
92.457 + } //if
92.458 + break;
92.459 + default: break;
92.460 + }
92.461 + }
92.462 + }
92.463 + }
92.464 +
92.465 + template <typename Graph>
92.466 + void MaxMatching<Graph>::greedyMatching() {
92.467 + for(NodeIt v(g); v!=INVALID; ++v)
92.468 + if ( _mate[v]==INVALID ) {
92.469 + for( IncEdgeIt e(g,v); e!=INVALID ; ++e ) {
92.470 + Node y=g.runningNode(e);
92.471 + if ( _mate[y]==INVALID && y!=v ) {
92.472 + _mate.set(v,y);
92.473 + _mate.set(y,v);
92.474 + break;
92.475 + }
92.476 + }
92.477 + }
92.478 + }
92.479 +
92.480 + template <typename Graph>
92.481 + int MaxMatching<Graph>::size() const {
92.482 + int s=0;
92.483 + for(NodeIt v(g); v!=INVALID; ++v) {
92.484 + if ( _mate[v]!=INVALID ) {
92.485 + ++s;
92.486 + }
92.487 + }
92.488 + return s/2;
92.489 + }
92.490 +
92.491 + template <typename Graph>
92.492 + void MaxMatching<Graph>::resetMatching() {
92.493 + for(NodeIt v(g); v!=INVALID; ++v)
92.494 + _mate.set(v,INVALID);
92.495 + }
92.496 +
92.497 + template <typename Graph>
92.498 + bool MaxMatching<Graph>::noShrinkStep(Node x,
92.499 + typename Graph::template
92.500 + NodeMap<Node>& ear,
92.501 + UFE& blossom, UFE& tree,
92.502 + std::queue<Node>& Q) {
92.503 + for( IncEdgeIt e(g,x); e!= INVALID; ++e ) {
92.504 + Node y=g.runningNode(e);
92.505 +
92.506 + if ( position[y]==C ) {
92.507 + if ( _mate[y]!=INVALID ) { //grow
92.508 + ear.set(y,x);
92.509 + Node w=_mate[y];
92.510 + blossom.insert(w);
92.511 + position.set(y,A);
92.512 + position.set(w,D);
92.513 + tree.insert(y);
92.514 + tree.insert(w);
92.515 + tree.join(y,blossom.find(x));
92.516 + tree.join(w,y);
92.517 + Q.push(w);
92.518 + } else { //augment
92.519 + augment(x, ear, blossom, tree);
92.520 + _mate.set(x,y);
92.521 + _mate.set(y,x);
92.522 + return true;
92.523 + }
92.524 + }
92.525 + }
92.526 + return false;
92.527 + }
92.528 +
92.529 + template <typename Graph>
92.530 + void MaxMatching<Graph>::shrinkStep(Node& top, Node& middle, Node& bottom,
92.531 + typename Graph::template
92.532 + NodeMap<Node>& ear,
92.533 + UFE& blossom, UFE& tree,
92.534 + std::queue<Node>& Q) {
92.535 + ear.set(top,bottom);
92.536 + Node t=top;
92.537 + while ( t!=middle ) {
92.538 + Node u=_mate[t];
92.539 + t=ear[u];
92.540 + ear.set(t,u);
92.541 + }
92.542 + bottom=_mate[middle];
92.543 + position.set(bottom,D);
92.544 + Q.push(bottom);
92.545 + top=ear[bottom];
92.546 + Node oldmiddle=middle;
92.547 + middle=blossom.find(top);
92.548 + tree.erase(bottom);
92.549 + tree.erase(oldmiddle);
92.550 + blossom.insert(bottom);
92.551 + blossom.join(bottom, oldmiddle);
92.552 + blossom.join(top, oldmiddle);
92.553 + }
92.554 +
92.555 + template <typename Graph>
92.556 + void MaxMatching<Graph>::augment(Node x,
92.557 + typename Graph::template NodeMap<Node>& ear,
92.558 + UFE& blossom, UFE& tree) {
92.559 + Node v=_mate[x];
92.560 + while ( v!=INVALID ) {
92.561 +
92.562 + Node u=ear[v];
92.563 + _mate.set(v,u);
92.564 + Node tmp=v;
92.565 + v=_mate[u];
92.566 + _mate.set(u,tmp);
92.567 + }
92.568 + typename UFE::ItemIt it;
92.569 + for (tree.first(it,blossom.find(x)); tree.valid(it); tree.next(it)) {
92.570 + if ( position[it] == D ) {
92.571 + typename UFE::ItemIt b_it;
92.572 + for (blossom.first(b_it,it); blossom.valid(b_it); blossom.next(b_it)) {
92.573 + position.set( b_it ,C);
92.574 + }
92.575 + blossom.eraseClass(it);
92.576 + } else position.set( it ,C);
92.577 + }
92.578 + tree.eraseClass(x);
92.579 +
92.580 + }
92.581 +
92.582 + /// @}
92.583 +
92.584 +} //END OF NAMESPACE LEMON
92.585 +
92.586 +#endif //LEMON_MAX_MATCHING_H
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/lemon/min_cost_flow.h Mon May 23 04:48:14 2005 +0000
93.3 @@ -0,0 +1,260 @@
93.4 +/* -*- C++ -*-
93.5 + * lemon/min_cost_flow.h - Part of LEMON, a generic C++ optimization library
93.6 + *
93.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
93.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
93.9 + *
93.10 + * Permission to use, modify and distribute this software is granted
93.11 + * provided that this copyright notice appears in all copies. For
93.12 + * precise terms see the accompanying LICENSE file.
93.13 + *
93.14 + * This software is provided "AS IS" with no warranty of any kind,
93.15 + * express or implied, and with no claim as to its suitability for any
93.16 + * purpose.
93.17 + *
93.18 + */
93.19 +
93.20 +#ifndef LEMON_MIN_COST_FLOW_H
93.21 +#define LEMON_MIN_COST_FLOW_H
93.22 +
93.23 +///\ingroup flowalgs
93.24 +///\file
93.25 +///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost
93.26 +
93.27 +
93.28 +#include <lemon/dijkstra.h>
93.29 +#include <lemon/graph_adaptor.h>
93.30 +#include <lemon/maps.h>
93.31 +#include <vector>
93.32 +
93.33 +namespace lemon {
93.34 +
93.35 +/// \addtogroup flowalgs
93.36 +/// @{
93.37 +
93.38 + ///\brief Implementation of an algorithm for finding a flow of value \c k
93.39 + ///(for small values of \c k) having minimal total cost between 2 nodes
93.40 + ///
93.41 + ///
93.42 + /// The class \ref lemon::MinCostFlow "MinCostFlow" implements an
93.43 + /// algorithm for finding a flow of value \c k having minimal total
93.44 + /// cost from a given source node to a given target node in an
93.45 + /// edge-weighted directed graph. To this end, the edge-capacities
93.46 + /// and edge-weights have to be nonnegative. The edge-capacities
93.47 + /// should be integers, but the edge-weights can be integers, reals
93.48 + /// or of other comparable numeric type. This algorithm is intended
93.49 + /// to be used only for small values of \c k, since it is only
93.50 + /// polynomial in k, not in the length of k (which is log k): in
93.51 + /// order to find the minimum cost flow of value \c k it finds the
93.52 + /// minimum cost flow of value \c i for every \c i between 0 and \c
93.53 + /// k.
93.54 + ///
93.55 + ///\param Graph The directed graph type the algorithm runs on.
93.56 + ///\param LengthMap The type of the length map.
93.57 + ///\param CapacityMap The capacity map type.
93.58 + ///
93.59 + ///\author Attila Bernath
93.60 + template <typename Graph, typename LengthMap, typename CapacityMap>
93.61 + class MinCostFlow {
93.62 +
93.63 + typedef typename LengthMap::Value Length;
93.64 +
93.65 + //Warning: this should be integer type
93.66 + typedef typename CapacityMap::Value Capacity;
93.67 +
93.68 + typedef typename Graph::Node Node;
93.69 + typedef typename Graph::NodeIt NodeIt;
93.70 + typedef typename Graph::Edge Edge;
93.71 + typedef typename Graph::OutEdgeIt OutEdgeIt;
93.72 + typedef typename Graph::template EdgeMap<int> EdgeIntMap;
93.73 +
93.74 + typedef ResGraphAdaptor<const Graph,int,CapacityMap,EdgeIntMap> ResGW;
93.75 + typedef typename ResGW::Edge ResGraphEdge;
93.76 +
93.77 + protected:
93.78 +
93.79 + const Graph& g;
93.80 + const LengthMap& length;
93.81 + const CapacityMap& capacity;
93.82 +
93.83 + EdgeIntMap flow;
93.84 + typedef typename Graph::template NodeMap<Length> PotentialMap;
93.85 + PotentialMap potential;
93.86 +
93.87 + Node s;
93.88 + Node t;
93.89 +
93.90 + Length total_length;
93.91 +
93.92 + class ModLengthMap {
93.93 + typedef typename Graph::template NodeMap<Length> NodeMap;
93.94 + const ResGW& g;
93.95 + const LengthMap &length;
93.96 + const NodeMap &pot;
93.97 + public :
93.98 + typedef typename LengthMap::Key Key;
93.99 + typedef typename LengthMap::Value Value;
93.100 +
93.101 + ModLengthMap(const ResGW& _g,
93.102 + const LengthMap &_length, const NodeMap &_pot) :
93.103 + g(_g), /*rev(_rev),*/ length(_length), pot(_pot) { }
93.104 +
93.105 + Value operator[](typename ResGW::Edge e) const {
93.106 + if (g.forward(e))
93.107 + return length[e]-(pot[g.target(e)]-pot[g.source(e)]);
93.108 + else
93.109 + return -length[e]-(pot[g.target(e)]-pot[g.source(e)]);
93.110 + }
93.111 +
93.112 + }; //ModLengthMap
93.113 +
93.114 + ResGW res_graph;
93.115 + ModLengthMap mod_length;
93.116 + Dijkstra<ResGW, ModLengthMap> dijkstra;
93.117 +
93.118 + public :
93.119 +
93.120 + /*! \brief The constructor of the class.
93.121 +
93.122 + \param _g The directed graph the algorithm runs on.
93.123 + \param _length The length (weight or cost) of the edges.
93.124 + \param _cap The capacity of the edges.
93.125 + \param _s Source node.
93.126 + \param _t Target node.
93.127 + */
93.128 + MinCostFlow(Graph& _g, LengthMap& _length, CapacityMap& _cap,
93.129 + Node _s, Node _t) :
93.130 + g(_g), length(_length), capacity(_cap), flow(_g), potential(_g),
93.131 + s(_s), t(_t),
93.132 + res_graph(g, capacity, flow),
93.133 + mod_length(res_graph, length, potential),
93.134 + dijkstra(res_graph, mod_length) {
93.135 + reset();
93.136 + }
93.137 +
93.138 + /*! Tries to augment the flow between s and t by 1.
93.139 + The return value shows if the augmentation is successful.
93.140 + */
93.141 + bool augment() {
93.142 + dijkstra.run(s);
93.143 + if (!dijkstra.reached(t)) {
93.144 +
93.145 + //Unsuccessful augmentation.
93.146 + return false;
93.147 + } else {
93.148 +
93.149 + //We have to change the potential
93.150 + for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n)
93.151 + potential.set(n, potential[n]+dijkstra.distMap()[n]);
93.152 +
93.153 + //Augmenting on the shortest path
93.154 + Node n=t;
93.155 + ResGraphEdge e;
93.156 + while (n!=s){
93.157 + e = dijkstra.pred(n);
93.158 + n = dijkstra.predNode(n);
93.159 + res_graph.augment(e,1);
93.160 + //Let's update the total length
93.161 + if (res_graph.forward(e))
93.162 + total_length += length[e];
93.163 + else
93.164 + total_length -= length[e];
93.165 + }
93.166 +
93.167 + return true;
93.168 + }
93.169 + }
93.170 +
93.171 + /*! \brief Runs the algorithm.
93.172 +
93.173 + Runs the algorithm.
93.174 + Returns k if there is a flow of value at least k from s to t.
93.175 + Otherwise it returns the maximum value of a flow from s to t.
93.176 +
93.177 + \param k The value of the flow we are looking for.
93.178 +
93.179 + \todo May be it does make sense to be able to start with a nonzero
93.180 + feasible primal-dual solution pair as well.
93.181 +
93.182 + \todo If the actual flow value is bigger than k, then everything is
93.183 + cleared and the algorithm starts from zero flow. Is it a good approach?
93.184 + */
93.185 + int run(int k) {
93.186 + if (flowValue()>k) reset();
93.187 + while (flowValue()<k && augment()) { }
93.188 + return flowValue();
93.189 + }
93.190 +
93.191 + /*! \brief The class is reset to zero flow and potential.
93.192 + The class is reset to zero flow and potential.
93.193 + */
93.194 + void reset() {
93.195 + total_length=0;
93.196 + for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
93.197 + for (typename Graph::NodeIt n(g); n!=INVALID; ++n) potential.set(n, 0);
93.198 + }
93.199 +
93.200 + /*! Returns the value of the actual flow.
93.201 + */
93.202 + int flowValue() const {
93.203 + int i=0;
93.204 + for (typename Graph::OutEdgeIt e(g, s); e!=INVALID; ++e) i+=flow[e];
93.205 + for (typename Graph::InEdgeIt e(g, s); e!=INVALID; ++e) i-=flow[e];
93.206 + return i;
93.207 + }
93.208 +
93.209 + /// Total weight of the found flow.
93.210 +
93.211 + /// This function gives back the total weight of the found flow.
93.212 + Length totalLength(){
93.213 + return total_length;
93.214 + }
93.215 +
93.216 + ///Returns a const reference to the EdgeMap \c flow.
93.217 +
93.218 + ///Returns a const reference to the EdgeMap \c flow.
93.219 + const EdgeIntMap &getFlow() const { return flow;}
93.220 +
93.221 + /*! \brief Returns a const reference to the NodeMap \c potential (the dual solution).
93.222 +
93.223 + Returns a const reference to the NodeMap \c potential (the dual solution).
93.224 + */
93.225 + const PotentialMap &getPotential() const { return potential;}
93.226 +
93.227 + /*! \brief Checking the complementary slackness optimality criteria.
93.228 +
93.229 + This function checks, whether the given flow and potential
93.230 + satisfy the complementary slackness conditions (i.e. these are optimal).
93.231 + This function only checks optimality, doesn't bother with feasibility.
93.232 + For testing purpose.
93.233 + */
93.234 + bool checkComplementarySlackness(){
93.235 + Length mod_pot;
93.236 + Length fl_e;
93.237 + for(typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
93.238 + //C^{\Pi}_{i,j}
93.239 + mod_pot = length[e]-potential[g.target(e)]+potential[g.source(e)];
93.240 + fl_e = flow[e];
93.241 + if (0<fl_e && fl_e<capacity[e]) {
93.242 + /// \todo better comparison is needed for real types, moreover,
93.243 + /// this comparison here is superfluous.
93.244 + if (mod_pot != 0)
93.245 + return false;
93.246 + }
93.247 + else {
93.248 + if (mod_pot > 0 && fl_e != 0)
93.249 + return false;
93.250 + if (mod_pot < 0 && fl_e != capacity[e])
93.251 + return false;
93.252 + }
93.253 + }
93.254 + return true;
93.255 + }
93.256 +
93.257 + }; //class MinCostFlow
93.258 +
93.259 + ///@}
93.260 +
93.261 +} //namespace lemon
93.262 +
93.263 +#endif //LEMON_MIN_COST_FLOW_H
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/lemon/path.h Mon May 23 04:48:14 2005 +0000
94.3 @@ -0,0 +1,703 @@
94.4 +/* -*- C++ -*-
94.5 + * lemon/path.h - Part of LEMON, a generic C++ optimization library
94.6 + *
94.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
94.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
94.9 + *
94.10 + * Permission to use, modify and distribute this software is granted
94.11 + * provided that this copyright notice appears in all copies. For
94.12 + * precise terms see the accompanying LICENSE file.
94.13 + *
94.14 + * This software is provided "AS IS" with no warranty of any kind,
94.15 + * express or implied, and with no claim as to its suitability for any
94.16 + * purpose.
94.17 + *
94.18 + */
94.19 +
94.20 +/**
94.21 +@defgroup paths Path Structures
94.22 +@ingroup datas
94.23 +\brief Path structures implemented in LEMON.
94.24 +
94.25 +LEMON provides flexible data structures
94.26 +to work with paths.
94.27 +
94.28 +All of them have the same interface, especially they can be built or extended
94.29 +using a standard Builder subclass. This make is easy to have e.g. the Dijkstra
94.30 +algorithm to store its result in any kind of path structure.
94.31 +
94.32 +\sa lemon::concept::Path
94.33 +
94.34 +*/
94.35 +
94.36 +///\ingroup paths
94.37 +///\file
94.38 +///\brief Classes for representing paths in graphs.
94.39 +///
94.40 +///\todo Iterators have obsolete style
94.41 +
94.42 +#ifndef LEMON_PATH_H
94.43 +#define LEMON_PATH_H
94.44 +
94.45 +#include <deque>
94.46 +#include <vector>
94.47 +#include <algorithm>
94.48 +
94.49 +#include <lemon/invalid.h>
94.50 +
94.51 +namespace lemon {
94.52 +
94.53 + /// \addtogroup paths
94.54 + /// @{
94.55 +
94.56 +
94.57 + //! \brief A structure for representing directed paths in a graph.
94.58 + //!
94.59 + //! A structure for representing directed path in a graph.
94.60 + //! \param Graph The graph type in which the path is.
94.61 + //! \param DM DebugMode, defaults to DefaultDebugMode.
94.62 + //!
94.63 + //! In a sense, the path can be treated as a graph, for is has \c NodeIt
94.64 + //! and \c EdgeIt with the same usage. These types converts to the \c Node
94.65 + //! and \c Edge of the original graph.
94.66 + //!
94.67 + //! \todo Thoroughfully check all the range and consistency tests.
94.68 + template<typename Graph>
94.69 + class DirPath {
94.70 + public:
94.71 + /// Edge type of the underlying graph.
94.72 + typedef typename Graph::Edge GraphEdge;
94.73 + /// Node type of the underlying graph.
94.74 + typedef typename Graph::Node GraphNode;
94.75 + class NodeIt;
94.76 + class EdgeIt;
94.77 +
94.78 + protected:
94.79 + const Graph *gr;
94.80 + typedef std::vector<GraphEdge> Container;
94.81 + Container edges;
94.82 +
94.83 + public:
94.84 +
94.85 + /// \param _G The graph in which the path is.
94.86 + ///
94.87 + DirPath(const Graph &_G) : gr(&_G) {}
94.88 +
94.89 + /// \brief Subpath constructor.
94.90 + ///
94.91 + /// Subpath defined by two nodes.
94.92 + /// \warning It is an error if the two edges are not in order!
94.93 + DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
94.94 + gr = P.gr;
94.95 + edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
94.96 + }
94.97 +
94.98 + /// \brief Subpath constructor.
94.99 + ///
94.100 + /// Subpath defined by two edges. Contains edges in [a,b)
94.101 + /// \warning It is an error if the two edges are not in order!
94.102 + DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
94.103 + gr = P.gr;
94.104 + edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
94.105 + }
94.106 +
94.107 + /// Length of the path.
94.108 + int length() const { return edges.size(); }
94.109 + /// Returns whether the path is empty.
94.110 + bool empty() const { return edges.empty(); }
94.111 +
94.112 + /// Resets the path to an empty path.
94.113 + void clear() { edges.clear(); }
94.114 +
94.115 + /// \brief Starting point of the path.
94.116 + ///
94.117 + /// Starting point of the path.
94.118 + /// Returns INVALID if the path is empty.
94.119 + GraphNode source() const {
94.120 + return empty() ? INVALID : gr->source(edges[0]);
94.121 + }
94.122 + /// \brief End point of the path.
94.123 + ///
94.124 + /// End point of the path.
94.125 + /// Returns INVALID if the path is empty.
94.126 + GraphNode target() const {
94.127 + return empty() ? INVALID : gr->target(edges[length()-1]);
94.128 + }
94.129 +
94.130 + /// \brief Initializes node or edge iterator to point to the first
94.131 + /// node or edge.
94.132 + ///
94.133 + /// \sa nth
94.134 + template<typename It>
94.135 + It& first(It &i) const { return i=It(*this); }
94.136 +
94.137 + /// \brief Initializes node iterator to point to the node of a given index.
94.138 + NodeIt& nth(NodeIt &i, int n) const {
94.139 + return i=NodeIt(*this, n);
94.140 + }
94.141 +
94.142 + /// \brief Initializes edge iterator to point to the edge of a given index.
94.143 + EdgeIt& nth(EdgeIt &i, int n) const {
94.144 + return i=EdgeIt(*this, n);
94.145 + }
94.146 +
94.147 + /// \brief Returns node iterator pointing to the target node of the
94.148 + /// given edge iterator.
94.149 + NodeIt target(const EdgeIt& e) const {
94.150 + return NodeIt(*this, e.idx+1);
94.151 + }
94.152 +
94.153 + /// \brief Returns node iterator pointing to the source node of the
94.154 + /// given edge iterator.
94.155 + NodeIt source(const EdgeIt& e) const {
94.156 + return NodeIt(*this, e.idx);
94.157 + }
94.158 +
94.159 +
94.160 + /* Iterator classes */
94.161 +
94.162 + /**
94.163 + * \brief Iterator class to iterate on the edges of the paths
94.164 + *
94.165 + * This class is used to iterate on the edges of the paths
94.166 + *
94.167 + * Of course it converts to Graph::Edge
94.168 + *
94.169 + */
94.170 + class EdgeIt {
94.171 + friend class DirPath;
94.172 +
94.173 + int idx;
94.174 + const DirPath *p;
94.175 + public:
94.176 + /// Default constructor
94.177 + EdgeIt() {}
94.178 + /// Invalid constructor
94.179 + EdgeIt(Invalid) : idx(-1), p(0) {}
94.180 + /// Constructor with starting point
94.181 + EdgeIt(const DirPath &_p, int _idx = 0) :
94.182 + idx(_idx), p(&_p) { validate(); }
94.183 +
94.184 + ///Validity check
94.185 + bool valid() const { return idx!=-1; }
94.186 +
94.187 + ///Conversion to Graph::Edge
94.188 + operator GraphEdge () const {
94.189 + return valid() ? p->edges[idx] : INVALID;
94.190 + }
94.191 +
94.192 + /// Next edge
94.193 + EdgeIt& operator++() { ++idx; validate(); return *this; }
94.194 +
94.195 + /// Comparison operator
94.196 + bool operator==(const EdgeIt& e) const { return idx==e.idx; }
94.197 + /// Comparison operator
94.198 + bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
94.199 + /// Comparison operator
94.200 + bool operator<(const EdgeIt& e) const { return idx<e.idx; }
94.201 +
94.202 + private:
94.203 + void validate() { if(idx >= p->length() ) idx=-1; }
94.204 + };
94.205 +
94.206 + /**
94.207 + * \brief Iterator class to iterate on the nodes of the paths
94.208 + *
94.209 + * This class is used to iterate on the nodes of the paths
94.210 + *
94.211 + * Of course it converts to Graph::Node
94.212 + *
94.213 + */
94.214 + class NodeIt {
94.215 + friend class DirPath;
94.216 +
94.217 + int idx;
94.218 + const DirPath *p;
94.219 + public:
94.220 + /// Default constructor
94.221 + NodeIt() {}
94.222 + /// Invalid constructor
94.223 + NodeIt(Invalid) : idx(-1), p(0) {}
94.224 + /// Constructor with starting point
94.225 + NodeIt(const DirPath &_p, int _idx = 0) :
94.226 + idx(_idx), p(&_p) { validate(); }
94.227 +
94.228 + ///Validity check
94.229 + bool valid() const { return idx!=-1; }
94.230 +
94.231 + ///Conversion to Graph::Node
94.232 + operator const GraphNode& () const {
94.233 + if(idx >= p->length())
94.234 + return p->target();
94.235 + else if(idx >= 0)
94.236 + return p->gr->source(p->edges[idx]);
94.237 + else
94.238 + return INVALID;
94.239 + }
94.240 + /// Next node
94.241 + NodeIt& operator++() { ++idx; validate(); return *this; }
94.242 +
94.243 + /// Comparison operator
94.244 + bool operator==(const NodeIt& e) const { return idx==e.idx; }
94.245 + /// Comparison operator
94.246 + bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
94.247 + /// Comparison operator
94.248 + bool operator<(const NodeIt& e) const { return idx<e.idx; }
94.249 +
94.250 + private:
94.251 + void validate() { if(idx > p->length() ) idx=-1; }
94.252 + };
94.253 +
94.254 + friend class Builder;
94.255 +
94.256 + /**
94.257 + * \brief Class to build paths
94.258 + *
94.259 + * This class is used to fill a path with edges.
94.260 + *
94.261 + * You can push new edges to the front and to the back of the path in
94.262 + * arbitrary order then you should commit these changes to the graph.
94.263 + *
94.264 + * Fundamentally, for most "Paths" (classes fulfilling the
94.265 + * PathConcept) while the builder is active (after the first modifying
94.266 + * operation and until the commit()) the original Path is in a
94.267 + * "transitional" state (operations on it have undefined result). But
94.268 + * in the case of DirPath the original path remains unchanged until the
94.269 + * commit. However we don't recomend that you use this feature.
94.270 + */
94.271 + class Builder {
94.272 + DirPath &P;
94.273 + Container front, back;
94.274 +
94.275 + public:
94.276 + ///\param _p the path you want to fill in.
94.277 + ///
94.278 + Builder(DirPath &_p) : P(_p) {}
94.279 +
94.280 + /// Sets the starting node of the path.
94.281 +
94.282 + /// Sets the starting node of the path. Edge added to the path
94.283 + /// afterwards have to be incident to this node.
94.284 + /// It should be called if and only if
94.285 + /// the path is empty and before any call to
94.286 + /// \ref pushFront() or \ref pushBack()
94.287 + void setStartNode(const GraphNode &) {}
94.288 +
94.289 + ///Push a new edge to the front of the path
94.290 +
94.291 + ///Push a new edge to the front of the path.
94.292 + ///\sa setStartNode
94.293 + void pushFront(const GraphEdge& e) {
94.294 + front.push_back(e);
94.295 + }
94.296 +
94.297 + ///Push a new edge to the back of the path
94.298 +
94.299 + ///Push a new edge to the back of the path.
94.300 + ///\sa setStartNode
94.301 + void pushBack(const GraphEdge& e) {
94.302 + back.push_back(e);
94.303 + }
94.304 +
94.305 + ///Commit the changes to the path.
94.306 + void commit() {
94.307 + if( !front.empty() || !back.empty() ) {
94.308 + Container tmp;
94.309 + tmp.reserve(front.size()+back.size()+P.length());
94.310 + tmp.insert(tmp.end(), front.rbegin(), front.rend());
94.311 + tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
94.312 + tmp.insert(tmp.end(), back.begin(), back.end());
94.313 + P.edges.swap(tmp);
94.314 + front.clear();
94.315 + back.clear();
94.316 + }
94.317 + }
94.318 +
94.319 + ///Reserve storage for the builder in advance.
94.320 +
94.321 + ///If you know a reasonable upper bound of the number of the edges
94.322 + ///to add to the front, using this function you can speed up the building.
94.323 +
94.324 + void reserveFront(size_t r) {front.reserve(r);}
94.325 +
94.326 + ///Reserve storage for the builder in advance.
94.327 +
94.328 + ///If you know a reasonable upper bound of the number of the edges
94.329 + ///to add to the back, using this function you can speed up the building.
94.330 +
94.331 + void reserveBack(size_t r) {back.reserve(r);}
94.332 +
94.333 + private:
94.334 + bool empty() {
94.335 + return front.empty() && back.empty() && P.empty();
94.336 + }
94.337 +
94.338 + GraphNode source() const {
94.339 + if( ! front.empty() )
94.340 + return P.gr->source(front[front.size()-1]);
94.341 + else if( ! P.empty() )
94.342 + return P.gr->source(P.edges[0]);
94.343 + else if( ! back.empty() )
94.344 + return P.gr->source(back[0]);
94.345 + else
94.346 + return INVALID;
94.347 + }
94.348 + GraphNode target() const {
94.349 + if( ! back.empty() )
94.350 + return P.gr->target(back[back.size()-1]);
94.351 + else if( ! P.empty() )
94.352 + return P.gr->target(P.edges[P.length()-1]);
94.353 + else if( ! front.empty() )
94.354 + return P.gr->target(front[0]);
94.355 + else
94.356 + return INVALID;
94.357 + }
94.358 +
94.359 + };
94.360 +
94.361 + };
94.362 +
94.363 +
94.364 +
94.365 +
94.366 +
94.367 +
94.368 +
94.369 +
94.370 +
94.371 +
94.372 + /**********************************************************************/
94.373 +
94.374 +
94.375 + //! \brief A structure for representing undirected path in a graph.
94.376 + //!
94.377 + //! A structure for representing undirected path in a graph. Ie. this is
94.378 + //! a path in a \e directed graph but the edges should not be directed
94.379 + //! forward.
94.380 + //!
94.381 + //! \param Graph The graph type in which the path is.
94.382 + //! \param DM DebugMode, defaults to DefaultDebugMode.
94.383 + //!
94.384 + //! In a sense, the path can be treated as a graph, for is has \c NodeIt
94.385 + //! and \c EdgeIt with the same usage. These types converts to the \c Node
94.386 + //! and \c Edge of the original graph.
94.387 + //!
94.388 + //! \todo Thoroughfully check all the range and consistency tests.
94.389 + template<typename Graph>
94.390 + class UndirPath {
94.391 + public:
94.392 + /// Edge type of the underlying graph.
94.393 + typedef typename Graph::Edge GraphEdge;
94.394 + /// Node type of the underlying graph.
94.395 + typedef typename Graph::Node GraphNode;
94.396 + class NodeIt;
94.397 + class EdgeIt;
94.398 +
94.399 + protected:
94.400 + const Graph *gr;
94.401 + typedef std::vector<GraphEdge> Container;
94.402 + Container edges;
94.403 +
94.404 + public:
94.405 +
94.406 + /// \param _G The graph in which the path is.
94.407 + ///
94.408 + UndirPath(const Graph &_G) : gr(&_G) {}
94.409 +
94.410 + /// \brief Subpath constructor.
94.411 + ///
94.412 + /// Subpath defined by two nodes.
94.413 + /// \warning It is an error if the two edges are not in order!
94.414 + UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
94.415 + gr = P.gr;
94.416 + edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
94.417 + }
94.418 +
94.419 + /// \brief Subpath constructor.
94.420 + ///
94.421 + /// Subpath defined by two edges. Contains edges in [a,b)
94.422 + /// \warning It is an error if the two edges are not in order!
94.423 + UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
94.424 + gr = P.gr;
94.425 + edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
94.426 + }
94.427 +
94.428 + /// Length of the path.
94.429 + size_t length() const { return edges.size(); }
94.430 + /// Returns whether the path is empty.
94.431 + bool empty() const { return edges.empty(); }
94.432 +
94.433 + /// Resets the path to an empty path.
94.434 + void clear() { edges.clear(); }
94.435 +
94.436 + /// \brief Starting point of the path.
94.437 + ///
94.438 + /// Starting point of the path.
94.439 + /// Returns INVALID if the path is empty.
94.440 + GraphNode source() const {
94.441 + return empty() ? INVALID : gr->source(edges[0]);
94.442 + }
94.443 + /// \brief End point of the path.
94.444 + ///
94.445 + /// End point of the path.
94.446 + /// Returns INVALID if the path is empty.
94.447 + GraphNode target() const {
94.448 + return empty() ? INVALID : gr->target(edges[length()-1]);
94.449 + }
94.450 +
94.451 + /// \brief Initializes node or edge iterator to point to the first
94.452 + /// node or edge.
94.453 + ///
94.454 + /// \sa nth
94.455 + template<typename It>
94.456 + It& first(It &i) const { return i=It(*this); }
94.457 +
94.458 + /// \brief Initializes node iterator to point to the node of a given index.
94.459 + NodeIt& nth(NodeIt &i, int n) const {
94.460 + return i=NodeIt(*this, n);
94.461 + }
94.462 +
94.463 + /// \brief Initializes edge iterator to point to the edge of a given index.
94.464 + EdgeIt& nth(EdgeIt &i, int n) const {
94.465 + return i=EdgeIt(*this, n);
94.466 + }
94.467 +
94.468 + /// Checks validity of a node or edge iterator.
94.469 + template<typename It>
94.470 + static
94.471 + bool valid(const It &i) { return i.valid(); }
94.472 +
94.473 + /// Steps the given node or edge iterator.
94.474 + template<typename It>
94.475 + static
94.476 + It& next(It &e) {
94.477 + return ++e;
94.478 + }
94.479 +
94.480 + /// \brief Returns node iterator pointing to the target node of the
94.481 + /// given edge iterator.
94.482 + NodeIt target(const EdgeIt& e) const {
94.483 + return NodeIt(*this, e.idx+1);
94.484 + }
94.485 +
94.486 + /// \brief Returns node iterator pointing to the source node of the
94.487 + /// given edge iterator.
94.488 + NodeIt source(const EdgeIt& e) const {
94.489 + return NodeIt(*this, e.idx);
94.490 + }
94.491 +
94.492 +
94.493 +
94.494 + /**
94.495 + * \brief Iterator class to iterate on the edges of the paths
94.496 + *
94.497 + * This class is used to iterate on the edges of the paths
94.498 + *
94.499 + * Of course it converts to Graph::Edge
94.500 + *
94.501 + * \todo Its interface differs from the standard edge iterator.
94.502 + * Yes, it shouldn't.
94.503 + */
94.504 + class EdgeIt {
94.505 + friend class UndirPath;
94.506 +
94.507 + int idx;
94.508 + const UndirPath *p;
94.509 + public:
94.510 + /// Default constructor
94.511 + EdgeIt() {}
94.512 + /// Invalid constructor
94.513 + EdgeIt(Invalid) : idx(-1), p(0) {}
94.514 + /// Constructor with starting point
94.515 + EdgeIt(const UndirPath &_p, int _idx = 0) :
94.516 + idx(_idx), p(&_p) { validate(); }
94.517 +
94.518 + ///Validity check
94.519 + bool valid() const { return idx!=-1; }
94.520 +
94.521 + ///Conversion to Graph::Edge
94.522 + operator GraphEdge () const {
94.523 + return valid() ? p->edges[idx] : INVALID;
94.524 + }
94.525 + /// Next edge
94.526 + EdgeIt& operator++() { ++idx; validate(); return *this; }
94.527 +
94.528 + /// Comparison operator
94.529 + bool operator==(const EdgeIt& e) const { return idx==e.idx; }
94.530 + /// Comparison operator
94.531 + bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
94.532 + /// Comparison operator
94.533 + bool operator<(const EdgeIt& e) const { return idx<e.idx; }
94.534 +
94.535 + private:
94.536 + // FIXME: comparison between signed and unsigned...
94.537 + // Jo ez igy? Vagy esetleg legyen a length() int?
94.538 + void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
94.539 + };
94.540 +
94.541 + /**
94.542 + * \brief Iterator class to iterate on the nodes of the paths
94.543 + *
94.544 + * This class is used to iterate on the nodes of the paths
94.545 + *
94.546 + * Of course it converts to Graph::Node
94.547 + *
94.548 + * \todo Its interface differs from the standard node iterator.
94.549 + * Yes, it shouldn't.
94.550 + */
94.551 + class NodeIt {
94.552 + friend class UndirPath;
94.553 +
94.554 + int idx;
94.555 + const UndirPath *p;
94.556 + public:
94.557 + /// Default constructor
94.558 + NodeIt() {}
94.559 + /// Invalid constructor
94.560 + NodeIt(Invalid) : idx(-1), p(0) {}
94.561 + /// Constructor with starting point
94.562 + NodeIt(const UndirPath &_p, int _idx = 0) :
94.563 + idx(_idx), p(&_p) { validate(); }
94.564 +
94.565 + ///Validity check
94.566 + bool valid() const { return idx!=-1; }
94.567 +
94.568 + ///Conversion to Graph::Node
94.569 + operator const GraphNode& () const {
94.570 + if(idx >= p->length())
94.571 + return p->target();
94.572 + else if(idx >= 0)
94.573 + return p->gr->source(p->edges[idx]);
94.574 + else
94.575 + return INVALID;
94.576 + }
94.577 + /// Next node
94.578 + NodeIt& operator++() { ++idx; validate(); return *this; }
94.579 +
94.580 + /// Comparison operator
94.581 + bool operator==(const NodeIt& e) const { return idx==e.idx; }
94.582 + /// Comparison operator
94.583 + bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
94.584 + /// Comparison operator
94.585 + bool operator<(const NodeIt& e) const { return idx<e.idx; }
94.586 +
94.587 + private:
94.588 + void validate() { if( size_t(idx) > p->length() ) idx=-1; }
94.589 + };
94.590 +
94.591 + friend class Builder;
94.592 +
94.593 + /**
94.594 + * \brief Class to build paths
94.595 + *
94.596 + * This class is used to fill a path with edges.
94.597 + *
94.598 + * You can push new edges to the front and to the back of the path in
94.599 + * arbitrary order then you should commit these changes to the graph.
94.600 + *
94.601 + * Fundamentally, for most "Paths" (classes fulfilling the
94.602 + * PathConcept) while the builder is active (after the first modifying
94.603 + * operation and until the commit()) the original Path is in a
94.604 + * "transitional" state (operations ot it have undefined result). But
94.605 + * in the case of UndirPath the original path is unchanged until the
94.606 + * commit. However we don't recomend that you use this feature.
94.607 + */
94.608 + class Builder {
94.609 + UndirPath &P;
94.610 + Container front, back;
94.611 +
94.612 + public:
94.613 + ///\param _p the path you want to fill in.
94.614 + ///
94.615 + Builder(UndirPath &_p) : P(_p) {}
94.616 +
94.617 + /// Sets the starting node of the path.
94.618 +
94.619 + /// Sets the starting node of the path. Edge added to the path
94.620 + /// afterwards have to be incident to this node.
94.621 + /// It should be called if and only if
94.622 + /// the path is empty and before any call to
94.623 + /// \ref pushFront() or \ref pushBack()
94.624 + void setStartNode(const GraphNode &) {}
94.625 +
94.626 + ///Push a new edge to the front of the path
94.627 +
94.628 + ///Push a new edge to the front of the path.
94.629 + ///\sa setStartNode
94.630 + void pushFront(const GraphEdge& e) {
94.631 + front.push_back(e);
94.632 + }
94.633 +
94.634 + ///Push a new edge to the back of the path
94.635 +
94.636 + ///Push a new edge to the back of the path.
94.637 + ///\sa setStartNode
94.638 + void pushBack(const GraphEdge& e) {
94.639 + back.push_back(e);
94.640 + }
94.641 +
94.642 + ///Commit the changes to the path.
94.643 + void commit() {
94.644 + if( !(front.empty() && back.empty()) ) {
94.645 + Container tmp;
94.646 + tmp.reserve(front.size()+back.size()+P.length());
94.647 + tmp.insert(tmp.end(), front.rbegin(), front.rend());
94.648 + tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
94.649 + tmp.insert(tmp.end(), back.begin(), back.end());
94.650 + P.edges.swap(tmp);
94.651 + front.clear();
94.652 + back.clear();
94.653 + }
94.654 + }
94.655 +
94.656 +
94.657 + ///Reserve storage for the builder in advance.
94.658 +
94.659 + ///If you know a reasonable upper bound of the number of the edges
94.660 + ///to add to the front, using this function you can speed up the building.
94.661 +
94.662 + void reserveFront(size_t r) {front.reserve(r);}
94.663 +
94.664 + ///Reserve storage for the builder in advance.
94.665 +
94.666 + ///If you know a reasonable upper bound of the number of the edges
94.667 + ///to add to the back, using this function you can speed up the building.
94.668 +
94.669 + void reserveBack(size_t r) {back.reserve(r);}
94.670 +
94.671 + private:
94.672 + bool empty() {
94.673 + return front.empty() && back.empty() && P.empty();
94.674 + }
94.675 +
94.676 + GraphNode source() const {
94.677 + if( ! front.empty() )
94.678 + return P.gr->source(front[front.size()-1]);
94.679 + else if( ! P.empty() )
94.680 + return P.gr->source(P.edges[0]);
94.681 + else if( ! back.empty() )
94.682 + return P.gr->source(back[0]);
94.683 + else
94.684 + return INVALID;
94.685 + }
94.686 + GraphNode target() const {
94.687 + if( ! back.empty() )
94.688 + return P.gr->target(back[back.size()-1]);
94.689 + else if( ! P.empty() )
94.690 + return P.gr->target(P.edges[P.length()-1]);
94.691 + else if( ! front.empty() )
94.692 + return P.gr->target(front[0]);
94.693 + else
94.694 + return INVALID;
94.695 + }
94.696 +
94.697 + };
94.698 +
94.699 + };
94.700 +
94.701 +
94.702 + ///@}
94.703 +
94.704 +} // namespace lemon
94.705 +
94.706 +#endif // LEMON_PATH_H
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/lemon/preflow.h Mon May 23 04:48:14 2005 +0000
95.3 @@ -0,0 +1,868 @@
95.4 +/* -*- C++ -*-
95.5 + * lemon/preflow.h - Part of LEMON, a generic C++ optimization library
95.6 + *
95.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
95.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
95.9 + *
95.10 + * Permission to use, modify and distribute this software is granted
95.11 + * provided that this copyright notice appears in all copies. For
95.12 + * precise terms see the accompanying LICENSE file.
95.13 + *
95.14 + * This software is provided "AS IS" with no warranty of any kind,
95.15 + * express or implied, and with no claim as to its suitability for any
95.16 + * purpose.
95.17 + *
95.18 + */
95.19 +
95.20 +#ifndef LEMON_PREFLOW_H
95.21 +#define LEMON_PREFLOW_H
95.22 +
95.23 +#include <vector>
95.24 +#include <queue>
95.25 +
95.26 +#include <lemon/invalid.h>
95.27 +#include <lemon/maps.h>
95.28 +#include <lemon/graph_utils.h>
95.29 +
95.30 +/// \file
95.31 +/// \ingroup flowalgs
95.32 +/// Implementation of the preflow algorithm.
95.33 +
95.34 +namespace lemon {
95.35 +
95.36 + /// \addtogroup flowalgs
95.37 + /// @{
95.38 +
95.39 + ///%Preflow algorithms class.
95.40 +
95.41 + ///This class provides an implementation of the \e preflow \e
95.42 + ///algorithm producing a flow of maximum value in a directed
95.43 + ///graph. The preflow algorithms are the fastest known max flow algorithms
95.44 + ///up to now. The \e source node, the \e target node, the \e
95.45 + ///capacity of the edges and the \e starting \e flow value of the
95.46 + ///edges should be passed to the algorithm through the
95.47 + ///constructor. It is possible to change these quantities using the
95.48 + ///functions \ref source, \ref target, \ref capacityMap and \ref
95.49 + ///flowMap.
95.50 + ///
95.51 + ///After running \ref lemon::Preflow::phase1() "phase1()"
95.52 + ///or \ref lemon::Preflow::run() "run()", the maximal flow
95.53 + ///value can be obtained by calling \ref flowValue(). The minimum
95.54 + ///value cut can be written into a <tt>bool</tt> node map by
95.55 + ///calling \ref minCut(). (\ref minMinCut() and \ref maxMinCut() writes
95.56 + ///the inclusionwise minimum and maximum of the minimum value cuts,
95.57 + ///resp.)
95.58 + ///
95.59 + ///\param Graph The directed graph type the algorithm runs on.
95.60 + ///\param Num The number type of the capacities and the flow values.
95.61 + ///\param CapacityMap The capacity map type.
95.62 + ///\param FlowMap The flow map type.
95.63 + ///
95.64 + ///\author Jacint Szabo
95.65 + ///\todo Second template parameter is superfluous
95.66 + template <typename Graph, typename Num,
95.67 + typename CapacityMap=typename Graph::template EdgeMap<Num>,
95.68 + typename FlowMap=typename Graph::template EdgeMap<Num> >
95.69 + class Preflow {
95.70 + protected:
95.71 + typedef typename Graph::Node Node;
95.72 + typedef typename Graph::NodeIt NodeIt;
95.73 + typedef typename Graph::EdgeIt EdgeIt;
95.74 + typedef typename Graph::OutEdgeIt OutEdgeIt;
95.75 + typedef typename Graph::InEdgeIt InEdgeIt;
95.76 +
95.77 + typedef typename Graph::template NodeMap<Node> NNMap;
95.78 + typedef typename std::vector<Node> VecNode;
95.79 +
95.80 + const Graph* _g;
95.81 + Node _source;
95.82 + Node _target;
95.83 + const CapacityMap* _capacity;
95.84 + FlowMap* _flow;
95.85 + int _node_num; //the number of nodes of G
95.86 +
95.87 + typename Graph::template NodeMap<int> level;
95.88 + typename Graph::template NodeMap<Num> excess;
95.89 +
95.90 + // constants used for heuristics
95.91 + static const int H0=20;
95.92 + static const int H1=1;
95.93 +
95.94 + public:
95.95 +
95.96 + ///Indicates the property of the starting flow map.
95.97 +
95.98 + ///Indicates the property of the starting flow map.
95.99 + ///The meanings are as follows:
95.100 + ///- \c ZERO_FLOW: constant zero flow
95.101 + ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
95.102 + ///the sum of the out-flows in every node except the \e source and
95.103 + ///the \e target.
95.104 + ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at
95.105 + ///least the sum of the out-flows in every node except the \e source.
95.106 + ///- \c NO_FLOW: indicates an unspecified edge map. \c flow will be
95.107 + ///set to the constant zero flow in the beginning of
95.108 + ///the algorithm in this case.
95.109 + ///
95.110 + enum FlowEnum{
95.111 + NO_FLOW,
95.112 + ZERO_FLOW,
95.113 + GEN_FLOW,
95.114 + PRE_FLOW
95.115 + };
95.116 +
95.117 + ///Indicates the state of the preflow algorithm.
95.118 +
95.119 + ///Indicates the state of the preflow algorithm.
95.120 + ///The meanings are as follows:
95.121 + ///- \c AFTER_NOTHING: before running the algorithm or
95.122 + /// at an unspecified state.
95.123 + ///- \c AFTER_PREFLOW_PHASE_1: right after running \c phase1
95.124 + ///- \c AFTER_PREFLOW_PHASE_2: after running \ref phase2()
95.125 + ///
95.126 + enum StatusEnum {
95.127 + AFTER_NOTHING,
95.128 + AFTER_PREFLOW_PHASE_1,
95.129 + AFTER_PREFLOW_PHASE_2
95.130 + };
95.131 +
95.132 + protected:
95.133 + FlowEnum flow_prop;
95.134 + StatusEnum status; // Do not needle this flag only if necessary.
95.135 +
95.136 + public:
95.137 + ///The constructor of the class.
95.138 +
95.139 + ///The constructor of the class.
95.140 + ///\param _gr The directed graph the algorithm runs on.
95.141 + ///\param _s The source node.
95.142 + ///\param _t The target node.
95.143 + ///\param _cap The capacity of the edges.
95.144 + ///\param _f The flow of the edges.
95.145 + ///Except the graph, all of these parameters can be reset by
95.146 + ///calling \ref source, \ref target, \ref capacityMap and \ref
95.147 + ///flowMap, resp.
95.148 + Preflow(const Graph& _gr, Node _s, Node _t,
95.149 + const CapacityMap& _cap, FlowMap& _f) :
95.150 + _g(&_gr), _source(_s), _target(_t), _capacity(&_cap),
95.151 + _flow(&_f), _node_num(countNodes(_gr)), level(_gr), excess(_gr,0),
95.152 + flow_prop(NO_FLOW), status(AFTER_NOTHING) { }
95.153 +
95.154 +
95.155 +
95.156 + ///Runs the preflow algorithm.
95.157 +
95.158 + ///Runs the preflow algorithm.
95.159 + ///
95.160 + void run() {
95.161 + phase1(flow_prop);
95.162 + phase2();
95.163 + }
95.164 +
95.165 + ///Runs the preflow algorithm.
95.166 +
95.167 + ///Runs the preflow algorithm.
95.168 + ///\pre The starting flow map must be
95.169 + /// - a constant zero flow if \c fp is \c ZERO_FLOW,
95.170 + /// - an arbitrary flow if \c fp is \c GEN_FLOW,
95.171 + /// - an arbitrary preflow if \c fp is \c PRE_FLOW,
95.172 + /// - any map if \c fp is NO_FLOW.
95.173 + ///If the starting flow map is a flow or a preflow then
95.174 + ///the algorithm terminates faster.
95.175 + void run(FlowEnum fp) {
95.176 + flow_prop=fp;
95.177 + run();
95.178 + }
95.179 +
95.180 + ///Runs the first phase of the preflow algorithm.
95.181 +
95.182 + ///The preflow algorithm consists of two phases, this method runs
95.183 + ///the first phase. After the first phase the maximum flow value
95.184 + ///and a minimum value cut can already be computed, although a
95.185 + ///maximum flow is not yet obtained. So after calling this method
95.186 + ///\ref flowValue returns the value of a maximum flow and \ref
95.187 + ///minCut returns a minimum cut.
95.188 + ///\warning \ref minMinCut and \ref maxMinCut do not give minimum
95.189 + ///value cuts unless calling \ref phase2.
95.190 + ///\pre The starting flow must be
95.191 + ///- a constant zero flow if \c fp is \c ZERO_FLOW,
95.192 + ///- an arbitary flow if \c fp is \c GEN_FLOW,
95.193 + ///- an arbitary preflow if \c fp is \c PRE_FLOW,
95.194 + ///- any map if \c fp is NO_FLOW.
95.195 + void phase1(FlowEnum fp)
95.196 + {
95.197 + flow_prop=fp;
95.198 + phase1();
95.199 + }
95.200 +
95.201 +
95.202 + ///Runs the first phase of the preflow algorithm.
95.203 +
95.204 + ///The preflow algorithm consists of two phases, this method runs
95.205 + ///the first phase. After the first phase the maximum flow value
95.206 + ///and a minimum value cut can already be computed, although a
95.207 + ///maximum flow is not yet obtained. So after calling this method
95.208 + ///\ref flowValue returns the value of a maximum flow and \ref
95.209 + ///minCut returns a minimum cut.
95.210 + ///\warning \ref minCut(), \ref minMinCut() and \ref maxMinCut() do not
95.211 + ///give minimum value cuts unless calling \ref phase2().
95.212 + void phase1()
95.213 + {
95.214 + int heur0=(int)(H0*_node_num); //time while running 'bound decrease'
95.215 + int heur1=(int)(H1*_node_num); //time while running 'highest label'
95.216 + int heur=heur1; //starting time interval (#of relabels)
95.217 + int numrelabel=0;
95.218 +
95.219 + bool what_heur=1;
95.220 + //It is 0 in case 'bound decrease' and 1 in case 'highest label'
95.221 +
95.222 + bool end=false;
95.223 + //Needed for 'bound decrease', true means no active
95.224 + //nodes are above bound b.
95.225 +
95.226 + int k=_node_num-2; //bound on the highest level under n containing a node
95.227 + int b=k; //bound on the highest level under n of an active node
95.228 +
95.229 + VecNode first(_node_num, INVALID);
95.230 + NNMap next(*_g, INVALID);
95.231 +
95.232 + NNMap left(*_g, INVALID);
95.233 + NNMap right(*_g, INVALID);
95.234 + VecNode level_list(_node_num,INVALID);
95.235 + //List of the nodes in level i<n, set to n.
95.236 +
95.237 + preflowPreproc(first, next, level_list, left, right);
95.238 +
95.239 + //Push/relabel on the highest level active nodes.
95.240 + while ( true ) {
95.241 + if ( b == 0 ) {
95.242 + if ( !what_heur && !end && k > 0 ) {
95.243 + b=k;
95.244 + end=true;
95.245 + } else break;
95.246 + }
95.247 +
95.248 + if ( first[b]==INVALID ) --b;
95.249 + else {
95.250 + end=false;
95.251 + Node w=first[b];
95.252 + first[b]=next[w];
95.253 + int newlevel=push(w, next, first);
95.254 + if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list,
95.255 + left, right, b, k, what_heur);
95.256 +
95.257 + ++numrelabel;
95.258 + if ( numrelabel >= heur ) {
95.259 + numrelabel=0;
95.260 + if ( what_heur ) {
95.261 + what_heur=0;
95.262 + heur=heur0;
95.263 + end=false;
95.264 + } else {
95.265 + what_heur=1;
95.266 + heur=heur1;
95.267 + b=k;
95.268 + }
95.269 + }
95.270 + }
95.271 + }
95.272 + flow_prop=PRE_FLOW;
95.273 + status=AFTER_PREFLOW_PHASE_1;
95.274 + }
95.275 + // Heuristics:
95.276 + // 2 phase
95.277 + // gap
95.278 + // list 'level_list' on the nodes on level i implemented by hand
95.279 + // stack 'active' on the active nodes on level i
95.280 + // runs heuristic 'highest label' for H1*n relabels
95.281 + // runs heuristic 'bound decrease' for H0*n relabels,
95.282 + // starts with 'highest label'
95.283 + // Parameters H0 and H1 are initialized to 20 and 1.
95.284 +
95.285 +
95.286 + ///Runs the second phase of the preflow algorithm.
95.287 +
95.288 + ///The preflow algorithm consists of two phases, this method runs
95.289 + ///the second phase. After calling \ref phase1 and then \ref
95.290 + ///phase2, \ref flow contains a maximum flow, \ref flowValue
95.291 + ///returns the value of a maximum flow, \ref minCut returns a
95.292 + ///minimum cut, while the methods \ref minMinCut and \ref
95.293 + ///maxMinCut return the inclusionwise minimum and maximum cuts of
95.294 + ///minimum value, resp. \pre \ref phase1 must be called before.
95.295 + void phase2()
95.296 + {
95.297 +
95.298 + int k=_node_num-2; //bound on the highest level under n containing a node
95.299 + int b=k; //bound on the highest level under n of an active node
95.300 +
95.301 +
95.302 + VecNode first(_node_num, INVALID);
95.303 + NNMap next(*_g, INVALID);
95.304 + level.set(_source,0);
95.305 + std::queue<Node> bfs_queue;
95.306 + bfs_queue.push(_source);
95.307 +
95.308 + while ( !bfs_queue.empty() ) {
95.309 +
95.310 + Node v=bfs_queue.front();
95.311 + bfs_queue.pop();
95.312 + int l=level[v]+1;
95.313 +
95.314 + for(InEdgeIt e(*_g,v); e!=INVALID; ++e) {
95.315 + if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
95.316 + Node u=_g->source(e);
95.317 + if ( level[u] >= _node_num ) {
95.318 + bfs_queue.push(u);
95.319 + level.set(u, l);
95.320 + if ( excess[u] > 0 ) {
95.321 + next.set(u,first[l]);
95.322 + first[l]=u;
95.323 + }
95.324 + }
95.325 + }
95.326 +
95.327 + for(OutEdgeIt e(*_g,v); e!=INVALID; ++e) {
95.328 + if ( 0 >= (*_flow)[e] ) continue;
95.329 + Node u=_g->target(e);
95.330 + if ( level[u] >= _node_num ) {
95.331 + bfs_queue.push(u);
95.332 + level.set(u, l);
95.333 + if ( excess[u] > 0 ) {
95.334 + next.set(u,first[l]);
95.335 + first[l]=u;
95.336 + }
95.337 + }
95.338 + }
95.339 + }
95.340 + b=_node_num-2;
95.341 +
95.342 + while ( true ) {
95.343 +
95.344 + if ( b == 0 ) break;
95.345 + if ( first[b]==INVALID ) --b;
95.346 + else {
95.347 + Node w=first[b];
95.348 + first[b]=next[w];
95.349 + int newlevel=push(w,next, first);
95.350 +
95.351 + //relabel
95.352 + if ( excess[w] > 0 ) {
95.353 + level.set(w,++newlevel);
95.354 + next.set(w,first[newlevel]);
95.355 + first[newlevel]=w;
95.356 + b=newlevel;
95.357 + }
95.358 + }
95.359 + } // while(true)
95.360 + flow_prop=GEN_FLOW;
95.361 + status=AFTER_PREFLOW_PHASE_2;
95.362 + }
95.363 +
95.364 + /// Returns the value of the maximum flow.
95.365 +
95.366 + /// Returns the value of the maximum flow by returning the excess
95.367 + /// of the target node \c t. This value equals to the value of
95.368 + /// the maximum flow already after running \ref phase1.
95.369 + Num flowValue() const {
95.370 + return excess[_target];
95.371 + }
95.372 +
95.373 +
95.374 + ///Returns a minimum value cut.
95.375 +
95.376 + ///Sets \c M to the characteristic vector of a minimum value
95.377 + ///cut. This method can be called both after running \ref
95.378 + ///phase1 and \ref phase2. It is much faster after
95.379 + ///\ref phase1. \pre M should be a bool-valued node-map. \pre
95.380 + ///If \ref minCut() is called after \ref phase2() then M should
95.381 + ///be initialized to false.
95.382 + template<typename _CutMap>
95.383 + void minCut(_CutMap& M) const {
95.384 + switch ( status ) {
95.385 + case AFTER_PREFLOW_PHASE_1:
95.386 + for(NodeIt v(*_g); v!=INVALID; ++v) {
95.387 + if (level[v] < _node_num) {
95.388 + M.set(v, false);
95.389 + } else {
95.390 + M.set(v, true);
95.391 + }
95.392 + }
95.393 + break;
95.394 + case AFTER_PREFLOW_PHASE_2:
95.395 + minMinCut(M);
95.396 + break;
95.397 + case AFTER_NOTHING:
95.398 + break;
95.399 + }
95.400 + }
95.401 +
95.402 + ///Returns the inclusionwise minimum of the minimum value cuts.
95.403 +
95.404 + ///Sets \c M to the characteristic vector of the minimum value cut
95.405 + ///which is inclusionwise minimum. It is computed by processing a
95.406 + ///bfs from the source node \c s in the residual graph. \pre M
95.407 + ///should be a node map of bools initialized to false. \pre \ref
95.408 + ///phase2 should already be run.
95.409 + template<typename _CutMap>
95.410 + void minMinCut(_CutMap& M) const {
95.411 +
95.412 + std::queue<Node> queue;
95.413 + M.set(_source,true);
95.414 + queue.push(_source);
95.415 +
95.416 + while (!queue.empty()) {
95.417 + Node w=queue.front();
95.418 + queue.pop();
95.419 +
95.420 + for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.421 + Node v=_g->target(e);
95.422 + if (!M[v] && (*_flow)[e] < (*_capacity)[e] ) {
95.423 + queue.push(v);
95.424 + M.set(v, true);
95.425 + }
95.426 + }
95.427 +
95.428 + for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.429 + Node v=_g->source(e);
95.430 + if (!M[v] && (*_flow)[e] > 0 ) {
95.431 + queue.push(v);
95.432 + M.set(v, true);
95.433 + }
95.434 + }
95.435 + }
95.436 + }
95.437 +
95.438 + ///Returns the inclusionwise maximum of the minimum value cuts.
95.439 +
95.440 + ///Sets \c M to the characteristic vector of the minimum value cut
95.441 + ///which is inclusionwise maximum. It is computed by processing a
95.442 + ///backward bfs from the target node \c t in the residual graph.
95.443 + ///\pre \ref phase2() or run() should already be run.
95.444 + template<typename _CutMap>
95.445 + void maxMinCut(_CutMap& M) const {
95.446 +
95.447 + for(NodeIt v(*_g) ; v!=INVALID; ++v) M.set(v, true);
95.448 +
95.449 + std::queue<Node> queue;
95.450 +
95.451 + M.set(_target,false);
95.452 + queue.push(_target);
95.453 +
95.454 + while (!queue.empty()) {
95.455 + Node w=queue.front();
95.456 + queue.pop();
95.457 +
95.458 + for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.459 + Node v=_g->source(e);
95.460 + if (M[v] && (*_flow)[e] < (*_capacity)[e] ) {
95.461 + queue.push(v);
95.462 + M.set(v, false);
95.463 + }
95.464 + }
95.465 +
95.466 + for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.467 + Node v=_g->target(e);
95.468 + if (M[v] && (*_flow)[e] > 0 ) {
95.469 + queue.push(v);
95.470 + M.set(v, false);
95.471 + }
95.472 + }
95.473 + }
95.474 + }
95.475 +
95.476 + ///Sets the source node to \c _s.
95.477 +
95.478 + ///Sets the source node to \c _s.
95.479 + ///
95.480 + void source(Node _s) {
95.481 + _source=_s;
95.482 + if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW;
95.483 + status=AFTER_NOTHING;
95.484 + }
95.485 +
95.486 + ///Returns the source node.
95.487 +
95.488 + ///Returns the source node.
95.489 + ///
95.490 + Node source() const {
95.491 + return _source;
95.492 + }
95.493 +
95.494 + ///Sets the target node to \c _t.
95.495 +
95.496 + ///Sets the target node to \c _t.
95.497 + ///
95.498 + void target(Node _t) {
95.499 + _target=_t;
95.500 + if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW;
95.501 + status=AFTER_NOTHING;
95.502 + }
95.503 +
95.504 + ///Returns the target node.
95.505 +
95.506 + ///Returns the target node.
95.507 + ///
95.508 + Node target() const {
95.509 + return _target;
95.510 + }
95.511 +
95.512 + /// Sets the edge map of the capacities to _cap.
95.513 +
95.514 + /// Sets the edge map of the capacities to _cap.
95.515 + ///
95.516 + void capacityMap(const CapacityMap& _cap) {
95.517 + _capacity=&_cap;
95.518 + status=AFTER_NOTHING;
95.519 + }
95.520 + /// Returns a reference to capacity map.
95.521 +
95.522 + /// Returns a reference to capacity map.
95.523 + ///
95.524 + const CapacityMap &capacityMap() const {
95.525 + return *_capacity;
95.526 + }
95.527 +
95.528 + /// Sets the edge map of the flows to _flow.
95.529 +
95.530 + /// Sets the edge map of the flows to _flow.
95.531 + ///
95.532 + void flowMap(FlowMap& _f) {
95.533 + _flow=&_f;
95.534 + flow_prop=NO_FLOW;
95.535 + status=AFTER_NOTHING;
95.536 + }
95.537 +
95.538 + /// Returns a reference to flow map.
95.539 +
95.540 + /// Returns a reference to flow map.
95.541 + ///
95.542 + const FlowMap &flowMap() const {
95.543 + return *_flow;
95.544 + }
95.545 +
95.546 + private:
95.547 +
95.548 + int push(Node w, NNMap& next, VecNode& first) {
95.549 +
95.550 + int lev=level[w];
95.551 + Num exc=excess[w];
95.552 + int newlevel=_node_num; //bound on the next level of w
95.553 +
95.554 + for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.555 + if ( (*_flow)[e] >= (*_capacity)[e] ) continue;
95.556 + Node v=_g->target(e);
95.557 +
95.558 + if( lev > level[v] ) { //Push is allowed now
95.559 +
95.560 + if ( excess[v]<=0 && v!=_target && v!=_source ) {
95.561 + next.set(v,first[level[v]]);
95.562 + first[level[v]]=v;
95.563 + }
95.564 +
95.565 + Num cap=(*_capacity)[e];
95.566 + Num flo=(*_flow)[e];
95.567 + Num remcap=cap-flo;
95.568 +
95.569 + if ( remcap >= exc ) { //A nonsaturating push.
95.570 +
95.571 + _flow->set(e, flo+exc);
95.572 + excess.set(v, excess[v]+exc);
95.573 + exc=0;
95.574 + break;
95.575 +
95.576 + } else { //A saturating push.
95.577 + _flow->set(e, cap);
95.578 + excess.set(v, excess[v]+remcap);
95.579 + exc-=remcap;
95.580 + }
95.581 + } else if ( newlevel > level[v] ) newlevel = level[v];
95.582 + } //for out edges wv
95.583 +
95.584 + if ( exc > 0 ) {
95.585 + for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
95.586 +
95.587 + if( (*_flow)[e] <= 0 ) continue;
95.588 + Node v=_g->source(e);
95.589 +
95.590 + if( lev > level[v] ) { //Push is allowed now
95.591 +
95.592 + if ( excess[v]<=0 && v!=_target && v!=_source ) {
95.593 + next.set(v,first[level[v]]);
95.594 + first[level[v]]=v;
95.595 + }
95.596 +
95.597 + Num flo=(*_flow)[e];
95.598 +
95.599 + if ( flo >= exc ) { //A nonsaturating push.
95.600 +
95.601 + _flow->set(e, flo-exc);
95.602 + excess.set(v, excess[v]+exc);
95.603 + exc=0;
95.604 + break;
95.605 + } else { //A saturating push.
95.606 +
95.607 + excess.set(v, excess[v]+flo);
95.608 + exc-=flo;
95.609 + _flow->set(e,0);
95.610 + }
95.611 + } else if ( newlevel > level[v] ) newlevel = level[v];
95.612 + } //for in edges vw
95.613 +
95.614 + } // if w still has excess after the out edge for cycle
95.615 +
95.616 + excess.set(w, exc);
95.617 +
95.618 + return newlevel;
95.619 + }
95.620 +
95.621 +
95.622 +
95.623 + void preflowPreproc(VecNode& first, NNMap& next,
95.624 + VecNode& level_list, NNMap& left, NNMap& right)
95.625 + {
95.626 + for(NodeIt v(*_g); v!=INVALID; ++v) level.set(v,_node_num);
95.627 + std::queue<Node> bfs_queue;
95.628 +
95.629 + if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) {
95.630 + //Reverse_bfs from t in the residual graph,
95.631 + //to find the starting level.
95.632 + level.set(_target,0);
95.633 + bfs_queue.push(_target);
95.634 +
95.635 + while ( !bfs_queue.empty() ) {
95.636 +
95.637 + Node v=bfs_queue.front();
95.638 + bfs_queue.pop();
95.639 + int l=level[v]+1;
95.640 +
95.641 + for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
95.642 + if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
95.643 + Node w=_g->source(e);
95.644 + if ( level[w] == _node_num && w != _source ) {
95.645 + bfs_queue.push(w);
95.646 + Node z=level_list[l];
95.647 + if ( z!=INVALID ) left.set(z,w);
95.648 + right.set(w,z);
95.649 + level_list[l]=w;
95.650 + level.set(w, l);
95.651 + }
95.652 + }
95.653 +
95.654 + for(OutEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
95.655 + if ( 0 >= (*_flow)[e] ) continue;
95.656 + Node w=_g->target(e);
95.657 + if ( level[w] == _node_num && w != _source ) {
95.658 + bfs_queue.push(w);
95.659 + Node z=level_list[l];
95.660 + if ( z!=INVALID ) left.set(z,w);
95.661 + right.set(w,z);
95.662 + level_list[l]=w;
95.663 + level.set(w, l);
95.664 + }
95.665 + }
95.666 + } //while
95.667 + } //if
95.668 +
95.669 +
95.670 + switch (flow_prop) {
95.671 + case NO_FLOW:
95.672 + for(EdgeIt e(*_g); e!=INVALID; ++e) _flow->set(e,0);
95.673 + case ZERO_FLOW:
95.674 + for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
95.675 +
95.676 + //Reverse_bfs from t, to find the starting level.
95.677 + level.set(_target,0);
95.678 + bfs_queue.push(_target);
95.679 +
95.680 + while ( !bfs_queue.empty() ) {
95.681 +
95.682 + Node v=bfs_queue.front();
95.683 + bfs_queue.pop();
95.684 + int l=level[v]+1;
95.685 +
95.686 + for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
95.687 + Node w=_g->source(e);
95.688 + if ( level[w] == _node_num && w != _source ) {
95.689 + bfs_queue.push(w);
95.690 + Node z=level_list[l];
95.691 + if ( z!=INVALID ) left.set(z,w);
95.692 + right.set(w,z);
95.693 + level_list[l]=w;
95.694 + level.set(w, l);
95.695 + }
95.696 + }
95.697 + }
95.698 +
95.699 + //the starting flow
95.700 + for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
95.701 + Num c=(*_capacity)[e];
95.702 + if ( c <= 0 ) continue;
95.703 + Node w=_g->target(e);
95.704 + if ( level[w] < _node_num ) {
95.705 + if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
95.706 + next.set(w,first[level[w]]);
95.707 + first[level[w]]=w;
95.708 + }
95.709 + _flow->set(e, c);
95.710 + excess.set(w, excess[w]+c);
95.711 + }
95.712 + }
95.713 + break;
95.714 +
95.715 + case GEN_FLOW:
95.716 + for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
95.717 + {
95.718 + Num exc=0;
95.719 + for(InEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc+=(*_flow)[e];
95.720 + for(OutEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc-=(*_flow)[e];
95.721 + excess.set(_target,exc);
95.722 + }
95.723 +
95.724 + //the starting flow
95.725 + for(OutEdgeIt e(*_g,_source); e!=INVALID; ++e) {
95.726 + Num rem=(*_capacity)[e]-(*_flow)[e];
95.727 + if ( rem <= 0 ) continue;
95.728 + Node w=_g->target(e);
95.729 + if ( level[w] < _node_num ) {
95.730 + if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
95.731 + next.set(w,first[level[w]]);
95.732 + first[level[w]]=w;
95.733 + }
95.734 + _flow->set(e, (*_capacity)[e]);
95.735 + excess.set(w, excess[w]+rem);
95.736 + }
95.737 + }
95.738 +
95.739 + for(InEdgeIt e(*_g,_source); e!=INVALID; ++e) {
95.740 + if ( (*_flow)[e] <= 0 ) continue;
95.741 + Node w=_g->source(e);
95.742 + if ( level[w] < _node_num ) {
95.743 + if ( excess[w] <= 0 && w!=_target ) {
95.744 + next.set(w,first[level[w]]);
95.745 + first[level[w]]=w;
95.746 + }
95.747 + excess.set(w, excess[w]+(*_flow)[e]);
95.748 + _flow->set(e, 0);
95.749 + }
95.750 + }
95.751 + break;
95.752 +
95.753 + case PRE_FLOW:
95.754 + //the starting flow
95.755 + for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
95.756 + Num rem=(*_capacity)[e]-(*_flow)[e];
95.757 + if ( rem <= 0 ) continue;
95.758 + Node w=_g->target(e);
95.759 + if ( level[w] < _node_num ) _flow->set(e, (*_capacity)[e]);
95.760 + }
95.761 +
95.762 + for(InEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
95.763 + if ( (*_flow)[e] <= 0 ) continue;
95.764 + Node w=_g->source(e);
95.765 + if ( level[w] < _node_num ) _flow->set(e, 0);
95.766 + }
95.767 +
95.768 + //computing the excess
95.769 + for(NodeIt w(*_g); w!=INVALID; ++w) {
95.770 + Num exc=0;
95.771 + for(InEdgeIt e(*_g,w); e!=INVALID; ++e) exc+=(*_flow)[e];
95.772 + for(OutEdgeIt e(*_g,w); e!=INVALID; ++e) exc-=(*_flow)[e];
95.773 + excess.set(w,exc);
95.774 +
95.775 + //putting the active nodes into the stack
95.776 + int lev=level[w];
95.777 + if ( exc > 0 && lev < _node_num && Node(w) != _target ) {
95.778 + next.set(w,first[lev]);
95.779 + first[lev]=w;
95.780 + }
95.781 + }
95.782 + break;
95.783 + } //switch
95.784 + } //preflowPreproc
95.785 +
95.786 +
95.787 + void relabel(Node w, int newlevel, VecNode& first, NNMap& next,
95.788 + VecNode& level_list, NNMap& left,
95.789 + NNMap& right, int& b, int& k, bool what_heur )
95.790 + {
95.791 +
95.792 + int lev=level[w];
95.793 +
95.794 + Node right_n=right[w];
95.795 + Node left_n=left[w];
95.796 +
95.797 + //unlacing starts
95.798 + if ( right_n!=INVALID ) {
95.799 + if ( left_n!=INVALID ) {
95.800 + right.set(left_n, right_n);
95.801 + left.set(right_n, left_n);
95.802 + } else {
95.803 + level_list[lev]=right_n;
95.804 + left.set(right_n, INVALID);
95.805 + }
95.806 + } else {
95.807 + if ( left_n!=INVALID ) {
95.808 + right.set(left_n, INVALID);
95.809 + } else {
95.810 + level_list[lev]=INVALID;
95.811 + }
95.812 + }
95.813 + //unlacing ends
95.814 +
95.815 + if ( level_list[lev]==INVALID ) {
95.816 +
95.817 + //gapping starts
95.818 + for (int i=lev; i!=k ; ) {
95.819 + Node v=level_list[++i];
95.820 + while ( v!=INVALID ) {
95.821 + level.set(v,_node_num);
95.822 + v=right[v];
95.823 + }
95.824 + level_list[i]=INVALID;
95.825 + if ( !what_heur ) first[i]=INVALID;
95.826 + }
95.827 +
95.828 + level.set(w,_node_num);
95.829 + b=lev-1;
95.830 + k=b;
95.831 + //gapping ends
95.832 +
95.833 + } else {
95.834 +
95.835 + if ( newlevel == _node_num ) level.set(w,_node_num);
95.836 + else {
95.837 + level.set(w,++newlevel);
95.838 + next.set(w,first[newlevel]);
95.839 + first[newlevel]=w;
95.840 + if ( what_heur ) b=newlevel;
95.841 + if ( k < newlevel ) ++k; //now k=newlevel
95.842 + Node z=level_list[newlevel];
95.843 + if ( z!=INVALID ) left.set(z,w);
95.844 + right.set(w,z);
95.845 + left.set(w,INVALID);
95.846 + level_list[newlevel]=w;
95.847 + }
95.848 + }
95.849 + } //relabel
95.850 +
95.851 + };
95.852 +
95.853 + ///Function type interface for Preflow algorithm.
95.854 +
95.855 + /// \ingroup flowalgs
95.856 + ///Function type interface for Preflow algorithm.
95.857 + ///\sa Preflow
95.858 + template<class GR, class CM, class FM>
95.859 + Preflow<GR,typename CM::Value,CM,FM> preflow(const GR &g,
95.860 + typename GR::Node source,
95.861 + typename GR::Node target,
95.862 + const CM &cap,
95.863 + FM &flow
95.864 + )
95.865 + {
95.866 + return Preflow<GR,typename CM::Value,CM,FM>(g,source,target,cap,flow);
95.867 + }
95.868 +
95.869 +} //namespace lemon
95.870 +
95.871 +#endif //LEMON_PREFLOW_H
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/lemon/radix_heap.h Mon May 23 04:48:14 2005 +0000
96.3 @@ -0,0 +1,412 @@
96.4 +/* -*- C++ -*-
96.5 + * lemon/radix_heap.h - Part of LEMON, a generic C++ optimization library
96.6 + *
96.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
96.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
96.9 + *
96.10 + * Permission to use, modify and distribute this software is granted
96.11 + * provided that this copyright notice appears in all copies. For
96.12 + * precise terms see the accompanying LICENSE file.
96.13 + *
96.14 + * This software is provided "AS IS" with no warranty of any kind,
96.15 + * express or implied, and with no claim as to its suitability for any
96.16 + * purpose.
96.17 + *
96.18 + */
96.19 +
96.20 +#ifndef LEMON_RADIX_HEAP_H
96.21 +#define LEMON_RADIX_HEAP_H
96.22 +
96.23 +///\ingroup auxdat
96.24 +///\file
96.25 +///\brief Radix Heap implementation.
96.26 +
96.27 +#include <vector>
96.28 +#include <lemon/error.h>
96.29 +
96.30 +namespace lemon {
96.31 +
96.32 + /// \addtogroup auxdat
96.33 + /// @{
96.34 +
96.35 + /// \brief Exception thrown by RadixHeap.
96.36 + ///
96.37 + /// This Exception is thrown when a smaller priority
96.38 + /// is inserted into the \e RadixHeap then the last time erased.
96.39 + /// \see RadixHeap
96.40 + /// \author Balazs Dezso
96.41 +
96.42 + class UnderFlowPriorityError : public RuntimeError {
96.43 + public:
96.44 + virtual const char* exceptionName() const {
96.45 + return "lemon::UnderFlowPriorityError";
96.46 + }
96.47 + };
96.48 +
96.49 + /// \brief A Radix Heap implementation.
96.50 + ///
96.51 + /// This class implements the \e radix \e heap data structure. A \e heap
96.52 + /// is a data structure for storing items with specified values called \e
96.53 + /// priorities in such a way that finding the item with minimum priority is
96.54 + /// efficient. This heap type can store only items with \e int priority.
96.55 + /// In a heap one can change the priority of an item, add or erase an
96.56 + /// item, but the priority cannot be decreased under the last removed
96.57 + /// item's priority.
96.58 + ///
96.59 + /// \param _Item Type of the items to be stored.
96.60 + /// \param _ItemIntMap A read and writable Item int map, used internally
96.61 + /// to handle the cross references.
96.62 + ///
96.63 + /// \see BinHeap
96.64 + /// \see Dijkstra
96.65 + /// \author Balazs Dezso
96.66 +
96.67 + template <typename _Item, typename _ItemIntMap>
96.68 + class RadixHeap {
96.69 +
96.70 + public:
96.71 + typedef _Item Item;
96.72 + typedef int Prio;
96.73 + typedef _ItemIntMap ItemIntMap;
96.74 +
96.75 + /// \brief Type to represent the items states.
96.76 + ///
96.77 + /// Each Item element have a state associated to it. It may be "in heap",
96.78 + /// "pre heap" or "post heap". The latter two are indifferent from the
96.79 + /// heap's point of view, but may be useful to the user.
96.80 + ///
96.81 + /// The ItemIntMap \e should be initialized in such way that it maps
96.82 + /// PRE_HEAP (-1) to any element to be put in the heap...
96.83 + enum state_enum {
96.84 + IN_HEAP = 0,
96.85 + PRE_HEAP = -1,
96.86 + POST_HEAP = -2
96.87 + };
96.88 +
96.89 + private:
96.90 +
96.91 + struct RadixItem {
96.92 + int prev, next, box;
96.93 + Item item;
96.94 + int prio;
96.95 + RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
96.96 + };
96.97 +
96.98 + struct RadixBox {
96.99 + int first;
96.100 + int min, size;
96.101 + RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
96.102 + };
96.103 +
96.104 + std::vector<RadixItem> data;
96.105 + std::vector<RadixBox> boxes;
96.106 +
96.107 + ItemIntMap &iim;
96.108 +
96.109 +
96.110 + public:
96.111 + /// \brief The constructor.
96.112 + ///
96.113 + /// The constructor.
96.114 + /// \param _iim should be given to the constructor, since it is used
96.115 + /// internally to handle the cross references. The value of the map
96.116 + /// should be PRE_HEAP (-1) for each element.
96.117 + explicit RadixHeap(ItemIntMap &_iim) : iim(_iim) {
96.118 + boxes.push_back(RadixBox(0, 1));
96.119 + boxes.push_back(RadixBox(1, 1));
96.120 + }
96.121 +
96.122 + /// \brief The constructor.
96.123 + ///
96.124 + /// The constructor.
96.125 + ///
96.126 + /// \param _iim It should be given to the constructor, since it is used
96.127 + /// internally to handle the cross references. The value of the map
96.128 + /// should be PRE_HEAP (-1) for each element.
96.129 + ///
96.130 + /// \param capacity It determines the initial capacity of the heap.
96.131 + RadixHeap(ItemIntMap &_iim, int capacity) : iim(_iim) {
96.132 + boxes.push_back(RadixBox(0, 1));
96.133 + boxes.push_back(RadixBox(1, 1));
96.134 + while (upper(boxes.back(), capacity)) {
96.135 + extend();
96.136 + }
96.137 + }
96.138 +
96.139 + /// The number of items stored in the heap.
96.140 + ///
96.141 + /// \brief Returns the number of items stored in the heap.
96.142 + int size() const { return data.size(); }
96.143 + /// \brief Checks if the heap stores no items.
96.144 + ///
96.145 + /// Returns \c true if and only if the heap stores no items.
96.146 + bool empty() const { return data.empty(); }
96.147 +
96.148 + private:
96.149 +
96.150 + bool upper(int box, Prio prio) {
96.151 + return prio < boxes[box].min;
96.152 + }
96.153 +
96.154 + bool lower(int box, Prio prio) {
96.155 + return prio >= boxes[box].min + boxes[box].size;
96.156 + }
96.157 +
96.158 + /// \brief Remove item from the box list.
96.159 + void remove(int index) {
96.160 + if (data[index].prev >= 0) {
96.161 + data[data[index].prev].next = data[index].next;
96.162 + } else {
96.163 + boxes[data[index].box].first = data[index].next;
96.164 + }
96.165 + if (data[index].next >= 0) {
96.166 + data[data[index].next].prev = data[index].prev;
96.167 + }
96.168 + }
96.169 +
96.170 + /// \brief Insert item into the box list.
96.171 + void insert(int box, int index) {
96.172 + if (boxes[box].first == -1) {
96.173 + boxes[box].first = index;
96.174 + data[index].next = data[index].prev = -1;
96.175 + } else {
96.176 + data[index].next = boxes[box].first;
96.177 + data[boxes[box].first].prev = index;
96.178 + data[index].prev = -1;
96.179 + boxes[box].first = index;
96.180 + }
96.181 + data[index].box = box;
96.182 + }
96.183 +
96.184 + /// \brief Add a new box to the box list.
96.185 + void extend() {
96.186 + int min = boxes.back().min + boxes.back().size;
96.187 + int size = 2 * boxes.back().size;
96.188 + boxes.push_back(RadixBox(min, size));
96.189 + }
96.190 +
96.191 + /// \brief Move an item up into the proper box.
96.192 + void bubble_up(int index) {
96.193 + if (!lower(data[index].box, data[index].prio)) return;
96.194 + remove(index);
96.195 + int box = findUp(data[index].box, data[index].prio);
96.196 + insert(box, index);
96.197 + }
96.198 +
96.199 + /// \brief Find up the proper box for the item with the given prio.
96.200 + int findUp(int start, int prio) {
96.201 + while (lower(start, prio)) {
96.202 + if (++start == (int)boxes.size()) {
96.203 + extend();
96.204 + }
96.205 + }
96.206 + return start;
96.207 + }
96.208 +
96.209 + /// \brief Move an item down into the proper box.
96.210 + void bubble_down(int index) {
96.211 + if (!upper(data[index].box, data[index].prio)) return;
96.212 + remove(index);
96.213 + int box = findDown(data[index].box, data[index].prio);
96.214 + insert(box, index);
96.215 + }
96.216 +
96.217 + /// \brief Find up the proper box for the item with the given prio.
96.218 + int findDown(int start, int prio) {
96.219 + while (upper(start, prio)) {
96.220 + if (--start < 0) throw UnderFlowPriorityError();
96.221 + }
96.222 + return start;
96.223 + }
96.224 +
96.225 + /// \brief Find the first not empty box.
96.226 + int findFirst() {
96.227 + int first = 0;
96.228 + while (boxes[first].first == -1) ++first;
96.229 + return first;
96.230 + }
96.231 +
96.232 + /// \brief Gives back the minimal prio of the box.
96.233 + int minValue(int box) {
96.234 + int min = data[boxes[box].first].prio;
96.235 + for (int k = boxes[box].first; k != -1; k = data[k].next) {
96.236 + if (data[k].prio < min) min = data[k].prio;
96.237 + }
96.238 + return min;
96.239 + }
96.240 +
96.241 + /// \brief Rearrange the items of the heap and makes the
96.242 + /// first box not empty.
96.243 + void moveDown() {
96.244 + int box = findFirst();
96.245 + if (box == 0) return;
96.246 + int min = minValue(box);
96.247 + for (int i = 0; i <= box; ++i) {
96.248 + boxes[i].min = min;
96.249 + min += boxes[i].size;
96.250 + }
96.251 + int curr = boxes[box].first, next;
96.252 + while (curr != -1) {
96.253 + next = data[curr].next;
96.254 + bubble_down(curr);
96.255 + curr = next;
96.256 + }
96.257 + }
96.258 +
96.259 + void relocate_last(int index) {
96.260 + if (index != (int)data.size() - 1) {
96.261 + data[index] = data.back();
96.262 + if (data[index].prev != -1) {
96.263 + data[data[index].prev].next = index;
96.264 + } else {
96.265 + boxes[data[index].box].first = index;
96.266 + }
96.267 + if (data[index].next != -1) {
96.268 + data[data[index].next].prev = index;
96.269 + }
96.270 + iim[data[index].item] = index;
96.271 + }
96.272 + data.pop_back();
96.273 + }
96.274 +
96.275 + public:
96.276 +
96.277 + /// \brief Insert an item into the heap with the given heap.
96.278 + ///
96.279 + /// Adds \c i to the heap with priority \c p.
96.280 + /// \param i The item to insert.
96.281 + /// \param p The priority of the item.
96.282 + void push(const Item &i, const Prio &p) {
96.283 + int n = data.size();
96.284 + iim.set(i, n);
96.285 + data.push_back(RadixItem(i, p));
96.286 + while (lower(boxes.size() - 1, p)) {
96.287 + extend();
96.288 + }
96.289 + int box = findDown(boxes.size() - 1, p);
96.290 + insert(box, n);
96.291 + }
96.292 +
96.293 + /// \brief Returns the item with minimum priority.
96.294 + ///
96.295 + /// This method returns the item with minimum priority.
96.296 + /// \pre The heap must be nonempty.
96.297 + Item top() const {
96.298 + const_cast<RadixHeap<Item, ItemIntMap>*>(this)->moveDown();
96.299 + return data[boxes[0].first].item;
96.300 + }
96.301 +
96.302 + /// \brief Returns the minimum priority.
96.303 + ///
96.304 + /// It returns the minimum priority.
96.305 + /// \pre The heap must be nonempty.
96.306 + Prio prio() const {
96.307 + const_cast<RadixHeap<Item, ItemIntMap>*>(this)->moveDown();
96.308 + return data[boxes[0].first].prio;
96.309 + }
96.310 +
96.311 + /// \brief Deletes the item with minimum priority.
96.312 + ///
96.313 + /// This method deletes the item with minimum priority.
96.314 + /// \pre The heap must be non-empty.
96.315 + void pop() {
96.316 + moveDown();
96.317 + int index = boxes[0].first;
96.318 + iim[data[index].item] = POST_HEAP;
96.319 + remove(index);
96.320 + relocate_last(index);
96.321 + }
96.322 +
96.323 + /// \brief Deletes \c i from the heap.
96.324 + ///
96.325 + /// This method deletes item \c i from the heap, if \c i was
96.326 + /// already stored in the heap.
96.327 + /// \param i The item to erase.
96.328 + void erase(const Item &i) {
96.329 + int index = iim[i];
96.330 + iim[i] = POST_HEAP;
96.331 + remove(index);
96.332 + relocate_last(index);
96.333 + }
96.334 +
96.335 + /// \brief Returns the priority of \c i.
96.336 + ///
96.337 + /// This function returns the priority of item \c i.
96.338 + /// \pre \c i must be in the heap.
96.339 + /// \param i The item.
96.340 + Prio operator[](const Item &i) const {
96.341 + int idx = iim[i];
96.342 + return data[idx].prio;
96.343 + }
96.344 +
96.345 + /// \brief \c i gets to the heap with priority \c p independently
96.346 + /// if \c i was already there.
96.347 + ///
96.348 + /// This method calls \ref push(\c i, \c p) if \c i is not stored
96.349 + /// in the heap and sets the priority of \c i to \c p otherwise.
96.350 + /// It may throw an \e UnderFlowPriorityException.
96.351 + /// \param i The item.
96.352 + /// \param p The priority.
96.353 + void set(const Item &i, const Prio &p) {
96.354 + int idx = iim[i];
96.355 + if( idx < 0 ) {
96.356 + push(i, p);
96.357 + }
96.358 + else if( p >= data[idx].prio ) {
96.359 + data[idx].prio = p;
96.360 + bubble_up(idx);
96.361 + } else {
96.362 + data[idx].prio = p;
96.363 + bubble_down(idx);
96.364 + }
96.365 + }
96.366 +
96.367 +
96.368 + /// \brief Decreases the priority of \c i to \c p.
96.369 + ///
96.370 + /// This method decreases the priority of item \c i to \c p.
96.371 + /// \pre \c i must be stored in the heap with priority at least \c p, and
96.372 + /// \c should be greater then the last removed item's priority.
96.373 + /// \param i The item.
96.374 + /// \param p The priority.
96.375 + void decrease(const Item &i, const Prio &p) {
96.376 + int idx = iim[i];
96.377 + data[idx].prio = p;
96.378 + bubble_down(idx);
96.379 + }
96.380 +
96.381 + /// \brief Increases the priority of \c i to \c p.
96.382 + ///
96.383 + /// This method sets the priority of item \c i to \c p.
96.384 + /// \pre \c i must be stored in the heap with priority at most \c
96.385 + /// p relative to \c Compare.
96.386 + /// \param i The item.
96.387 + /// \param p The priority.
96.388 + void increase(const Item &i, const Prio &p) {
96.389 + int idx = iim[i];
96.390 + data[idx].prio = p;
96.391 + bubble_up(idx);
96.392 + }
96.393 +
96.394 + /// \brief Returns if \c item is in, has already been in, or has
96.395 + /// never been in the heap.
96.396 + ///
96.397 + /// This method returns PRE_HEAP if \c item has never been in the
96.398 + /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
96.399 + /// otherwise. In the latter case it is possible that \c item will
96.400 + /// get back to the heap again.
96.401 + /// \param i The item.
96.402 + state_enum state(const Item &i) const {
96.403 + int s = iim[i];
96.404 + if( s >= 0 ) s = 0;
96.405 + return state_enum(s);
96.406 + }
96.407 +
96.408 + }; // class RadixHeap
96.409 +
96.410 +
96.411 + ///@}
96.412 +
96.413 +} // namespace lemon
96.414 +
96.415 +#endif // LEMON_RADIX_HEAP_H
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/lemon/smart_graph.h Mon May 23 04:48:14 2005 +0000
97.3 @@ -0,0 +1,414 @@
97.4 +/* -*- C++ -*-
97.5 + * lemon/smart_graph.h - Part of LEMON, a generic C++ optimization library
97.6 + *
97.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
97.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
97.9 + *
97.10 + * Permission to use, modify and distribute this software is granted
97.11 + * provided that this copyright notice appears in all copies. For
97.12 + * precise terms see the accompanying LICENSE file.
97.13 + *
97.14 + * This software is provided "AS IS" with no warranty of any kind,
97.15 + * express or implied, and with no claim as to its suitability for any
97.16 + * purpose.
97.17 + *
97.18 + */
97.19 +
97.20 +#ifndef LEMON_SMART_GRAPH_H
97.21 +#define LEMON_SMART_GRAPH_H
97.22 +
97.23 +///\ingroup graphs
97.24 +///\file
97.25 +///\brief SmartGraph and SymSmartGraph classes.
97.26 +
97.27 +#include <vector>
97.28 +
97.29 +#include <lemon/invalid.h>
97.30 +
97.31 +#include <lemon/bits/clearable_graph_extender.h>
97.32 +#include <lemon/bits/extendable_graph_extender.h>
97.33 +#include <lemon/bits/iterable_graph_extender.h>
97.34 +#include <lemon/bits/alteration_notifier.h>
97.35 +#include <lemon/bits/default_map.h>
97.36 +
97.37 +#include <lemon/bits/undir_graph_extender.h>
97.38 +
97.39 +#include <lemon/utility.h>
97.40 +
97.41 +namespace lemon {
97.42 +
97.43 + class SmartGraph;
97.44 + ///Base of SmartGraph
97.45 +
97.46 + ///Base of SmartGraph
97.47 + ///
97.48 + class SmartGraphBase {
97.49 +
97.50 + friend class SmatGraph;
97.51 +
97.52 + protected:
97.53 + struct NodeT
97.54 + {
97.55 + int first_in,first_out;
97.56 + NodeT() : first_in(-1), first_out(-1) {}
97.57 + };
97.58 + struct EdgeT
97.59 + {
97.60 + int target, source, next_in, next_out;
97.61 + //FIXME: is this necessary?
97.62 + EdgeT() : next_in(-1), next_out(-1) {}
97.63 + };
97.64 +
97.65 + std::vector<NodeT> nodes;
97.66 +
97.67 + std::vector<EdgeT> edges;
97.68 +
97.69 +
97.70 + public:
97.71 +
97.72 + typedef SmartGraphBase Graph;
97.73 +
97.74 + class Node;
97.75 + class Edge;
97.76 +
97.77 +
97.78 + public:
97.79 +
97.80 + SmartGraphBase() : nodes(), edges() { }
97.81 + SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
97.82 +
97.83 + typedef True NodeNumTag;
97.84 + typedef True EdgeNumTag;
97.85 +
97.86 + ///Number of nodes.
97.87 + int nodeNum() const { return nodes.size(); }
97.88 + ///Number of edges.
97.89 + int edgeNum() const { return edges.size(); }
97.90 +
97.91 + /// Maximum node ID.
97.92 +
97.93 + /// Maximum node ID.
97.94 + ///\sa id(Node)
97.95 + int maxId(Node = INVALID) const { return nodes.size()-1; }
97.96 + /// Maximum edge ID.
97.97 +
97.98 + /// Maximum edge ID.
97.99 + ///\sa id(Edge)
97.100 + int maxId(Edge = INVALID) const { return edges.size()-1; }
97.101 +
97.102 + Node source(Edge e) const { return edges[e.n].source; }
97.103 + Node target(Edge e) const { return edges[e.n].target; }
97.104 +
97.105 + /// Node ID.
97.106 +
97.107 + /// The ID of a valid Node is a nonnegative integer not greater than
97.108 + /// \ref maxNodeId(). The range of the ID's is not surely continuous
97.109 + /// and the greatest node ID can be actually less then \ref maxNodeId().
97.110 + ///
97.111 + /// The ID of the \ref INVALID node is -1.
97.112 + ///\return The ID of the node \c v.
97.113 + static int id(Node v) { return v.n; }
97.114 + /// Edge ID.
97.115 +
97.116 + /// The ID of a valid Edge is a nonnegative integer not greater than
97.117 + /// \ref maxEdgeId(). The range of the ID's is not surely continuous
97.118 + /// and the greatest edge ID can be actually less then \ref maxEdgeId().
97.119 + ///
97.120 + /// The ID of the \ref INVALID edge is -1.
97.121 + ///\return The ID of the edge \c e.
97.122 + static int id(Edge e) { return e.n; }
97.123 +
97.124 + static Node fromId(int id, Node) { return Node(id);}
97.125 +
97.126 + static Edge fromId(int id, Edge) { return Edge(id);}
97.127 +
97.128 + Node addNode() {
97.129 + Node n; n.n=nodes.size();
97.130 + nodes.push_back(NodeT()); //FIXME: Hmmm...
97.131 + return n;
97.132 + }
97.133 +
97.134 + Edge addEdge(Node u, Node v) {
97.135 + Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
97.136 + edges[e.n].source=u.n; edges[e.n].target=v.n;
97.137 + edges[e.n].next_out=nodes[u.n].first_out;
97.138 + edges[e.n].next_in=nodes[v.n].first_in;
97.139 + nodes[u.n].first_out=nodes[v.n].first_in=e.n;
97.140 +
97.141 + return e;
97.142 + }
97.143 +
97.144 + void clear() {
97.145 + edges.clear();
97.146 + nodes.clear();
97.147 + }
97.148 +
97.149 +
97.150 + class Node {
97.151 + friend class SmartGraphBase;
97.152 + friend class SmartGraph;
97.153 +
97.154 + protected:
97.155 + int n;
97.156 + ///\todo It should be removed (or at least define a setToId() instead).
97.157 + ///
97.158 + Node(int nn) {n=nn;}
97.159 + public:
97.160 + Node() {}
97.161 + Node (Invalid) { n=-1; }
97.162 + bool operator==(const Node i) const {return n==i.n;}
97.163 + bool operator!=(const Node i) const {return n!=i.n;}
97.164 + bool operator<(const Node i) const {return n<i.n;}
97.165 + };
97.166 +
97.167 +
97.168 + class Edge {
97.169 + friend class SmartGraphBase;
97.170 + friend class SmartGraph;
97.171 +
97.172 + protected:
97.173 + int n;
97.174 + ///\todo It should be removed (or at least define a setToId() instead).
97.175 + ///
97.176 + Edge(int nn) {n=nn;}
97.177 + public:
97.178 + Edge() { }
97.179 + Edge (Invalid) { n=-1; }
97.180 + bool operator==(const Edge i) const {return n==i.n;}
97.181 + bool operator!=(const Edge i) const {return n!=i.n;}
97.182 + bool operator<(const Edge i) const {return n<i.n;}
97.183 + };
97.184 +
97.185 + void first(Node& node) const {
97.186 + node.n = nodes.size() - 1;
97.187 + }
97.188 +
97.189 + static void next(Node& node) {
97.190 + --node.n;
97.191 + }
97.192 +
97.193 + void first(Edge& edge) const {
97.194 + edge.n = edges.size() - 1;
97.195 + }
97.196 +
97.197 + static void next(Edge& edge) {
97.198 + --edge.n;
97.199 + }
97.200 +
97.201 + void firstOut(Edge& edge, const Node& node) const {
97.202 + edge.n = nodes[node.n].first_out;
97.203 + }
97.204 +
97.205 + void nextOut(Edge& edge) const {
97.206 + edge.n = edges[edge.n].next_out;
97.207 + }
97.208 +
97.209 + void firstIn(Edge& edge, const Node& node) const {
97.210 + edge.n = nodes[node.n].first_in;
97.211 + }
97.212 +
97.213 + void nextIn(Edge& edge) const {
97.214 + edge.n = edges[edge.n].next_in;
97.215 + }
97.216 +
97.217 + Edge _findEdge(Node u,Node v, Edge prev = INVALID)
97.218 + {
97.219 + int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
97.220 + while(e!=-1 && edges[e].target!=v.n) e = edges[e].next_out;
97.221 + prev.n=e;
97.222 + return prev;
97.223 + }
97.224 +
97.225 + Node _split(Node n, bool connect = true)
97.226 + {
97.227 + Node b = addNode();
97.228 + nodes[b.n].first_out=nodes[n.n].first_out;
97.229 + nodes[n.n].first_out=-1;
97.230 + for(int i=nodes[b.n].first_out;i!=-1;i++) edges[i].source=b.n;
97.231 + if(connect) addEdge(n,b);
97.232 + return b;
97.233 + }
97.234 +
97.235 + };
97.236 +
97.237 + typedef AlterableGraphExtender<SmartGraphBase> AlterableSmartGraphBase;
97.238 + typedef IterableGraphExtender<AlterableSmartGraphBase> IterableSmartGraphBase;
97.239 + typedef DefaultMappableGraphExtender<IterableSmartGraphBase> MappableSmartGraphBase;
97.240 + typedef ExtendableGraphExtender<MappableSmartGraphBase> ExtendableSmartGraphBase;
97.241 + typedef ClearableGraphExtender<ExtendableSmartGraphBase> ClearableSmartGraphBase;
97.242 +
97.243 + /// \addtogroup graphs
97.244 + /// @{
97.245 +
97.246 + ///A smart graph class.
97.247 +
97.248 + ///This is a simple and fast graph implementation.
97.249 + ///It is also quite memory efficient, but at the price
97.250 + ///that <b> it does support only limited (only stack-like)
97.251 + ///node and edge deletions</b>.
97.252 + ///It conforms to
97.253 + ///the \ref concept::ExtendableGraph "ExtendableGraph" concept.
97.254 + ///\sa concept::ExtendableGraph.
97.255 + ///
97.256 + ///\author Alpar Juttner
97.257 + class SmartGraph : public ClearableSmartGraphBase {
97.258 + public:
97.259 + /// Finds an edge between two nodes.
97.260 +
97.261 + /// Finds an edge from node \c u to node \c v.
97.262 + ///
97.263 + /// If \c prev is \ref INVALID (this is the default value), then
97.264 + /// it finds the first edge from \c u to \c v. Otherwise it looks for
97.265 + /// the next edge from \c u to \c v after \c prev.
97.266 + /// \return The found edge or \ref INVALID if there is no such an edge.
97.267 + ///
97.268 + /// Thus you can iterate through each edge from \c u to \c v as it follows.
97.269 + /// \code
97.270 + /// for(Edge e=G.findEdge(u,v);e!=INVALID;e=G.findEdge(u,v,e)) {
97.271 + /// ...
97.272 + /// }
97.273 + /// \endcode
97.274 + /// \todo Possibly it should be a global function.
97.275 + Edge findEdge(Node u,Node v, Edge prev = INVALID)
97.276 + {
97.277 + return _findEdge(u,v,prev);
97.278 + }
97.279 +
97.280 + class SnapShot;
97.281 + friend class SnapShot;
97.282 +
97.283 + protected:
97.284 + void restoreSnapShot(const SnapShot &s)
97.285 + {
97.286 + while(s.edge_num>edges.size()) {
97.287 + Parent::getNotifier(Edge()).erase(Edge(edges.size()-1));
97.288 + nodes[edges.back().target].first_in=edges.back().next_in;
97.289 + nodes[edges.back().source].first_out=edges.back().next_out;
97.290 + edges.pop_back();
97.291 + }
97.292 + //nodes.resize(s.nodes_num);
97.293 + while(s.node_num>nodes.size()) {
97.294 + Parent::getNotifier(Node()).erase(Node(nodes.size()-1));
97.295 + nodes.pop_back();
97.296 + }
97.297 + }
97.298 +
97.299 + public:
97.300 +
97.301 + ///Split a node.
97.302 +
97.303 + ///This function splits a node. First a new node is added to the graph,
97.304 + ///then the source of each outgoing edge of \c n is moved to this new node.
97.305 + ///If \c connect is \c true (this is the default value), then a new edge
97.306 + ///from \c n to the newly created node is also added.
97.307 + ///\return The newly created node.
97.308 + ///
97.309 + ///\note The <tt>Edge</tt>s
97.310 + ///referencing a moved edge remain
97.311 + ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
97.312 + ///may be invalidated.
97.313 + ///\warning This functionality cannot be used together with the SnapShot
97.314 + ///feature.
97.315 + ///\todo It could be implemented in a bit faster way.
97.316 + Node split(Node n, bool connect = true)
97.317 + {
97.318 + return _split(n,connect);
97.319 + }
97.320 +
97.321 +
97.322 + ///Class to make a snapshot of the graph and to restrore to it later.
97.323 +
97.324 + ///Class to make a snapshot of the graph and to restrore to it later.
97.325 + ///
97.326 + ///The newly added nodes and edges can be removed using the
97.327 + ///restore() function.
97.328 + ///\note After you restore a state, you cannot restore
97.329 + ///a later state, in other word you cannot add again the edges deleted
97.330 + ///by restore() using another SnapShot instance.
97.331 + ///
97.332 + class SnapShot
97.333 + {
97.334 + SmartGraph *g;
97.335 + protected:
97.336 + friend class SmartGraph;
97.337 + unsigned int node_num;
97.338 + unsigned int edge_num;
97.339 + public:
97.340 + ///Default constructor.
97.341 +
97.342 + ///Default constructor.
97.343 + ///To actually make a snapshot you must call save().
97.344 + ///
97.345 + SnapShot() : g(0) {}
97.346 + ///Constructor that immediately makes a snapshot
97.347 +
97.348 + ///This constructor immediately makes a snapshot of the graph.
97.349 + ///\param _g The graph we make a snapshot of.
97.350 + SnapShot(SmartGraph &_g) :g(&_g) {
97.351 + node_num=g->nodes.size();
97.352 + edge_num=g->edges.size();
97.353 + }
97.354 +
97.355 + ///Make a snapshot.
97.356 +
97.357 + ///Make a snapshot of the graph.
97.358 + ///
97.359 + ///This function can be called more than once. In case of a repeated
97.360 + ///call, the previous snapshot gets lost.
97.361 + ///\param _g The graph we make the snapshot of.
97.362 + void save(SmartGraph &_g)
97.363 + {
97.364 + g=&_g;
97.365 + node_num=g->nodes.size();
97.366 + edge_num=g->edges.size();
97.367 + }
97.368 +
97.369 + ///Undo the changes until a snapshot.
97.370 +
97.371 + ///Undo the changes until a snapshot created by save().
97.372 + ///
97.373 + ///\param s an internal stucture given back by save()
97.374 + ///\note After you restored a state, you cannot restore
97.375 + ///a later state, in other word you cannot add again the edges deleted
97.376 + ///by restore().
97.377 + ///
97.378 + ///\todo This function might be called undo().
97.379 +
97.380 + void restore()
97.381 + {
97.382 + g->restoreSnapShot(*this);
97.383 + }
97.384 + };
97.385 + };
97.386 +
97.387 +
97.388 + /**************** Undirected List Graph ****************/
97.389 +
97.390 + typedef ClearableUndirGraphExtender<
97.391 + ExtendableUndirGraphExtender<
97.392 + MappableUndirGraphExtender<
97.393 + IterableUndirGraphExtender<
97.394 + AlterableUndirGraphExtender<
97.395 + UndirGraphExtender<SmartGraphBase> > > > > > UndirSmartGraphBase;
97.396 +
97.397 + ///A smart undirected graph class.
97.398 +
97.399 + ///This is a simple and fast undirected graph implementation.
97.400 + ///It is also quite memory efficient, but at the price
97.401 + ///that <b> it does support only limited (only stack-like)
97.402 + ///node and edge deletions</b>.
97.403 + ///Except from this it conforms to
97.404 + ///the \ref concept::UndirGraph "UndirGraph" concept.
97.405 + ///\sa concept::UndirGraph.
97.406 + ///
97.407 + ///\todo SnapShot hasn't been implemented yet.
97.408 + ///
97.409 + class UndirSmartGraph : public UndirSmartGraphBase {
97.410 + };
97.411 +
97.412 +
97.413 + /// @}
97.414 +} //namespace lemon
97.415 +
97.416 +
97.417 +#endif //LEMON_SMART_GRAPH_H
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/lemon/suurballe.h Mon May 23 04:48:14 2005 +0000
98.3 @@ -0,0 +1,209 @@
98.4 +/* -*- C++ -*-
98.5 + * lemon/suurballe.h - Part of LEMON, a generic C++ optimization library
98.6 + *
98.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
98.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
98.9 + *
98.10 + * Permission to use, modify and distribute this software is granted
98.11 + * provided that this copyright notice appears in all copies. For
98.12 + * precise terms see the accompanying LICENSE file.
98.13 + *
98.14 + * This software is provided "AS IS" with no warranty of any kind,
98.15 + * express or implied, and with no claim as to its suitability for any
98.16 + * purpose.
98.17 + *
98.18 + */
98.19 +
98.20 +#ifndef LEMON_SUURBALLE_H
98.21 +#define LEMON_SUURBALLE_H
98.22 +
98.23 +///\ingroup flowalgs
98.24 +///\file
98.25 +///\brief An algorithm for finding k paths of minimal total length.
98.26 +
98.27 +
98.28 +#include <lemon/maps.h>
98.29 +#include <vector>
98.30 +#include <lemon/min_cost_flow.h>
98.31 +
98.32 +namespace lemon {
98.33 +
98.34 +/// \addtogroup flowalgs
98.35 +/// @{
98.36 +
98.37 + ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes
98.38 + /// of minimal total length
98.39 + ///
98.40 + /// The class \ref lemon::Suurballe implements
98.41 + /// an algorithm for finding k edge-disjoint paths
98.42 + /// from a given source node to a given target node in an
98.43 + /// edge-weighted directed graph having minimal total weight (length).
98.44 + ///
98.45 + ///\warning Length values should be nonnegative.
98.46 + ///
98.47 + ///\param Graph The directed graph type the algorithm runs on.
98.48 + ///\param LengthMap The type of the length map (values should be nonnegative).
98.49 + ///
98.50 + ///\note It it questionable whether it is correct to call this method after
98.51 + ///%Suurballe for it is just a special case of Edmonds' and Karp's algorithm
98.52 + ///for finding minimum cost flows. In fact, this implementation just
98.53 + ///wraps the MinCostFlow algorithms. The paper of both %Suurballe and
98.54 + ///Edmonds-Karp published in 1972, therefore it is possibly right to
98.55 + ///state that they are
98.56 + ///independent results. Most frequently this special case is referred as
98.57 + ///%Suurballe method in the literature, especially in communication
98.58 + ///network context.
98.59 + ///\author Attila Bernath
98.60 + template <typename Graph, typename LengthMap>
98.61 + class Suurballe{
98.62 +
98.63 +
98.64 + typedef typename LengthMap::Value Length;
98.65 +
98.66 + typedef typename Graph::Node Node;
98.67 + typedef typename Graph::NodeIt NodeIt;
98.68 + typedef typename Graph::Edge Edge;
98.69 + typedef typename Graph::OutEdgeIt OutEdgeIt;
98.70 + typedef typename Graph::template EdgeMap<int> EdgeIntMap;
98.71 +
98.72 + typedef ConstMap<Edge,int> ConstMap;
98.73 +
98.74 + const Graph& G;
98.75 +
98.76 + Node s;
98.77 + Node t;
98.78 +
98.79 + //Auxiliary variables
98.80 + //This is the capacity map for the mincostflow problem
98.81 + ConstMap const1map;
98.82 + //This MinCostFlow instance will actually solve the problem
98.83 + MinCostFlow<Graph, LengthMap, ConstMap> min_cost_flow;
98.84 +
98.85 + //Container to store found paths
98.86 + std::vector< std::vector<Edge> > paths;
98.87 +
98.88 + public :
98.89 +
98.90 +
98.91 + /*! \brief The constructor of the class.
98.92 +
98.93 + \param _G The directed graph the algorithm runs on.
98.94 + \param _length The length (weight or cost) of the edges.
98.95 + \param _s Source node.
98.96 + \param _t Target node.
98.97 + */
98.98 + Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) :
98.99 + G(_G), s(_s), t(_t), const1map(1),
98.100 + min_cost_flow(_G, _length, const1map, _s, _t) { }
98.101 +
98.102 + ///Runs the algorithm.
98.103 +
98.104 + ///Runs the algorithm.
98.105 + ///Returns k if there are at least k edge-disjoint paths from s to t.
98.106 + ///Otherwise it returns the number of edge-disjoint paths found
98.107 + ///from s to t.
98.108 + ///
98.109 + ///\param k How many paths are we looking for?
98.110 + ///
98.111 + int run(int k) {
98.112 + int i = min_cost_flow.run(k);
98.113 +
98.114 + //Let's find the paths
98.115 + //We put the paths into stl vectors (as an inner representation).
98.116 + //In the meantime we lose the information stored in 'reversed'.
98.117 + //We suppose the lengths to be positive now.
98.118 +
98.119 + //We don't want to change the flow of min_cost_flow, so we make a copy
98.120 + //The name here suggests that the flow has only 0/1 values.
98.121 + EdgeIntMap reversed(G);
98.122 +
98.123 + for(typename Graph::EdgeIt e(G); e!=INVALID; ++e)
98.124 + reversed[e] = min_cost_flow.getFlow()[e];
98.125 +
98.126 + paths.clear();
98.127 + //total_length=0;
98.128 + paths.resize(k);
98.129 + for (int j=0; j<i; ++j){
98.130 + Node n=s;
98.131 +
98.132 + while (n!=t){
98.133 +
98.134 + OutEdgeIt e(G, n);
98.135 +
98.136 + while (!reversed[e]){
98.137 + ++e;
98.138 + }
98.139 + n = G.target(e);
98.140 + paths[j].push_back(e);
98.141 + //total_length += length[e];
98.142 + reversed[e] = 1-reversed[e];
98.143 + }
98.144 +
98.145 + }
98.146 + return i;
98.147 + }
98.148 +
98.149 +
98.150 + ///Returns the total length of the paths.
98.151 +
98.152 + ///This function gives back the total length of the found paths.
98.153 + Length totalLength(){
98.154 + return min_cost_flow.totalLength();
98.155 + }
98.156 +
98.157 + ///Returns the found flow.
98.158 +
98.159 + ///This function returns a const reference to the EdgeMap \c flow.
98.160 + const EdgeIntMap &getFlow() const { return min_cost_flow.flow;}
98.161 +
98.162 + /// Returns the optimal dual solution
98.163 +
98.164 + ///This function returns a const reference to the NodeMap
98.165 + ///\c potential (the dual solution).
98.166 + const EdgeIntMap &getPotential() const { return min_cost_flow.potential;}
98.167 +
98.168 + ///Checks whether the complementary slackness holds.
98.169 +
98.170 + ///This function checks, whether the given solution is optimal.
98.171 + ///Currently this function only checks optimality,
98.172 + ///doesn't bother with feasibility
98.173 + ///It is meant for testing purposes.
98.174 + bool checkComplementarySlackness(){
98.175 + return min_cost_flow.checkComplementarySlackness();
98.176 + }
98.177 +
98.178 + ///Read the found paths.
98.179 +
98.180 + ///This function gives back the \c j-th path in argument p.
98.181 + ///Assumes that \c run() has been run and nothing changed since then.
98.182 + /// \warning It is assumed that \c p is constructed to
98.183 + ///be a path of graph \c G.
98.184 + ///If \c j is not less than the result of previous \c run,
98.185 + ///then the result here will be an empty path (\c j can be 0 as well).
98.186 + ///
98.187 + ///\param Path The type of the path structure to put the result to (must meet lemon path concept).
98.188 + ///\param p The path to put the result to
98.189 + ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
98.190 + template<typename Path>
98.191 + void getPath(Path& p, size_t j){
98.192 +
98.193 + p.clear();
98.194 + if (j>paths.size()-1){
98.195 + return;
98.196 + }
98.197 + typename Path::Builder B(p);
98.198 + for(typename std::vector<Edge>::iterator i=paths[j].begin();
98.199 + i!=paths[j].end(); ++i ){
98.200 + B.pushBack(*i);
98.201 + }
98.202 +
98.203 + B.commit();
98.204 + }
98.205 +
98.206 + }; //class Suurballe
98.207 +
98.208 + ///@}
98.209 +
98.210 +} //namespace lemon
98.211 +
98.212 +#endif //LEMON_SUURBALLE_H
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/lemon/time_measure.h Mon May 23 04:48:14 2005 +0000
99.3 @@ -0,0 +1,255 @@
99.4 +/* -*- C++ -*-
99.5 + * lemon/time_measure.h - Part of LEMON, a generic C++ optimization library
99.6 + *
99.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
99.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
99.9 + *
99.10 + * Permission to use, modify and distribute this software is granted
99.11 + * provided that this copyright notice appears in all copies. For
99.12 + * precise terms see the accompanying LICENSE file.
99.13 + *
99.14 + * This software is provided "AS IS" with no warranty of any kind,
99.15 + * express or implied, and with no claim as to its suitability for any
99.16 + * purpose.
99.17 + *
99.18 + */
99.19 +
99.20 +#ifndef LEMON_TIME_MEASURE_H
99.21 +#define LEMON_TIME_MEASURE_H
99.22 +
99.23 +///\ingroup misc
99.24 +///\file
99.25 +///\brief Tools for measuring cpu usage
99.26 +
99.27 +#include <sys/time.h>
99.28 +#include <sys/times.h>
99.29 +#include <fstream>
99.30 +#include <iostream>
99.31 +#include <unistd.h>
99.32 +
99.33 +namespace lemon {
99.34 +
99.35 + /// \addtogroup misc
99.36 + /// @{
99.37 +
99.38 + /// A class to store (cpu)time instances.
99.39 +
99.40 + /// This class stores five time values.
99.41 + /// - a real time
99.42 + /// - a user cpu time
99.43 + /// - a system cpu time
99.44 + /// - a user cpu time of children
99.45 + /// - a system cpu time of children
99.46 + ///
99.47 + /// TimeStamp's can be added to or substracted from each other and
99.48 + /// they can be pushed to a stream.
99.49 + ///
99.50 + /// In most cases, perhaps \ref Timer class is what you want to use instead.
99.51 + ///
99.52 + ///\author Alpar Juttner
99.53 +
99.54 + class TimeStamp
99.55 + {
99.56 + tms ts;
99.57 + double real_time;
99.58 +
99.59 + public:
99.60 +
99.61 + tms &getTms() {return ts;}
99.62 + const tms &getTms() const {return ts;}
99.63 + ///Read the current time values of the process
99.64 + void stamp()
99.65 + {
99.66 + timeval tv;
99.67 + times(&ts);
99.68 + gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
99.69 + }
99.70 +
99.71 + /// Constructor initializing with zero
99.72 + TimeStamp()
99.73 + { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
99.74 + ///Constructor initializing with the current time values of the process
99.75 + TimeStamp(void *) { stamp();}
99.76 +
99.77 + ///\e
99.78 + TimeStamp &operator+=(const TimeStamp &b)
99.79 + {
99.80 + ts.tms_utime+=b.ts.tms_utime;
99.81 + ts.tms_stime+=b.ts.tms_stime;
99.82 + ts.tms_cutime+=b.ts.tms_cutime;
99.83 + ts.tms_cstime+=b.ts.tms_cstime;
99.84 + real_time+=b.real_time;
99.85 + return *this;
99.86 + }
99.87 + ///\e
99.88 + TimeStamp operator+(const TimeStamp &b) const
99.89 + {
99.90 + TimeStamp t(*this);
99.91 + return t+=b;
99.92 + }
99.93 + ///\e
99.94 + TimeStamp &operator-=(const TimeStamp &b)
99.95 + {
99.96 + ts.tms_utime-=b.ts.tms_utime;
99.97 + ts.tms_stime-=b.ts.tms_stime;
99.98 + ts.tms_cutime-=b.ts.tms_cutime;
99.99 + ts.tms_cstime-=b.ts.tms_cstime;
99.100 + real_time-=b.real_time;
99.101 + return *this;
99.102 + }
99.103 + ///\e
99.104 + TimeStamp operator-(const TimeStamp &b) const
99.105 + {
99.106 + TimeStamp t(*this);
99.107 + return t-=b;
99.108 + }
99.109 + ///The time ellapsed since the last call of stamp()
99.110 + TimeStamp ellapsed() const
99.111 + {
99.112 + TimeStamp t(NULL);
99.113 + return t-*this;
99.114 + }
99.115 +
99.116 + friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
99.117 +
99.118 + ///Gives back the user time of the process
99.119 + double getUserTime() const
99.120 + {
99.121 + return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
99.122 + }
99.123 + ///Gives back the system time of the process
99.124 + double getSystemTime() const
99.125 + {
99.126 + return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
99.127 + }
99.128 + ///Gives back the user time of the process' children
99.129 + double getCUserTime() const
99.130 + {
99.131 + return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
99.132 + }
99.133 + ///Gives back the user time of the process' children
99.134 + double getCSystemTime() const
99.135 + {
99.136 + return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
99.137 + }
99.138 + ///Gives back the real time of the process
99.139 + double getRealTime() const {return real_time;}
99.140 + };
99.141 +
99.142 + ///Class measuring the cpu time and real time usage of the process
99.143 +
99.144 + ///Class measuring the cpu time and real time usage of the process.
99.145 + ///It is quite easy-to-use, here is a short example.
99.146 + ///\code
99.147 + ///#include<lemon/time_measure.h>
99.148 + ///#include<iostream>
99.149 + ///
99.150 + ///int main()
99.151 + ///{
99.152 + ///
99.153 + /// ...
99.154 + ///
99.155 + /// Timer T;
99.156 + /// doSomething();
99.157 + /// std::cout << T << '\n';
99.158 + /// T.reset();
99.159 + /// doSomethingElse();
99.160 + /// std::cout << T << '\n';
99.161 + ///
99.162 + /// ...
99.163 + ///
99.164 + ///}
99.165 + ///\endcode
99.166 + ///
99.167 + ///\todo This shouldn't be Unix (Linux) specific.
99.168 + ///
99.169 + ///\author Alpar Juttner
99.170 + class Timer
99.171 + {
99.172 + TimeStamp start_time;
99.173 +
99.174 + void _reset() {start_time.stamp();}
99.175 +
99.176 + public:
99.177 + ///Constructor. It starts with zero time counters
99.178 + Timer() {_reset();}
99.179 +
99.180 + ///Computes the ellapsed time
99.181 +
99.182 + ///This conversion computes the ellapsed time
99.183 + ///since the construction of \c t or since
99.184 + ///the last \c t.reset().
99.185 + operator TimeStamp () const
99.186 + {
99.187 + TimeStamp t;
99.188 + t.stamp();
99.189 + return t-start_time;
99.190 + }
99.191 +
99.192 + ///Resets the time counters
99.193 +
99.194 + ///Resets the time counters
99.195 + ///
99.196 + void reset()
99.197 + {
99.198 + _reset();
99.199 + }
99.200 +
99.201 +
99.202 + ///Gives back the ellapsed user time of the process
99.203 + double getUserTime() const
99.204 + {
99.205 + return operator TimeStamp().getUserTime();
99.206 + }
99.207 + ///Gives back the ellapsed system time of the process
99.208 + double getSystemTime() const
99.209 + {
99.210 + return operator TimeStamp().getSystemTime();
99.211 + }
99.212 + ///Gives back the ellapsed user time of the process' children
99.213 + double getCUserTime() const
99.214 + {
99.215 + return operator TimeStamp().getCUserTime();
99.216 + }
99.217 + ///Gives back the ellapsed user time of the process' children
99.218 + double getCSystemTime() const
99.219 + {
99.220 + return operator TimeStamp().getCSystemTime();
99.221 + }
99.222 + ///Gives back the ellapsed real time of the process
99.223 + double getRealTime() const
99.224 + {
99.225 + return operator TimeStamp().getRealTime();
99.226 + }
99.227 +
99.228 + };
99.229 +
99.230 + ///Prints the time counters
99.231 +
99.232 + ///Prints the time counters in the following form:
99.233 + ///
99.234 + /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
99.235 + ///
99.236 + /// where the values are the
99.237 + /// \li \c u: user cpu time,
99.238 + /// \li \c s: system cpu time,
99.239 + /// \li \c cu: user cpu time of children,
99.240 + /// \li \c cs: system cpu time of children,
99.241 + /// \li \c real: real time.
99.242 + /// \relates TimeStamp
99.243 + inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
99.244 + {
99.245 + long cls = sysconf(_SC_CLK_TCK);
99.246 + os << "u: " << double(t.getTms().tms_utime)/cls <<
99.247 + "s, s: " << double(t.getTms().tms_stime)/cls <<
99.248 + "s, cu: " << double(t.getTms().tms_cutime)/cls <<
99.249 + "s, cs: " << double(t.getTms().tms_cstime)/cls <<
99.250 + "s, real: " << t.getRealTime() << "s";
99.251 + return os;
99.252 + }
99.253 +
99.254 + /// @}
99.255 +
99.256 +} //namespace lemon
99.257 +
99.258 +#endif //LEMON_TIME_MEASURE_H
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/lemon/unionfind.h Mon May 23 04:48:14 2005 +0000
100.3 @@ -0,0 +1,724 @@
100.4 +/* -*- C++ -*-
100.5 + * lemon/unionfind.h - Part of LEMON, a generic C++ optimization library
100.6 + *
100.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
100.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
100.9 + *
100.10 + * Permission to use, modify and distribute this software is granted
100.11 + * provided that this copyright notice appears in all copies. For
100.12 + * precise terms see the accompanying LICENSE file.
100.13 + *
100.14 + * This software is provided "AS IS" with no warranty of any kind,
100.15 + * express or implied, and with no claim as to its suitability for any
100.16 + * purpose.
100.17 + *
100.18 + */
100.19 +
100.20 +#ifndef LEMON_UNION_FIND_H
100.21 +#define LEMON_UNION_FIND_H
100.22 +
100.23 +//!\ingroup auxdat
100.24 +//!\file
100.25 +//!\brief Union-Find data structures.
100.26 +//!
100.27 +//!\bug unionfind_test.cc doesn't work with Intel compiler. It compiles but
100.28 +//!fails to run (Segmentation fault).
100.29 +
100.30 +
100.31 +#include <vector>
100.32 +#include <list>
100.33 +#include <utility>
100.34 +#include <algorithm>
100.35 +
100.36 +#include <lemon/invalid.h>
100.37 +
100.38 +namespace lemon {
100.39 +
100.40 + //! \addtogroup auxdat
100.41 + //! @{
100.42 +
100.43 + /**
100.44 + * \brief A \e Union-Find data structure implementation
100.45 + *
100.46 + * The class implements the \e Union-Find data structure.
100.47 + * The union operation uses rank heuristic, while
100.48 + * the find operation uses path compression.
100.49 + * This is a very simple but efficient implementation, providing
100.50 + * only four methods: join (union), find, insert and size.
100.51 + * For more features see the \ref UnionFindEnum class.
100.52 + *
100.53 + * It is primarily used in Kruskal algorithm for finding minimal
100.54 + * cost spanning tree in a graph.
100.55 + * \sa kruskal()
100.56 + *
100.57 + * \pre The elements are automatically added only if the map
100.58 + * given to the constructor was filled with -1's. Otherwise you
100.59 + * need to add all the elements by the \ref insert() method.
100.60 + * \bug It is not clear what the constructor parameter is used for.
100.61 + */
100.62 +
100.63 + template <typename T, typename TIntMap>
100.64 + class UnionFind {
100.65 +
100.66 + public:
100.67 + typedef T ElementType;
100.68 + typedef std::pair<int,int> PairType;
100.69 +
100.70 + private:
100.71 + std::vector<PairType> data;
100.72 + TIntMap& map;
100.73 +
100.74 + public:
100.75 + UnionFind(TIntMap& m) : map(m) {}
100.76 +
100.77 + /**
100.78 + * \brief Returns the index of the element's component.
100.79 + *
100.80 + * The method returns the index of the element's component.
100.81 + * This is an integer between zero and the number of inserted elements.
100.82 + */
100.83 +
100.84 + int find(T a)
100.85 + {
100.86 + int comp0 = map[a];
100.87 + if (comp0 < 0) {
100.88 + return insert(a);
100.89 + }
100.90 + int comp = comp0;
100.91 + int next;
100.92 + while ( (next = data[comp].first) != comp) {
100.93 + comp = next;
100.94 + }
100.95 + while ( (next = data[comp0].first) != comp) {
100.96 + data[comp0].first = comp;
100.97 + comp0 = next;
100.98 + }
100.99 +
100.100 + return comp;
100.101 + }
100.102 +
100.103 + /**
100.104 + * \brief Inserts a new element into the structure.
100.105 + *
100.106 + * This method inserts a new element into the data structure.
100.107 + *
100.108 + * It is not required to use this method:
100.109 + * if the map given to the constructor was filled
100.110 + * with -1's then it is called automatically
100.111 + * on the first \ref find or \ref join.
100.112 + *
100.113 + * The method returns the index of the new component.
100.114 + */
100.115 +
100.116 + int insert(T a)
100.117 + {
100.118 + int n = data.size();
100.119 + data.push_back(std::make_pair(n, 1));
100.120 + map.set(a,n);
100.121 + return n;
100.122 + }
100.123 +
100.124 + /**
100.125 + * \brief Joining the components of element \e a and element \e b.
100.126 + *
100.127 + * This is the \e union operation of the Union-Find structure.
100.128 + * Joins the component of element \e a and component of
100.129 + * element \e b. If \e a and \e b are in the same component then
100.130 + * it returns false otherwise it returns true.
100.131 + */
100.132 +
100.133 + bool join(T a, T b)
100.134 + {
100.135 + int ca = find(a);
100.136 + int cb = find(b);
100.137 +
100.138 + if ( ca == cb )
100.139 + return false;
100.140 +
100.141 + if ( data[ca].second > data[cb].second ) {
100.142 + data[cb].first = ca;
100.143 + data[ca].second += data[cb].second;
100.144 + }
100.145 + else {
100.146 + data[ca].first = cb;
100.147 + data[cb].second += data[ca].second;
100.148 + }
100.149 + return true;
100.150 + }
100.151 +
100.152 + /**
100.153 + * \brief Returns the size of the component of element \e a.
100.154 + *
100.155 + * Returns the size of the component of element \e a.
100.156 + */
100.157 +
100.158 + int size(T a)
100.159 + {
100.160 + int ca = find(a);
100.161 + return data[ca].second;
100.162 + }
100.163 +
100.164 + };
100.165 +
100.166 +
100.167 +
100.168 +
100.169 + /*******************************************************/
100.170 +
100.171 +
100.172 +#ifdef DEVELOPMENT_DOCS
100.173 +
100.174 + /**
100.175 + * \brief The auxiliary class for the \ref UnionFindEnum class.
100.176 + *
100.177 + * In the \ref UnionFindEnum class all components are represented as
100.178 + * a std::list.
100.179 + * Items of these lists are UnionFindEnumItem structures.
100.180 + *
100.181 + * The class has four fields:
100.182 + * - T me - the actual element
100.183 + * - IIter parent - the parent of the element in the union-find structure
100.184 + * - int size - the size of the component of the element.
100.185 + * Only valid if the element
100.186 + * is the leader of the component.
100.187 + * - CIter my_class - pointer into the list of components
100.188 + * pointing to the component of the element.
100.189 + * Only valid if the element is the leader of the component.
100.190 + */
100.191 +
100.192 +#endif
100.193 +
100.194 + template <typename T>
100.195 + struct UnionFindEnumItem {
100.196 +
100.197 + typedef std::list<UnionFindEnumItem> ItemList;
100.198 + typedef std::list<ItemList> ClassList;
100.199 + typedef typename ItemList::iterator IIter;
100.200 + typedef typename ClassList::iterator CIter;
100.201 +
100.202 + T me;
100.203 + IIter parent;
100.204 + int size;
100.205 + CIter my_class;
100.206 +
100.207 + UnionFindEnumItem() {}
100.208 + UnionFindEnumItem(const T &_me, CIter _my_class):
100.209 + me(_me), size(1), my_class(_my_class) {}
100.210 + };
100.211 +
100.212 +
100.213 + /**
100.214 + * \brief A \e Union-Find data structure implementation which
100.215 + * is able to enumerate the components.
100.216 + *
100.217 + * The class implements a \e Union-Find data structure
100.218 + * which is able to enumerate the components and the items in
100.219 + * a component. If you don't need this feature then perhaps it's
100.220 + * better to use the \ref UnionFind class which is more efficient.
100.221 + *
100.222 + * The union operation uses rank heuristic, while
100.223 + * the find operation uses path compression.
100.224 + *
100.225 + * \pre You
100.226 + * need to add all the elements by the \ref insert() method.
100.227 + */
100.228 +
100.229 +
100.230 + template <typename T, template <typename Item> class Map>
100.231 + class UnionFindEnum {
100.232 +
100.233 + typedef std::list<UnionFindEnumItem<T> > ItemList;
100.234 + typedef std::list<ItemList> ClassList;
100.235 + typedef typename ItemList::iterator IIter;
100.236 + typedef typename ItemList::const_iterator IcIter;
100.237 + typedef typename ClassList::iterator CIter;
100.238 + typedef typename ClassList::const_iterator CcIter;
100.239 +
100.240 + public:
100.241 + typedef T ElementType;
100.242 + typedef UnionFindEnumItem<T> ItemType;
100.243 + typedef Map< IIter > MapType;
100.244 +
100.245 + private:
100.246 + MapType& m;
100.247 + ClassList classes;
100.248 +
100.249 + IIter _find(IIter a) const {
100.250 + IIter comp = a;
100.251 + IIter next;
100.252 + while( (next = comp->parent) != comp ) {
100.253 + comp = next;
100.254 + }
100.255 +
100.256 + IIter comp1 = a;
100.257 + while( (next = comp1->parent) != comp ) {
100.258 + comp1->parent = comp->parent;
100.259 + comp1 = next;
100.260 + }
100.261 + return comp;
100.262 + }
100.263 +
100.264 + public:
100.265 + UnionFindEnum(MapType& _m) : m(_m) {}
100.266 +
100.267 +
100.268 + /**
100.269 + * \brief Inserts the given element into a new component.
100.270 + *
100.271 + * This method creates a new component consisting only of the
100.272 + * given element.
100.273 + */
100.274 +
100.275 + void insert(const T &a)
100.276 + {
100.277 +
100.278 +
100.279 + classes.push_back(ItemList());
100.280 + CIter aclass = classes.end();
100.281 + --aclass;
100.282 +
100.283 + ItemList &alist = *aclass;
100.284 + alist.push_back(ItemType(a, aclass));
100.285 + IIter ai = alist.begin();
100.286 +
100.287 + ai->parent = ai;
100.288 + m.set(a, ai);
100.289 +
100.290 + }
100.291 +
100.292 + /**
100.293 + * \brief Inserts the given element into the component of the others.
100.294 + *
100.295 + * This methods inserts the element \e a into the component of the
100.296 + * element \e comp.
100.297 + */
100.298 +
100.299 + void insert(const T &a, const T &comp) {
100.300 +
100.301 + IIter clit = _find(m[comp]);
100.302 + ItemList &c = *clit->my_class;
100.303 + c.push_back(ItemType(a,0));
100.304 + IIter ai = c.end();
100.305 + --ai;
100.306 + ai->parent = clit;
100.307 + m.set(a, ai);
100.308 + ++clit->size;
100.309 + }
100.310 +
100.311 +
100.312 + /**
100.313 + * \brief Finds the leader of the component of the given element.
100.314 + *
100.315 + * The method returns the leader of the component of the given element.
100.316 + */
100.317 +
100.318 + T find(const T &a) const {
100.319 + return _find(m[a])->me;
100.320 + }
100.321 +
100.322 +
100.323 + /**
100.324 + * \brief Joining the component of element \e a and element \e b.
100.325 + *
100.326 + * This is the \e union operation of the Union-Find structure.
100.327 + * Joins the component of element \e a and component of
100.328 + * element \e b. If \e a and \e b are in the same component then
100.329 + * returns false else returns true.
100.330 + */
100.331 +
100.332 + bool join(T a, T b) {
100.333 +
100.334 + IIter ca = _find(m[a]);
100.335 + IIter cb = _find(m[b]);
100.336 +
100.337 + if ( ca == cb ) {
100.338 + return false;
100.339 + }
100.340 +
100.341 + if ( ca->size > cb->size ) {
100.342 +
100.343 + cb->parent = ca->parent;
100.344 + ca->size += cb->size;
100.345 +
100.346 + ItemList &alist = *ca->my_class;
100.347 + alist.splice(alist.end(),*cb->my_class);
100.348 +
100.349 + classes.erase(cb->my_class);
100.350 + cb->my_class = 0;
100.351 + }
100.352 + else {
100.353 +
100.354 + ca->parent = cb->parent;
100.355 + cb->size += ca->size;
100.356 +
100.357 + ItemList &blist = *cb->my_class;
100.358 + blist.splice(blist.end(),*ca->my_class);
100.359 +
100.360 + classes.erase(ca->my_class);
100.361 + ca->my_class = 0;
100.362 + }
100.363 +
100.364 + return true;
100.365 + }
100.366 +
100.367 +
100.368 + /**
100.369 + * \brief Returns the size of the component of element \e a.
100.370 + *
100.371 + * Returns the size of the component of element \e a.
100.372 + */
100.373 +
100.374 + int size(const T &a) const {
100.375 + return _find(m[a])->size;
100.376 + }
100.377 +
100.378 +
100.379 + /**
100.380 + * \brief Splits up the component of the element.
100.381 + *
100.382 + * Splitting the component of the element into sigleton
100.383 + * components (component of size one).
100.384 + */
100.385 +
100.386 + void split(const T &a) {
100.387 +
100.388 + IIter ca = _find(m[a]);
100.389 +
100.390 + if ( ca->size == 1 )
100.391 + return;
100.392 +
100.393 + CIter aclass = ca->my_class;
100.394 +
100.395 + for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
100.396 + classes.push_back(ItemList());
100.397 + CIter nl = --classes.end();
100.398 + nl->splice(nl->end(), *aclass, curr);
100.399 +
100.400 + curr->size=1;
100.401 + curr->parent=curr;
100.402 + curr->my_class = nl;
100.403 + }
100.404 +
100.405 + ca->size=1;
100.406 + return;
100.407 + }
100.408 +
100.409 +
100.410 + /**
100.411 + * \brief Sets the given element to the leader element of its component.
100.412 + *
100.413 + * Sets the given element to the leader element of its component.
100.414 + */
100.415 +
100.416 + void makeRep(const T &a) {
100.417 +
100.418 + IIter ia = m[a];
100.419 + IIter la = _find(ia);
100.420 + if (la == ia) return;
100.421 +
100.422 + ia->my_class = la->my_class;
100.423 + la->my_class = 0;
100.424 +
100.425 + ia->size = la->size;
100.426 +
100.427 + CIter l = ia->my_class;
100.428 + l->splice(l->begin(),*l,ia);
100.429 +
100.430 + ia->parent = ia;
100.431 + la->parent = ia;
100.432 + }
100.433 +
100.434 + /**
100.435 + * \brief Moves the given element to an other component.
100.436 + *
100.437 + * This method moves the element \e a from its component
100.438 + * to the component of \e comp.
100.439 + * If \e a and \e comp are in the same component then
100.440 + * it returns false otherwise it returns true.
100.441 + */
100.442 +
100.443 + bool move(const T &a, const T &comp) {
100.444 +
100.445 + IIter ai = m[a];
100.446 + IIter lai = _find(ai);
100.447 + IIter clit = _find(m[comp]);
100.448 +
100.449 + if (lai == clit)
100.450 + return false;
100.451 +
100.452 + ItemList &cl = *clit->my_class,
100.453 + &al = *lai->my_class;
100.454 +
100.455 + bool is_leader = (lai == ai);
100.456 + bool singleton = false;
100.457 +
100.458 + if (is_leader) {
100.459 + ++lai;
100.460 + }
100.461 +
100.462 + cl.splice(cl.end(), al, ai);
100.463 +
100.464 + if (is_leader) {
100.465 + if (ai->size == 1) {
100.466 + classes.erase(ai->my_class);
100.467 + singleton = true;
100.468 + }
100.469 + else {
100.470 + lai->size = ai->size;
100.471 + lai->my_class = ai->my_class;
100.472 + }
100.473 + }
100.474 + if (!singleton) {
100.475 + for (IIter i = lai; i != al.end(); ++i)
100.476 + i->parent = lai;
100.477 + --lai->size;
100.478 + }
100.479 +
100.480 + ai->parent = clit;
100.481 + ai->my_class = 0;
100.482 + ++clit->size;
100.483 +
100.484 + return true;
100.485 + }
100.486 +
100.487 +
100.488 + /**
100.489 + * \brief Removes the given element from the structure.
100.490 + *
100.491 + * Removes the given element from the structure.
100.492 + *
100.493 + * Removes the element from its component and if the component becomes
100.494 + * empty then removes that component from the component list.
100.495 + */
100.496 + void erase(const T &a) {
100.497 +
100.498 + IIter ma = m[a];
100.499 + if (ma == 0) return;
100.500 +
100.501 + IIter la = _find(ma);
100.502 + if (la == ma) {
100.503 + if (ma -> size == 1){
100.504 + classes.erase(ma->my_class);
100.505 + m.set(a,0);
100.506 + return;
100.507 + }
100.508 + ++la;
100.509 + la->size = ma->size;
100.510 + la->my_class = ma->my_class;
100.511 + }
100.512 +
100.513 + for (IIter i = la; i != la->my_class->end(); ++i) {
100.514 + i->parent = la;
100.515 + }
100.516 +
100.517 + la->size--;
100.518 + la->my_class->erase(ma);
100.519 + m.set(a,0);
100.520 + }
100.521 +
100.522 + /**
100.523 + * \brief Removes the component of the given element from the structure.
100.524 + *
100.525 + * Removes the component of the given element from the structure.
100.526 + */
100.527 +
100.528 + void eraseClass(const T &a) {
100.529 + IIter ma = m[a];
100.530 + if (ma == 0) return;
100.531 +# ifdef DEBUG
100.532 + CIter c = _find(ma)->my_class;
100.533 + for (IIter i=c->begin(); i!=c->end(); ++i)
100.534 + m.set(i->me, 0);
100.535 +# endif
100.536 + classes.erase(_find(ma)->my_class);
100.537 + }
100.538 +
100.539 +
100.540 + class ClassIt {
100.541 + friend class UnionFindEnum;
100.542 +
100.543 + CcIter i;
100.544 + public:
100.545 + ClassIt(Invalid): i(0) {}
100.546 + ClassIt() {}
100.547 +
100.548 + operator const T& () const {
100.549 + ItemList const &ll = *i;
100.550 + return (ll.begin())->me; }
100.551 + bool operator == (ClassIt it) const {
100.552 + return (i == it.i);
100.553 + }
100.554 + bool operator != (ClassIt it) const {
100.555 + return (i != it.i);
100.556 + }
100.557 + bool operator < (ClassIt it) const {
100.558 + return (i < it.i);
100.559 + }
100.560 +
100.561 + bool valid() const { return i != 0; }
100.562 + private:
100.563 + void first(const ClassList &l) { i = l.begin(); validate(l); }
100.564 + void next(const ClassList &l) {
100.565 + ++i;
100.566 + validate(l);
100.567 + }
100.568 + void validate(const ClassList &l) {
100.569 + if ( i == l.end() )
100.570 + i = 0;
100.571 + }
100.572 + };
100.573 +
100.574 + /**
100.575 + * \brief Sets the iterator to point to the first component.
100.576 + *
100.577 + * Sets the iterator to point to the first component.
100.578 + *
100.579 + * With the \ref first, \ref valid and \ref next methods you can
100.580 + * iterate through the components. For example:
100.581 + * \code
100.582 + * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
100.583 + * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
100.584 + * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
100.585 + * for (U.first(iter); U.valid(iter); U.next(iter)) {
100.586 + * // iter is convertible to Graph::Node
100.587 + * cout << iter << endl;
100.588 + * }
100.589 + * \endcode
100.590 + */
100.591 +
100.592 + ClassIt& first(ClassIt& it) const {
100.593 + it.first(classes);
100.594 + return it;
100.595 + }
100.596 +
100.597 + /**
100.598 + * \brief Returns whether the iterator is valid.
100.599 + *
100.600 + * Returns whether the iterator is valid.
100.601 + *
100.602 + * With the \ref first, \ref valid and \ref next methods you can
100.603 + * iterate through the components. See the example here: \ref first.
100.604 + */
100.605 +
100.606 + bool valid(ClassIt const &it) const {
100.607 + return it.valid();
100.608 + }
100.609 +
100.610 + /**
100.611 + * \brief Steps the iterator to the next component.
100.612 + *
100.613 + * Steps the iterator to the next component.
100.614 + *
100.615 + * With the \ref first, \ref valid and \ref next methods you can
100.616 + * iterate through the components. See the example here: \ref first.
100.617 + */
100.618 +
100.619 + ClassIt& next(ClassIt& it) const {
100.620 + it.next(classes);
100.621 + return it;
100.622 + }
100.623 +
100.624 +
100.625 + class ItemIt {
100.626 + friend class UnionFindEnum;
100.627 +
100.628 + IcIter i;
100.629 + const ItemList *l;
100.630 + public:
100.631 + ItemIt(Invalid): i(0) {}
100.632 + ItemIt() {}
100.633 +
100.634 + operator const T& () const { return i->me; }
100.635 + bool operator == (ItemIt it) const {
100.636 + return (i == it.i);
100.637 + }
100.638 + bool operator != (ItemIt it) const {
100.639 + return (i != it.i);
100.640 + }
100.641 + bool operator < (ItemIt it) const {
100.642 + return (i < it.i);
100.643 + }
100.644 +
100.645 + bool valid() const { return i != 0; }
100.646 + private:
100.647 + void first(const ItemList &il) { l=&il; i = l->begin(); validate(); }
100.648 + void next() {
100.649 + ++i;
100.650 + validate();
100.651 + }
100.652 + void validate() {
100.653 + if ( i == l->end() )
100.654 + i = 0;
100.655 + }
100.656 + };
100.657 +
100.658 +
100.659 +
100.660 + /**
100.661 + * \brief Sets the iterator to point to the first element of the component.
100.662 + *
100.663 + * \anchor first2
100.664 + * Sets the iterator to point to the first element of the component.
100.665 + *
100.666 + * With the \ref first2 "first", \ref valid2 "valid"
100.667 + * and \ref next2 "next" methods you can
100.668 + * iterate through the elements of a component. For example
100.669 + * (iterating through the component of the node \e node):
100.670 + * \code
100.671 + * Graph::Node node = ...;
100.672 + * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
100.673 + * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
100.674 + * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
100.675 + * for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
100.676 + * // iiter is convertible to Graph::Node
100.677 + * cout << iiter << endl;
100.678 + * }
100.679 + * \endcode
100.680 + */
100.681 +
100.682 + ItemIt& first(ItemIt& it, const T& a) const {
100.683 + it.first( * _find(m[a])->my_class );
100.684 + return it;
100.685 + }
100.686 +
100.687 + /**
100.688 + * \brief Returns whether the iterator is valid.
100.689 + *
100.690 + * \anchor valid2
100.691 + * Returns whether the iterator is valid.
100.692 + *
100.693 + * With the \ref first2 "first", \ref valid2 "valid"
100.694 + * and \ref next2 "next" methods you can
100.695 + * iterate through the elements of a component.
100.696 + * See the example here: \ref first2 "first".
100.697 + */
100.698 +
100.699 + bool valid(ItemIt const &it) const {
100.700 + return it.valid();
100.701 + }
100.702 +
100.703 + /**
100.704 + * \brief Steps the iterator to the next component.
100.705 + *
100.706 + * \anchor next2
100.707 + * Steps the iterator to the next component.
100.708 + *
100.709 + * With the \ref first2 "first", \ref valid2 "valid"
100.710 + * and \ref next2 "next" methods you can
100.711 + * iterate through the elements of a component.
100.712 + * See the example here: \ref first2 "first".
100.713 + */
100.714 +
100.715 + ItemIt& next(ItemIt& it) const {
100.716 + it.next();
100.717 + return it;
100.718 + }
100.719 +
100.720 + };
100.721 +
100.722 +
100.723 + //! @}
100.724 +
100.725 +} //namespace lemon
100.726 +
100.727 +#endif //LEMON_UNION_FIND_H
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/lemon/utility.h Mon May 23 04:48:14 2005 +0000
101.3 @@ -0,0 +1,152 @@
101.4 +/* -*- C++ -*-
101.5 + * lemon/utility.h - Part of LEMON, a generic C++ optimization library
101.6 + *
101.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
101.8 + * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
101.9 + * EGRES).
101.10 + *
101.11 + * Permission to use, modify and distribute this software is granted
101.12 + * provided that this copyright notice appears in all copies. For
101.13 + * precise terms see the accompanying LICENSE file.
101.14 + *
101.15 + * This software is provided "AS IS" with no warranty of any kind,
101.16 + * express or implied, and with no claim as to its suitability for any
101.17 + * purpose.
101.18 + *
101.19 + * This file contains a modified version of the enable_if library from BOOST.
101.20 + * See the appropriate copyright notice below.
101.21 + */
101.22 +
101.23 +// Boost enable_if library
101.24 +
101.25 +// Copyright 2003 © The Trustees of Indiana University.
101.26 +
101.27 +// Use, modification, and distribution is subject to the Boost Software
101.28 +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
101.29 +// http://www.boost.org/LICENSE_1_0.txt)
101.30 +
101.31 +// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
101.32 +// Jeremiah Willcock (jewillco at osl.iu.edu)
101.33 +// Andrew Lumsdaine (lums at osl.iu.edu)
101.34 +
101.35 +
101.36 +#ifndef LEMON_UTILITY_H
101.37 +#define LEMON_UTILITY_H
101.38 +
101.39 +namespace lemon
101.40 +{
101.41 +
101.42 + /// Basic type for defining "tags". A "YES" condition for enable_if.
101.43 +
101.44 + /// \todo This should go to a separate "basic_types.h" (or something)
101.45 + /// file.
101.46 + struct True {
101.47 + static const bool value = true;
101.48 + };
101.49 +
101.50 + /// Basic type for defining "tags". A "NO" condition for enable_if.
101.51 + struct False {
101.52 + static const bool value = false;
101.53 + };
101.54 +
101.55 + template <typename T>
101.56 + struct Wrap {
101.57 + const T &value;
101.58 + Wrap(const T &t) : value(t) {}
101.59 + };
101.60 +
101.61 + /**************** dummy class to avoid ambiguity ****************/
101.62 +
101.63 + template<int T> struct dummy { dummy(int) {} };
101.64 +
101.65 + /**************** enable_if from BOOST ****************/
101.66 +
101.67 + template <bool B, class T = void>
101.68 + struct enable_if_c {
101.69 + typedef T type;
101.70 + };
101.71 +
101.72 + template <class T>
101.73 + struct enable_if_c<false, T> {};
101.74 +
101.75 + template <class Cond, class T = void>
101.76 + struct enable_if : public enable_if_c<Cond::value, T> {};
101.77 +
101.78 + template <bool B, class T>
101.79 + struct lazy_enable_if_c {
101.80 + typedef typename T::type type;
101.81 + };
101.82 +
101.83 + template <class T>
101.84 + struct lazy_enable_if_c<false, T> {};
101.85 +
101.86 + template <class Cond, class T>
101.87 + struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
101.88 +
101.89 +
101.90 + template <bool B, class T = void>
101.91 + struct disable_if_c {
101.92 + typedef T type;
101.93 + };
101.94 +
101.95 + template <class T>
101.96 + struct disable_if_c<true, T> {};
101.97 +
101.98 + template <class Cond, class T = void>
101.99 + struct disable_if : public disable_if_c<Cond::value, T> {};
101.100 +
101.101 + template <bool B, class T>
101.102 + struct lazy_disable_if_c {
101.103 + typedef typename T::type type;
101.104 + };
101.105 +
101.106 + template <class T>
101.107 + struct lazy_disable_if_c<true, T> {};
101.108 +
101.109 + template <class Cond, class T>
101.110 + struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
101.111 +
101.112 + // smart referencing
101.113 +
101.114 + template <typename _Type, typename Enable = void>
101.115 + struct SmartReference {
101.116 + typedef _Type& Type;
101.117 + };
101.118 +
101.119 + template <typename _Type>
101.120 + struct SmartReference<
101.121 + _Type,
101.122 + typename enable_if<typename _Type::NeedCopy, void>::type
101.123 + > {
101.124 + typedef _Type Type;
101.125 + };
101.126 +
101.127 + template <typename _Type, typename Enable = void>
101.128 + struct SmartConstReference {
101.129 + typedef const _Type& Type;
101.130 + };
101.131 +
101.132 + template <typename _Type>
101.133 + struct SmartConstReference<
101.134 + _Type,
101.135 + typename enable_if<typename _Type::NeedCopy, void>::type
101.136 + > {
101.137 + typedef const _Type Type;
101.138 + };
101.139 +
101.140 + template <typename _Type, typename Enable = void>
101.141 + struct SmartParameter {
101.142 + typedef _Type& Type;
101.143 + };
101.144 +
101.145 + template <typename _Type>
101.146 + struct SmartParameter<
101.147 + _Type,
101.148 + typename enable_if<typename _Type::NeedCopy, void>::type
101.149 + > {
101.150 + typedef const _Type& Type;
101.151 + };
101.152 +
101.153 +} // namespace lemon
101.154 +
101.155 +#endif
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/lemon/xy.h Mon May 23 04:48:14 2005 +0000
102.3 @@ -0,0 +1,518 @@
102.4 +/* -*- C++ -*-
102.5 + * lemon/xy.h - Part of LEMON, a generic C++ optimization library
102.6 + *
102.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
102.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
102.9 + *
102.10 + * Permission to use, modify and distribute this software is granted
102.11 + * provided that this copyright notice appears in all copies. For
102.12 + * precise terms see the accompanying LICENSE file.
102.13 + *
102.14 + * This software is provided "AS IS" with no warranty of any kind,
102.15 + * express or implied, and with no claim as to its suitability for any
102.16 + * purpose.
102.17 + *
102.18 + */
102.19 +
102.20 +#ifndef LEMON_XY_H
102.21 +#define LEMON_XY_H
102.22 +
102.23 +#include <iostream>
102.24 +#include <lemon/utility.h>
102.25 +
102.26 +///\ingroup misc
102.27 +///\file
102.28 +///\brief A simple two dimensional vector and a bounding box implementation
102.29 +///
102.30 +/// The class \ref lemon::xy "xy" implements
102.31 +///a two dimensional vector with the usual
102.32 +/// operations.
102.33 +///
102.34 +/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
102.35 +/// the rectangular bounding box of a set of \ref lemon::xy "xy"'s.
102.36 +///
102.37 +///\author Attila Bernath
102.38 +
102.39 +
102.40 +namespace lemon {
102.41 +
102.42 + /// \addtogroup misc
102.43 + /// @{
102.44 +
102.45 + /// A simple two dimensional vector (plainvector) implementation
102.46 +
102.47 + /// A simple two dimensional vector (plainvector) implementation
102.48 + ///with the usual vector
102.49 + /// operators.
102.50 + ///
102.51 + ///\author Attila Bernath
102.52 + template<typename T>
102.53 + class xy {
102.54 +
102.55 + public:
102.56 +
102.57 + typedef T Value;
102.58 +
102.59 + T x,y;
102.60 +
102.61 + ///Default constructor
102.62 + xy() {}
102.63 +
102.64 + ///Constructing the instance from coordinates
102.65 + xy(T a, T b) : x(a), y(b) { }
102.66 +
102.67 +
102.68 + ///Conversion constructor
102.69 + template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
102.70 +
102.71 + ///Gives back the square of the norm of the vector
102.72 + T normSquare() const {
102.73 + return x*x+y*y;
102.74 + }
102.75 +
102.76 + ///Increments the left hand side by u
102.77 + xy<T>& operator +=(const xy<T>& u) {
102.78 + x += u.x;
102.79 + y += u.y;
102.80 + return *this;
102.81 + }
102.82 +
102.83 + ///Decrements the left hand side by u
102.84 + xy<T>& operator -=(const xy<T>& u) {
102.85 + x -= u.x;
102.86 + y -= u.y;
102.87 + return *this;
102.88 + }
102.89 +
102.90 + ///Multiplying the left hand side with a scalar
102.91 + xy<T>& operator *=(const T &u) {
102.92 + x *= u;
102.93 + y *= u;
102.94 + return *this;
102.95 + }
102.96 +
102.97 + ///Dividing the left hand side by a scalar
102.98 + xy<T>& operator /=(const T &u) {
102.99 + x /= u;
102.100 + y /= u;
102.101 + return *this;
102.102 + }
102.103 +
102.104 + ///Returns the scalar product of two vectors
102.105 + T operator *(const xy<T>& u) const {
102.106 + return x*u.x+y*u.y;
102.107 + }
102.108 +
102.109 + ///Returns the sum of two vectors
102.110 + xy<T> operator+(const xy<T> &u) const {
102.111 + xy<T> b=*this;
102.112 + return b+=u;
102.113 + }
102.114 +
102.115 + ///Returns the neg of the vectors
102.116 + xy<T> operator-() const {
102.117 + xy<T> b=*this;
102.118 + b.x=-b.x; b.y=-b.y;
102.119 + return b;
102.120 + }
102.121 +
102.122 + ///Returns the difference of two vectors
102.123 + xy<T> operator-(const xy<T> &u) const {
102.124 + xy<T> b=*this;
102.125 + return b-=u;
102.126 + }
102.127 +
102.128 + ///Returns a vector multiplied by a scalar
102.129 + xy<T> operator*(const T &u) const {
102.130 + xy<T> b=*this;
102.131 + return b*=u;
102.132 + }
102.133 +
102.134 + ///Returns a vector divided by a scalar
102.135 + xy<T> operator/(const T &u) const {
102.136 + xy<T> b=*this;
102.137 + return b/=u;
102.138 + }
102.139 +
102.140 + ///Testing equality
102.141 + bool operator==(const xy<T> &u) const {
102.142 + return (x==u.x) && (y==u.y);
102.143 + }
102.144 +
102.145 + ///Testing inequality
102.146 + bool operator!=(xy u) const {
102.147 + return (x!=u.x) || (y!=u.y);
102.148 + }
102.149 +
102.150 + };
102.151 +
102.152 + ///Returns a vector multiplied by a scalar
102.153 +
102.154 + ///Returns a vector multiplied by a scalar
102.155 + ///\relates xy
102.156 + template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
102.157 + return x*u;
102.158 + }
102.159 +
102.160 + ///Read a plainvector from a stream
102.161 +
102.162 + ///Read a plainvector from a stream
102.163 + ///\relates xy
102.164 + ///
102.165 + template<typename T>
102.166 + inline std::istream& operator>>(std::istream &is, xy<T> &z) {
102.167 + char c;
102.168 + if (is >> c) {
102.169 + if (c != '(') is.putback(c);
102.170 + } else {
102.171 + is.clear();
102.172 + }
102.173 + if (!(is >> z.x)) return is;
102.174 + if (is >> c) {
102.175 + if (c != ',') is.putback(c);
102.176 + } else {
102.177 + is.clear();
102.178 + }
102.179 + if (!(is >> z.y)) return is;
102.180 + if (is >> c) {
102.181 + if (c != ')') is.putback(c);
102.182 + } else {
102.183 + is.clear();
102.184 + }
102.185 + return is;
102.186 + }
102.187 +
102.188 + ///Write a plainvector to a stream
102.189 +
102.190 + ///Write a plainvector to a stream
102.191 + ///\relates xy
102.192 + ///
102.193 + template<typename T>
102.194 + inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
102.195 + {
102.196 + os << "(" << z.x << ", " << z.y << ")";
102.197 + return os;
102.198 + }
102.199 +
102.200 + ///Rotate by 90 degrees
102.201 +
102.202 + ///Returns its parameter rotated by 90 degrees in positive direction.
102.203 + ///\relates xy
102.204 + ///
102.205 + template<typename T>
102.206 + inline xy<T> rot90(const xy<T> &z)
102.207 + {
102.208 + return xy<T>(-z.y,z.x);
102.209 + }
102.210 +
102.211 + ///Rotate by 270 degrees
102.212 +
102.213 + ///Returns its parameter rotated by 90 degrees in negative direction.
102.214 + ///\relates xy
102.215 + ///
102.216 + template<typename T>
102.217 + inline xy<T> rot270(const xy<T> &z)
102.218 + {
102.219 + return xy<T>(z.y,-z.x);
102.220 + }
102.221 +
102.222 +
102.223 +
102.224 + /// A class to calculate or store the bounding box of plainvectors.
102.225 +
102.226 + /// A class to calculate or store the bounding box of plainvectors.
102.227 + ///
102.228 + ///\author Attila Bernath
102.229 + template<typename T>
102.230 + class BoundingBox {
102.231 + xy<T> bottom_left, top_right;
102.232 + bool _empty;
102.233 + public:
102.234 +
102.235 + ///Default constructor: creates an empty bounding box
102.236 + BoundingBox() { _empty = true; }
102.237 +
102.238 + ///Constructing the instance from one point
102.239 + BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
102.240 +
102.241 + ///Were any points added?
102.242 + bool empty() const {
102.243 + return _empty;
102.244 + }
102.245 +
102.246 + ///Makes the BoundingBox empty
102.247 + void clear() {
102.248 + _empty=1;
102.249 + }
102.250 +
102.251 + ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined)
102.252 + xy<T> bottomLeft() const {
102.253 + return bottom_left;
102.254 + }
102.255 +
102.256 + ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined)
102.257 + xy<T> topRight() const {
102.258 + return top_right;
102.259 + }
102.260 +
102.261 + ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined)
102.262 + xy<T> bottomRight() const {
102.263 + return xy<T>(top_right.x,bottom_left.y);
102.264 + }
102.265 +
102.266 + ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined)
102.267 + xy<T> topLeft() const {
102.268 + return xy<T>(bottom_left.x,top_right.y);
102.269 + }
102.270 +
102.271 + ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined)
102.272 + T bottom() const {
102.273 + return bottom_left.y;
102.274 + }
102.275 +
102.276 + ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined)
102.277 + T top() const {
102.278 + return top_right.y;
102.279 + }
102.280 +
102.281 + ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined)
102.282 + T left() const {
102.283 + return bottom_left.x;
102.284 + }
102.285 +
102.286 + ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined)
102.287 + T right() const {
102.288 + return top_right.x;
102.289 + }
102.290 +
102.291 + ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined)
102.292 + T height() const {
102.293 + return top_right.y-bottom_left.y;
102.294 + }
102.295 +
102.296 + ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined)
102.297 + T width() const {
102.298 + return top_right.x-bottom_left.x;
102.299 + }
102.300 +
102.301 + ///Checks whether a point is inside a bounding box
102.302 + bool inside(const xy<T>& u){
102.303 + if (_empty)
102.304 + return false;
102.305 + else{
102.306 + return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
102.307 + (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
102.308 + }
102.309 + }
102.310 +
102.311 + ///Increments a bounding box with a point
102.312 + BoundingBox& operator +=(const xy<T>& u){
102.313 + if (_empty){
102.314 + bottom_left=top_right=u;
102.315 + _empty = false;
102.316 + }
102.317 + else{
102.318 + if (bottom_left.x > u.x) bottom_left.x = u.x;
102.319 + if (bottom_left.y > u.y) bottom_left.y = u.y;
102.320 + if (top_right.x < u.x) top_right.x = u.x;
102.321 + if (top_right.y < u.y) top_right.y = u.y;
102.322 + }
102.323 + return *this;
102.324 + }
102.325 +
102.326 + ///Sums a bounding box and a point
102.327 + BoundingBox operator +(const xy<T>& u){
102.328 + BoundingBox b = *this;
102.329 + return b += u;
102.330 + }
102.331 +
102.332 + ///Increments a bounding box with an other bounding box
102.333 + BoundingBox& operator +=(const BoundingBox &u){
102.334 + if ( !u.empty() ){
102.335 + *this += u.bottomLeft();
102.336 + *this += u.topRight();
102.337 + }
102.338 + return *this;
102.339 + }
102.340 +
102.341 + ///Sums two bounding boxes
102.342 + BoundingBox operator +(const BoundingBox& u){
102.343 + BoundingBox b = *this;
102.344 + return b += u;
102.345 + }
102.346 +
102.347 + };//class Boundingbox
102.348 +
102.349 +
102.350 + ///Map of x-coordinates of an xy<>-map
102.351 +
102.352 + ///\ingroup maps
102.353 + ///
102.354 + template<class M>
102.355 + class XMap
102.356 + {
102.357 + typename SmartReference<M>::Type _map;
102.358 + public:
102.359 + typedef True NeedCopy;
102.360 +
102.361 + typedef typename M::Value::Value Value;
102.362 + typedef typename M::Key Key;
102.363 + ///\e
102.364 + XMap(typename SmartParameter<M>::Type map) : _map(map) {}
102.365 + Value operator[](Key k) const {return _map[k].x;}
102.366 + void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
102.367 + };
102.368 +
102.369 + ///Returns an \ref XMap class
102.370 +
102.371 + ///This function just returns an \ref XMap class.
102.372 + ///
102.373 + ///\ingroup maps
102.374 + ///\relates XMap
102.375 + template<class M>
102.376 + inline XMap<M> xMap(M &m)
102.377 + {
102.378 + return XMap<M>(m);
102.379 + }
102.380 +
102.381 + template<class M>
102.382 + inline XMap<M> xMap(const M &m)
102.383 + {
102.384 + return XMap<M>(m);
102.385 + }
102.386 +
102.387 + ///Constant (read only) version of \ref XMap
102.388 +
102.389 + ///\ingroup maps
102.390 + ///
102.391 + template<class M>
102.392 + class ConstXMap
102.393 + {
102.394 + typename SmartConstReference<M>::Type _map;
102.395 + public:
102.396 + typedef True NeedCopy;
102.397 +
102.398 + typedef typename M::Value::Value Value;
102.399 + typedef typename M::Key Key;
102.400 + ///\e
102.401 + ConstXMap(const M &map) : _map(map) {}
102.402 + Value operator[](Key k) const {return _map[k].x;}
102.403 + };
102.404 +
102.405 + ///Returns a \ref ConstXMap class
102.406 +
102.407 + ///This function just returns an \ref ConstXMap class.
102.408 + ///
102.409 + ///\ingroup maps
102.410 + ///\relates ConstXMap
102.411 + template<class M>
102.412 + inline ConstXMap<M> xMap(const M &m)
102.413 + {
102.414 + return ConstXMap<M>(m);
102.415 + }
102.416 +
102.417 + ///Map of y-coordinates of an xy<>-map
102.418 +
102.419 + ///\ingroup maps
102.420 + ///
102.421 + template<class M>
102.422 + class YMap
102.423 + {
102.424 + typename SmartReference<M>::Type _map;
102.425 + public:
102.426 + typedef True NeedCopy;
102.427 +
102.428 + typedef typename M::Value::Value Value;
102.429 + typedef typename M::Key Key;
102.430 + ///\e
102.431 + YMap(typename SmartParameter<M>::Type map) : _map(map) {}
102.432 + Value operator[](Key k) const {return _map[k].y;}
102.433 + void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
102.434 + };
102.435 +
102.436 + ///Returns an \ref YMap class
102.437 +
102.438 + ///This function just returns an \ref YMap class.
102.439 + ///
102.440 + ///\ingroup maps
102.441 + ///\relates YMap
102.442 + template<class M>
102.443 + inline YMap<M> yMap(M &m)
102.444 + {
102.445 + return YMap<M>(m);
102.446 + }
102.447 +
102.448 + template<class M>
102.449 + inline YMap<M> yMap(const M &m)
102.450 + {
102.451 + return YMap<M>(m);
102.452 + }
102.453 +
102.454 + ///Constant (read only) version of \ref YMap
102.455 +
102.456 + ///\ingroup maps
102.457 + ///
102.458 + template<class M>
102.459 + class ConstYMap
102.460 + {
102.461 + typename SmartConstReference<M>::Type _map;
102.462 + public:
102.463 + typedef True NeedCopy;
102.464 +
102.465 + typedef typename M::Value::Value Value;
102.466 + typedef typename M::Key Key;
102.467 + ///\e
102.468 + ConstYMap(const M &map) : _map(map) {}
102.469 + Value operator[](Key k) const {return _map[k].y;}
102.470 + };
102.471 +
102.472 + ///Returns a \ref ConstYMap class
102.473 +
102.474 + ///This function just returns an \ref ConstYMap class.
102.475 + ///
102.476 + ///\ingroup maps
102.477 + ///\relates ConstYMap
102.478 + template<class M>
102.479 + inline ConstYMap<M> yMap(const M &m)
102.480 + {
102.481 + return ConstYMap<M>(m);
102.482 + }
102.483 +
102.484 +
102.485 + ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
102.486 +
102.487 + ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
102.488 + ///\ingroup maps
102.489 + ///
102.490 + template<class M>
102.491 + class NormSquareMap
102.492 + {
102.493 + typename SmartConstReference<M>::Type _map;
102.494 + public:
102.495 + typedef True NeedCopy;
102.496 +
102.497 + typedef typename M::Value::Value Value;
102.498 + typedef typename M::Key Key;
102.499 + ///\e
102.500 + NormSquareMap(const M &map) : _map(map) {}
102.501 + Value operator[](Key k) const {return _map[k].normSquare();}
102.502 + };
102.503 +
102.504 + ///Returns a \ref NormSquareMap class
102.505 +
102.506 + ///This function just returns an \ref NormSquareMap class.
102.507 + ///
102.508 + ///\ingroup maps
102.509 + ///\relates NormSquareMap
102.510 + template<class M>
102.511 + inline NormSquareMap<M> normSquareMap(const M &m)
102.512 + {
102.513 + return NormSquareMap<M>(m);
102.514 + }
102.515 +
102.516 + /// @}
102.517 +
102.518 +
102.519 +} //namespace lemon
102.520 +
102.521 +#endif //LEMON_XY_H
103.1 --- a/src/Makefile.am Sat May 21 21:04:57 2005 +0000
103.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
103.3 @@ -1,4 +0,0 @@
103.4 -if WANT_GUI
103.5 - MAYBE_GUI = gui
103.6 -endif
103.7 -SUBDIRS = lemon benchmark demo test $(MAYBE_GUI)
104.1 --- a/src/benchmark/Makefile.am Sat May 21 21:04:57 2005 +0000
104.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
104.3 @@ -1,11 +0,0 @@
104.4 -AM_CPPFLAGS = -I$(top_srcdir)/src
104.5 -
104.6 -noinst_HEADERS = bench_tools.h
104.7 -
104.8 -noinst_PROGRAMS = graph-bench hcube bfs-bench
104.9 -
104.10 -graph_bench_SOURCES = graph-bench.cc
104.11 -
104.12 -hcube_SOURCES = hcube.cc
104.13 -
104.14 -bfs_bench_SOURCES = bfs-bench.cc
105.1 --- a/src/benchmark/bench_tools.h Sat May 21 21:04:57 2005 +0000
105.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
105.3 @@ -1,128 +0,0 @@
105.4 -// -*- mode:C++ -*-
105.5 -#ifndef LEMON_BENCH_TEST_H
105.6 -#define LEMON_BENCH_TEST_H
105.7 -
105.8 -#include<vector>
105.9 -#include<iostream>
105.10 -
105.11 -#include<lemon/time_measure.h>
105.12 -
105.13 -///An experimental typedef factory
105.14 -#define GRAPH_TYPEDEF_FACTORY(Graph) \
105.15 - typedef typename Graph:: Node Node;\
105.16 - typedef typename Graph:: NodeIt NodeIt;\
105.17 - typedef typename Graph:: Edge Edge;\
105.18 - typedef typename Graph:: EdgeIt EdgeIt;\
105.19 - typedef typename Graph:: InEdgeIt InEdgeIt;\
105.20 - typedef typename Graph::OutEdgeIt OutEdgeIt;
105.21 -
105.22 -#define GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph) \
105.23 - typedef Graph:: Node Node;\
105.24 - typedef Graph:: NodeIt NodeIt;\
105.25 - typedef Graph:: Edge Edge;\
105.26 - typedef Graph:: EdgeIt EdgeIt;\
105.27 - typedef Graph:: InEdgeIt InEdgeIt;\
105.28 - typedef Graph::OutEdgeIt OutEdgeIt;
105.29 -
105.30 -
105.31 -///A primitive primtest
105.32 -
105.33 -///\bug 2 is not a prime according to this function!
105.34 -///
105.35 -///\bug This function should go out of header file. I'm making it
105.36 -/// inline for now.
105.37 -inline bool isPrim(int n)
105.38 -{
105.39 - if(n%2) {
105.40 - for(int k=3;n/k>=k;k+=2)
105.41 - if(!(n%k)) return false;
105.42 - return true;
105.43 - }
105.44 - return false;
105.45 -}
105.46 -
105.47 -///Finds the smallest prime not less then \c n.
105.48 -
105.49 -///\bug This function should go out of header file. I'm making it
105.50 -/// inline for now.
105.51 -inline int nextPrim(int n)
105.52 -{
105.53 - for(n+=!(n%2);!isPrim(n);n+=2) ;
105.54 - return n;
105.55 -}
105.56 -
105.57 -
105.58 -/// Class to generate consecutive primes
105.59 -class Primes
105.60 -{
105.61 - std::vector<int> primes;
105.62 - int n;
105.63 -
105.64 - bool isPrime(int m)
105.65 - {
105.66 - for(int i=0;m<primes[i]*primes[i];i++) if(!(m%primes[i])) return false;
105.67 - return true;
105.68 - }
105.69 -public:
105.70 - Primes() : n(1) {}
105.71 -
105.72 - int operator() ()
105.73 - {
105.74 - if(primes.size()==0) {
105.75 - primes.push_back(2);
105.76 - return 2;
105.77 - }
105.78 - else {
105.79 - do n+=2; while(!isPrime(n));
105.80 - primes.push_back(n);
105.81 - return n;
105.82 - }
105.83 - }
105.84 -};
105.85 -
105.86 -inline void PrintTime(char *ID,lemon::Timer &T)
105.87 -{
105.88 - lemon::TimeStamp S(T);
105.89 - std::cout << ID << ' ' << S.getUserTime() << ' '
105.90 - << S.getSystemTime() << ' ' << S.getRealTime() << std::endl;
105.91 -}
105.92 -
105.93 -
105.94 -
105.95 -///
105.96 -template<class Graph>
105.97 -void addHiperCube(Graph &G,int dim,std::vector<typename Graph::Node> &nodes)
105.98 -{
105.99 - GRAPH_TYPEDEF_FACTORY(Graph);
105.100 -
105.101 - std::vector<int> bits(dim+1);
105.102 - bits[0]=1;
105.103 - for(int i=1;i<=dim;i++) bits[i]=2*bits[i-1];
105.104 -
105.105 - for(int i=0;i<bits[dim];i++) {
105.106 - nodes.push_back(G.addNode());
105.107 - for(int j=0;j<dim;j++) if(i&bits[j]) G.addEdge(nodes[i-bits[j]],nodes[i]);
105.108 - }
105.109 -}
105.110 -
105.111 -///
105.112 -template<class Graph>
105.113 -void addBiDirHiperCube(Graph &G,int dim,std::vector<typename Graph::Node>&nodes)
105.114 -{
105.115 - GRAPH_TYPEDEF_FACTORY(Graph);
105.116 -
105.117 - std::vector<int> bits(dim+1);
105.118 - bits[0]=1;
105.119 - for(int i=1;i<=dim;i++) bits[i]=2*bits[i-1];
105.120 -
105.121 - for(int i=0;i<bits[dim];i++) {
105.122 - nodes.push_back(G.addNode());
105.123 - for(int j=0;j<dim;j++) if(i&bits[j]) {
105.124 - G.addEdge(nodes[i-bits[j]],nodes[i]);
105.125 - G.addEdge(nodes[i],nodes[i-bits[j]]);
105.126 - }
105.127 -
105.128 - }
105.129 -}
105.130 -
105.131 -#endif
106.1 --- a/src/benchmark/benchmark Sat May 21 21:04:57 2005 +0000
106.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
106.3 @@ -1,41 +0,0 @@
106.4 -#!/bin/bash
106.5 -
106.6 -function runtest () # prefix, prog, args
106.7 -{
106.8 - echo $1 1>&2
106.9 - $2 $3 $4 $5 $6 $7 $8 $9 >/dev/null;
106.10 - for ((i=1;i<=3;i++))
106.11 - do
106.12 - $2 $3 $4 $5 $6 $7 $8 $9;
106.13 - done |
106.14 - awk '{print "'$1'",$0}'
106.15 -}
106.16 -
106.17 -function runalltest() #postfix, CXX, CXXFLAGS
106.18 -{
106.19 - echo $1 1>&2
106.20 - make clean >/dev/null
106.21 - make CXX="$2" CXXFLAGS="$3" >/dev/null
106.22 - {
106.23 - runtest HCUBE19 hcube 19
106.24 - runtest BFS13-5000 hcube 13 5000
106.25 - runtest BFS10-50000 hcube 10 50000
106.26 - runtest GRBENCH graph-bench
106.27 - } | awk "{print \$0, \"$1\"}"
106.28 -}
106.29 -
106.30 -runalltest "gcc-3.3 -O2" g++ "-O2"
106.31 -runalltest "gcc-3.3 -O2-march=pentium-m" g++ "-O2 -march=pentium-m"
106.32 -runalltest "gcc-3.3 -O3" g++ "-O3"
106.33 -runalltest "gcc-3.3 -O3-march=pentium-m" g++ "-O3 -march=pentium-m"
106.34 -
106.35 -runalltest "gcc-3.4 -O2" g++-3.4 "-O2"
106.36 -runalltest "gcc-3.4 -O2-march=pentium-m" g++-3.4 "-O2 -march=pentium-m"
106.37 -runalltest "gcc-3.4 -O3" g++-3.4 "-O3"
106.38 -runalltest "gcc-3.4 -O3-march=pentium-m" g++-3.4 "-O3 -march=pentium-m"
106.39 -
106.40 -runalltest "icc -O2" icc "-O2"
106.41 -runalltest "icc -O2-march=pentium-m" icc "-O2 -march=pentium-m"
106.42 -runalltest "icc -O3" icc "-O3"
106.43 -runalltest "icc -O3-march=pentium-m" icc "-O3 -march=pentium-m"
106.44 -
107.1 --- a/src/benchmark/bfs-bench.cc Sat May 21 21:04:57 2005 +0000
107.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
107.3 @@ -1,144 +0,0 @@
107.4 -// -*- mode:C++ -*-
107.5 -
107.6 -#include <queue>
107.7 -#include<math.h>
107.8 -#include<lemon/smart_graph.h>
107.9 -#include"bench_tools.h"
107.10 -
107.11 -using namespace std;
107.12 -using namespace lemon;
107.13 -
107.14 -inline int numOfOnes(int n,int dim)
107.15 -{
107.16 - int s=0;
107.17 - for(int i=0;i<dim;i++) {
107.18 - s+=n%2;
107.19 - n>>=1;
107.20 - }
107.21 - return s;
107.22 -}
107.23 -
107.24 -inline int numOfZeros(int n,int dim)
107.25 -{
107.26 - int s=dim;
107.27 - for(int i=0;i<dim;i++) {
107.28 - s-=n&1;
107.29 - n>>=1;
107.30 - }
107.31 - return s;
107.32 -}
107.33 -
107.34 -template<class Graph>
107.35 -void bfsStlQueue(Graph &G,typename Graph::Node source)
107.36 -{
107.37 - GRAPH_TYPEDEF_FACTORY(Graph);
107.38 -
107.39 - using namespace std;
107.40 -
107.41 - typename Graph::template NodeMap<bool> visited(G,false);
107.42 -
107.43 - queue<typename Graph::Node> Q;
107.44 -
107.45 - Q.push(source);
107.46 - visited[source]=true;
107.47 - do {
107.48 - Node n(Q.front());
107.49 - Node m;
107.50 - Q.pop();
107.51 - for(OutEdgeIt e(G,n);e!=INVALID;++e)
107.52 - if(!visited[m=G.target(e)]) {
107.53 - Q.push(m);
107.54 - visited.set(m,true);
107.55 - }
107.56 - } while(!Q.empty());
107.57 -}
107.58 -
107.59 -template<class Graph>
107.60 -void bfsOwnQueue(Graph &G,typename Graph::Node source)
107.61 -{
107.62 - GRAPH_TYPEDEF_FACTORY(Graph);
107.63 -
107.64 - using namespace std;
107.65 -
107.66 - typename Graph::template NodeMap<bool> visited(G,false);
107.67 -
107.68 - int N=G.nodeNum();
107.69 - vector<typename Graph::Node> Q(N);
107.70 - int Qh=0;
107.71 - int Qt=0;
107.72 -
107.73 -
107.74 - Q[Qh++]=source;
107.75 - visited.set(source,true);
107.76 - do {
107.77 - Node m;
107.78 - Node n=Q[Qt++];
107.79 - for(OutEdgeIt e(G,n);e!=INVALID;++e)
107.80 - if(!visited[m=G.target(e)]) {
107.81 - Q[Qh++]=m;
107.82 - visited.set(m,true);
107.83 - }
107.84 - } while(Qt!=Qh);
107.85 -}
107.86 -
107.87 -template<class Graph>
107.88 -void iteratorBench(Graph &G)
107.89 -{
107.90 - GRAPH_TYPEDEF_FACTORY(Graph);
107.91 -
107.92 - int i=0;
107.93 -
107.94 - for(NodeIt n(G);n!=INVALID;++n)
107.95 - for(OutEdgeIt e(G,n);e!=INVALID;++e)
107.96 - i++;
107.97 -}
107.98 -
107.99 -int main(int argc, char *argv[])
107.100 -{
107.101 - typedef SmartGraph Graph;
107.102 -
107.103 - ///\bug GRAPH_TYPEDEF_FACTORY(Graph);
107.104 - GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph);
107.105 -
107.106 - Graph G;
107.107 -
107.108 - Timer T;
107.109 -
107.110 - if(argc!=3) {
107.111 - cout << "Usage: " << argv[0] << " dim mul\n";
107.112 - return 1;
107.113 - }
107.114 -
107.115 - int dim=atoi(argv[1]);
107.116 - int mul=atoi(argv[2]);
107.117 -
107.118 -// cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
107.119 -// << dim*(1<<dim) << " edges):";
107.120 -
107.121 - T.reset();
107.122 - vector<Node> nodes;
107.123 - addBiDirHiperCube(G,dim,nodes);
107.124 -
107.125 - PrintTime("GENGRAPH",T);
107.126 -
107.127 - T.reset();
107.128 - {
107.129 - for(int i=0;i<mul;i++)
107.130 - bfsStlQueue(G,nodes[0]);
107.131 - }
107.132 - PrintTime("BFS-STL",T);
107.133 - T.reset();
107.134 - {
107.135 - for(int i=0;i<mul;i++)
107.136 - bfsOwnQueue(G,nodes[0]);
107.137 - }
107.138 - PrintTime("BFS-OWN",T);
107.139 - T.reset();
107.140 - {
107.141 - for(int i=0;i<mul;i++)
107.142 - iteratorBench(G);
107.143 - }
107.144 - PrintTime("ITERATE",T);
107.145 -
107.146 -
107.147 -}
108.1 --- a/src/benchmark/graph-bench.cc Sat May 21 21:04:57 2005 +0000
108.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
108.3 @@ -1,55 +0,0 @@
108.4 -#include<lemon/list_graph.h>
108.5 -
108.6 -#include"bench_tools.h"
108.7 -
108.8 -using namespace lemon;
108.9 -
108.10 -///Makes a full graph by adding and deleting a lot of edges;
108.11 -
108.12 -///\param n Number of nodes.
108.13 -///\param rat The funcion will make \f$rat\timesn^2\f$ edge addition and
108.14 -///\f$(rat-1)\timesn^2\f$ deletion.
108.15 -///\param p Tuning parameters.
108.16 -///\warning \c rat, \c p, and \c n must be pairwise relative primes.
108.17 -template <class Graph>
108.18 -void makeFullGraph(int n, int rat, int p)
108.19 -{
108.20 - GRAPH_TYPEDEF_FACTORY(Graph);
108.21 -
108.22 - Graph G;
108.23 -
108.24 - // Node nodes[n];
108.25 - std::vector<Node> nodes(n);
108.26 - for(int i=0;i<n;i++) nodes[i]=G.addNode();
108.27 -
108.28 - //Edge equ[rat];
108.29 - std::vector<Edge> equ(rat);
108.30 -
108.31 - long long int count;
108.32 -
108.33 - for(count=0;count<rat;count++) {
108.34 - equ[count%rat]=G.addEdge(nodes[(count*p)%n],nodes[(count*p/n)%n]);
108.35 - }
108.36 - for(;(count%rat)||((count*p)%n)||((count*p/n)%n);count++) {
108.37 - // if(!(count%1000000)) fprintf(stderr,"%d\r",count);
108.38 - if(count%rat) G.erase(equ[count%rat]);
108.39 - equ[count%rat]=G.addEdge(nodes[(count*p)%n],nodes[(count*p/n)%n]);
108.40 - }
108.41 -// std::cout << "Added " << count
108.42 -// << " ( " << n << "^2 * " << rat << " ) edges\n";
108.43 -
108.44 -
108.45 - // for(int i=0;1;i++) ;
108.46 -}
108.47 -
108.48 -int main()
108.49 -{
108.50 - lemon::Timer T;
108.51 - makeFullGraph<ListGraph>(nextPrim(1000),nextPrim(300),nextPrim(100));
108.52 -
108.53 - PrintTime("BIG",T);
108.54 - T.reset();
108.55 - makeFullGraph<ListGraph>(nextPrim(100),nextPrim(30000),nextPrim(150));
108.56 -
108.57 - PrintTime("SMALL",T);
108.58 -}
109.1 --- a/src/benchmark/hcube.cc Sat May 21 21:04:57 2005 +0000
109.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
109.3 @@ -1,106 +0,0 @@
109.4 -// -*- mode:C++ -*-
109.5 -
109.6 -#include<math.h>
109.7 -#include<lemon/list_graph.h>
109.8 -#include<lemon/smart_graph.h>
109.9 -#include<lemon/dijkstra.h>
109.10 -#include<lemon/preflow.h>
109.11 -
109.12 -#include"bench_tools.h"
109.13 -
109.14 -using namespace std;
109.15 -using namespace lemon;
109.16 -
109.17 -inline int numOfOnes(int n,int dim)
109.18 -{
109.19 - int s=0;
109.20 - for(int i=0;i<dim;i++) {
109.21 - s+=n%2;
109.22 - n>>=1;
109.23 - }
109.24 - return s;
109.25 -}
109.26 -
109.27 -inline int numOfZeros(int n,int dim)
109.28 -{
109.29 - int s=dim;
109.30 - for(int i=0;i<dim;i++) {
109.31 - s-=n&1;
109.32 - n>>=1;
109.33 - }
109.34 - return s;
109.35 -}
109.36 -
109.37 -int main(int argc, char *argv[])
109.38 -{
109.39 - // typedef ListGraph Graph;
109.40 - typedef SmartGraph Graph;
109.41 -
109.42 - ///\bug GRAPH_TYPEDEF_FACTORY(Graph);
109.43 - GRAPH_TYPEDEF_FACTORY_NOTYPENAME(Graph);
109.44 -
109.45 - Graph G;
109.46 -
109.47 - Timer T;
109.48 -
109.49 - if(argc!=2) {
109.50 - cout << "Usage: " << argv[0] << " dim\n";
109.51 - return 1;
109.52 - }
109.53 -
109.54 - int dim=atoi(argv[1]);
109.55 -
109.56 -// cout << "Creating Hipercube ("<< (1<<dim) << " nodes, "
109.57 -// << dim*(1<<dim) << " edges):";
109.58 -
109.59 - T.reset();
109.60 - vector<Node> nodes;
109.61 - addBiDirHiperCube(G,dim,nodes);
109.62 -
109.63 - PrintTime("GENGRAPH",T);
109.64 -
109.65 - T.reset();
109.66 - Graph::EdgeMap<int> map(G);
109.67 - for(int i=0;i<5;i++) {
109.68 - Primes P;
109.69 - for(int i=0;i<dim*(1<<dim);i++) P();
109.70 -
109.71 - // for(EdgeIt e(G);G.valid(e);G.next(e)) map[e]=P();
109.72 -
109.73 - ///\todo It must have been commented out because of
109.74 - ///setToId
109.75 -// Edge te;
109.76 -// for(int i=0;i<dim*(1<<dim);i++) {
109.77 -// te.setToId(((long long int)(i)*93505)%(dim*(1<<dim)));
109.78 -// // map[Edge(((long long int)(i)*2987)%(dim*(1<<dim)))]=P();
109.79 -// map[te]=P();
109.80 -// }
109.81 -
109.82 -// for(int i=0;i<(1<<dim);i++) {
109.83 -// int mul= (1<<(numOfZeros(i,dim)/4));
109.84 -// for(OutEdgeIt e(G,nodes[i]);G.valid(e);G.next(e))
109.85 -// map[e]*=mul;
109.86 -// }
109.87 - }
109.88 -
109.89 - PrintTime("GENLENGTHS",T);
109.90 -
109.91 - T.reset();
109.92 - {
109.93 - Dijkstra<Graph> Dij(G,map);
109.94 - for(int i=0;i<10;i++)
109.95 - Dij.run(nodes[0]);
109.96 - }
109.97 - PrintTime("DIJKSTRA",T);
109.98 -
109.99 - T.reset();
109.100 - {
109.101 - Graph::EdgeMap<int> flow(G);
109.102 -
109.103 - Preflow<Graph,int> MF(G,nodes[0],nodes[1<<dim-1],map,flow);
109.104 - for(int i=0;i<10;i++)
109.105 - MF.run(MF.NO_FLOW);
109.106 - }
109.107 - PrintTime("PREFLOW",T);
109.108 -
109.109 -}
110.1 --- a/src/demo/Makefile.am Sat May 21 21:04:57 2005 +0000
110.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
110.3 @@ -1,41 +0,0 @@
110.4 -AM_CPPFLAGS = -I$(top_srcdir)/src
110.5 -LDADD = $(top_builddir)/src/lemon/libemon.la
110.6 -
110.7 -EXTRA_DIST = sub_graph_adaptor_demo.dim
110.8 -
110.9 -noinst_PROGRAMS = \
110.10 - dim_to_dot \
110.11 - dim_to_lgf \
110.12 - graph_to_eps_demo \
110.13 - min_route \
110.14 - sub_graph_adaptor_demo \
110.15 - coloring
110.16 -
110.17 -if HAVE_GLPK
110.18 -noinst_PROGRAMS += lp_demo lp_maxflow_demo
110.19 -else !HAVE_GLPK
110.20 -if HAVE_CPLEX
110.21 -noinst_PROGRAMS += lp_demo lp_maxflow_demo
110.22 -endif HAVE_CPLEX
110.23 -endif !HAVE_GLPK
110.24 -
110.25 -
110.26 -dim_to_dot_SOURCES = dim_to_dot.cc
110.27 -
110.28 -dim_to_lgf_SOURCES = dim_to_lgf.cc
110.29 -
110.30 -coloring_SOURCES = coloring.cc
110.31 -
110.32 -graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
110.33 -
110.34 -min_route_SOURCES = min_route.cc
110.35 -
110.36 -sub_graph_adaptor_demo_SOURCES = \
110.37 - sub_graph_adaptor_demo.cc \
110.38 - tight_edge_filter_map.h
110.39 -
110.40 -lp_demo_SOURCES = lp_demo.cc
110.41 -lp_demo_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
110.42 -
110.43 -lp_maxflow_demo_SOURCES = lp_maxflow_demo.cc
110.44 -lp_maxflow_demo_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
111.1 --- a/src/demo/coloring.cc Sat May 21 21:04:57 2005 +0000
111.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
111.3 @@ -1,71 +0,0 @@
111.4 -#include <vector>
111.5 -
111.6 -#include <lemon/smart_graph.h>
111.7 -#include <lemon/bin_heap.h>
111.8 -#include <lemon/graph_reader.h>
111.9 -#include <lemon/graph_to_eps.h>
111.10 -
111.11 -using namespace std;
111.12 -using namespace lemon;
111.13 -
111.14 -int main() {
111.15 - typedef UndirSmartGraph Graph;
111.16 - typedef Graph::Node Node;
111.17 - typedef Graph::NodeIt NodeIt;
111.18 - typedef Graph::UndirEdge UndirEdge;
111.19 - typedef Graph::IncEdgeIt IncEdgeIt;
111.20 -
111.21 - Graph graph;
111.22 -
111.23 - UndirGraphReader<Graph> reader(std::cin, graph);
111.24 - Graph::NodeMap<xy<double> > coords(graph);
111.25 - reader.readNodeMap("coords", coords);
111.26 -
111.27 - reader.run();
111.28 -
111.29 - Graph::NodeMap<int> color(graph, -2);
111.30 -
111.31 - Graph::NodeMap<int> heapMap(graph, -1);
111.32 - BinHeap<Node, int, Graph::NodeMap<int> > heap(heapMap);
111.33 -
111.34 - for (NodeIt it(graph); it != INVALID; ++it) {
111.35 - heap.push(it, countOutEdges(graph, it));
111.36 - }
111.37 -
111.38 - vector<Node> order;
111.39 -
111.40 - while (!heap.empty()) {
111.41 - Node node = heap.top();
111.42 - heap.pop();
111.43 - color[node] = -1;
111.44 - order.push_back(node);
111.45 - for (IncEdgeIt it(graph, node); it != INVALID; ++it) {
111.46 - Node target = graph.runningNode(it);
111.47 - if (color[target] == -2) {
111.48 - heap.decrease(target, heap[target] - 1);
111.49 - }
111.50 - }
111.51 - }
111.52 -
111.53 - for (int i = order.size() - 1; i >= 0; --i) {
111.54 - set<int> forbidden;
111.55 - for (IncEdgeIt it(graph, order[i]); it != INVALID; ++it) {
111.56 - Node target = graph.runningNode(it);
111.57 - if (color[target] != -1) {
111.58 - forbidden.insert(color[target]);
111.59 - }
111.60 - }
111.61 - int current = 0;
111.62 - while (forbidden.find(current) != forbidden.end()) ++current;
111.63 - color[order[i]] = current;
111.64 - }
111.65 -
111.66 - ColorSet colorSet;
111.67 -
111.68 - graphToEps(graph, "six_coloring.eps").
111.69 - title("Six Colored Graph").copyright("(C) 2005 LEMON Project").
111.70 - coords(coords).nodeColors(composeMap(colorSet, color)).
111.71 - scaleToA4().run();
111.72 -
111.73 - return 0;
111.74 -}
112.1 --- a/src/demo/dijkstra_demo.cc Sat May 21 21:04:57 2005 +0000
112.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
112.3 @@ -1,75 +0,0 @@
112.4 -#include <iostream>
112.5 -
112.6 -#include <lemon/list_graph.h>
112.7 -#include <lemon/dijkstra.h>
112.8 -
112.9 -using namespace lemon;
112.10 -
112.11 -
112.12 -int main (int, char*[])
112.13 -{
112.14 -
112.15 - typedef ListGraph Graph;
112.16 - typedef Graph::Node Node;
112.17 - typedef Graph::Edge Edge;
112.18 - typedef Graph::EdgeMap<int> LengthMap;
112.19 -
112.20 - Graph g;
112.21 -
112.22 - //An example from Ahuja's book
112.23 -
112.24 - Node s=g.addNode();
112.25 - Node v2=g.addNode();
112.26 - Node v3=g.addNode();
112.27 - Node v4=g.addNode();
112.28 - Node v5=g.addNode();
112.29 - Node t=g.addNode();
112.30 -
112.31 - Edge s_v2=g.addEdge(s, v2);
112.32 - Edge s_v3=g.addEdge(s, v3);
112.33 - Edge v2_v4=g.addEdge(v2, v4);
112.34 - Edge v2_v5=g.addEdge(v2, v5);
112.35 - Edge v3_v5=g.addEdge(v3, v5);
112.36 - Edge v4_t=g.addEdge(v4, t);
112.37 - Edge v5_t=g.addEdge(v5, t);
112.38 -
112.39 - LengthMap len(g);
112.40 -
112.41 - len.set(s_v2, 10);
112.42 - len.set(s_v3, 10);
112.43 - len.set(v2_v4, 5);
112.44 - len.set(v2_v5, 8);
112.45 - len.set(v3_v5, 5);
112.46 - len.set(v4_t, 8);
112.47 - len.set(v5_t, 8);
112.48 -
112.49 - std::cout << "The id of s is " << g.id(s)<< ", the id of t is " << g.id(t)<<"."<<std::endl;
112.50 -
112.51 - std::cout << "Dijkstra algorithm test..." << std::endl;
112.52 -
112.53 - Dijkstra<Graph, LengthMap> dijkstra_test(g,len);
112.54 -
112.55 - dijkstra_test.run(s);
112.56 -
112.57 -
112.58 - std::cout << "The distance of node t from node s: " << dijkstra_test.dist(t)<<std::endl;
112.59 -
112.60 - std::cout << "The shortest path from s to t goes through the following nodes (the first one is t, the last one is s): "<<std::endl;
112.61 -
112.62 - for (Node v=t;v != s; v=dijkstra_test.predNode(v)){
112.63 - std::cout << g.id(v) << "<-";
112.64 - }
112.65 - std::cout << g.id(s) << std::endl;
112.66 -
112.67 -
112.68 - return 0;
112.69 -}
112.70 -
112.71 -
112.72 -
112.73 -
112.74 -
112.75 -
112.76 -
112.77 -
112.78 -
113.1 --- a/src/demo/dim_to_dot.cc Sat May 21 21:04:57 2005 +0000
113.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
113.3 @@ -1,59 +0,0 @@
113.4 -// -*- c++ -*-
113.5 -
113.6 -// Use a DIMACS max flow file as stdin.
113.7 -// dim_to_dot < dimacs_max_flow_file > dot_output_file
113.8 -// This program makes a dot file from a dimacs max flow file.
113.9 -// This program can be an aid in making up to date visualized documantation
113.10 -// of demo programs.
113.11 -
113.12 -#include <iostream>
113.13 -#include <fstream>
113.14 -
113.15 -#include <lemon/smart_graph.h>
113.16 -#include <lemon/dimacs.h>
113.17 -
113.18 -using namespace lemon;
113.19 -
113.20 -using std::cout;
113.21 -using std::endl;
113.22 -
113.23 -int main()
113.24 -{
113.25 - typedef SmartGraph Graph;
113.26 -
113.27 - typedef Graph::Edge Edge;
113.28 - typedef Graph::Node Node;
113.29 - typedef Graph::EdgeIt EdgeIt;
113.30 - typedef Graph::NodeIt NodeIt;
113.31 - typedef Graph::EdgeMap<int> LengthMap;
113.32 -
113.33 - Graph g;
113.34 - Node s, t;
113.35 - LengthMap length(g);
113.36 -
113.37 - readDimacs(std::cin, g, length, s, t);
113.38 -
113.39 - cout << "digraph lemon_dot_example {" << endl;
113.40 - cout << " node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
113.41 - for(NodeIt n(g); n!=INVALID; ++n) {
113.42 - if (n==s) {
113.43 - cout << " n" << g.id(n)
113.44 - << " [ label=\"" << g.id(n) << " (s)\" ]; " << endl;
113.45 - } else {
113.46 - if (n==t) {
113.47 - cout << " n" << g.id(n)
113.48 - << " [ label=\"" << g.id(n) << " (t)\" ]; " << endl;
113.49 - } else {
113.50 - cout << " n" << g.id(n)
113.51 - << " [ label=\"" << g.id(n) << "\" ]; " << endl;
113.52 - }
113.53 - }
113.54 - }
113.55 - cout << " edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
113.56 - for(EdgeIt e(g); e!=INVALID; ++e) {
113.57 - cout << " n" << g.id(g.source(e)) << " -> " << " n" << g.id(g.target(e))
113.58 - << " [ label=\"" << g.id(e)
113.59 - << ", length:" << length[e] << "\" ]; " << endl;
113.60 - }
113.61 - cout << "}" << endl;
113.62 -}
114.1 --- a/src/demo/dim_to_lgf.cc Sat May 21 21:04:57 2005 +0000
114.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
114.3 @@ -1,166 +0,0 @@
114.4 -#include <iostream>
114.5 -#include <fstream>
114.6 -#include <cstring>
114.7 -
114.8 -#include <lemon/smart_graph.h>
114.9 -#include <lemon/dimacs.h>
114.10 -#include <lemon/graph_writer.h>
114.11 -
114.12 -using namespace std;
114.13 -using namespace lemon;
114.14 -
114.15 -const char* versionString =
114.16 -"dim_to_lgf - part of lemon library\n";
114.17 -
114.18 -const char* helpString =
114.19 -"Dimacs to LGF converter\n"
114.20 -"Usage: dim_to_lgf [OPTIONS]\n"
114.21 -"\n"
114.22 -"Examples:\n"
114.23 -" dim_to_lgf --type shortestpath --input graph.dim --output graph.lgf\n"
114.24 -"\n"
114.25 -"Options:\n"
114.26 -" -i FILE, --input FILE use FILE as input instead of standard input\n"
114.27 -" -o FILE, --output FILE use FILE as output instead of standard output\n"
114.28 -" -t TYPE, --type TYPE set up the type of the graph\n"
114.29 -" Possible types:\n"
114.30 -" mincostflow\n"
114.31 -" maxflow (default)\n"
114.32 -" shortestpath\n"
114.33 -" capacitated\n"
114.34 -" plain\n"
114.35 -" -v, --version shows the version of the converter\n"
114.36 -" -h, --help shows the help of the converter\n";
114.37 -
114.38 -
114.39 -int main(int argc, const char *argv[]) {
114.40 - typedef SmartGraph Graph;
114.41 -
114.42 - typedef Graph::Edge Edge;
114.43 - typedef Graph::Node Node;
114.44 - typedef Graph::EdgeIt EdgeIt;
114.45 - typedef Graph::NodeIt NodeIt;
114.46 - typedef Graph::EdgeMap<string> StringMap;
114.47 -
114.48 - std::string inputName;
114.49 - std::string outputName;
114.50 - std::string typeName;
114.51 -
114.52 - bool help = false;
114.53 - bool version = false;
114.54 -
114.55 - for (int arg = 1; arg < argc; ++arg) {
114.56 - if (strcmp(argv[arg], "--type") == 0 ||
114.57 - strcmp(argv[arg], "-t") == 0) {
114.58 - if (!typeName.empty()) {
114.59 - cerr << "Multiple type description" << endl;
114.60 - return -1;
114.61 - }
114.62 - if (arg + 1 == argc) {
114.63 - cerr << "Parameter without value" << endl;
114.64 - return -1;
114.65 - }
114.66 - typeName = argv[++arg];
114.67 - }
114.68 - else if (strcmp(argv[arg], "--input") == 0 ||
114.69 - strcmp(argv[arg], "-i") == 0) {
114.70 - if (!inputName.empty()) {
114.71 - cerr << "Multiple input description" << endl;
114.72 - return -1;
114.73 - }
114.74 - if (arg + 1 == argc) {
114.75 - cerr << "Parameter without value" << endl;
114.76 - return -1;
114.77 - }
114.78 - inputName = argv[++arg];
114.79 - }
114.80 - else if (strcmp(argv[arg], "--output") == 0 ||
114.81 - strcmp(argv[arg], "-o") == 0) {
114.82 - if (!outputName.empty()) {
114.83 - cerr << "Multiple input description" << endl;
114.84 - return -1;
114.85 - }
114.86 - if (arg + 1 == argc) {
114.87 - cerr << "Parameter without value" << endl;
114.88 - return -1;
114.89 - }
114.90 - outputName = argv[++arg];
114.91 - } else if (strcmp(argv[arg], "--help") == 0 ||
114.92 - strcmp(argv[arg], "-h") == 0) {
114.93 - help = true;
114.94 - } else if (strcmp(argv[arg], "--version") == 0 ||
114.95 - strcmp(argv[arg], "-v") == 0) {
114.96 - version = true;
114.97 - } else {
114.98 - cerr << "Invalid option: " << argv[arg] << endl;
114.99 - return -1;
114.100 - }
114.101 - }
114.102 -
114.103 - if (version) {
114.104 - cout << versionString;
114.105 - }
114.106 - if (help) {
114.107 - cout << helpString;
114.108 - }
114.109 - if (help || version) {
114.110 - return 0;
114.111 - }
114.112 -
114.113 - ifstream input;
114.114 - if (!inputName.empty()) {
114.115 - input.open(inputName.c_str());
114.116 - if (!input) {
114.117 - cerr << "File open error" << endl;
114.118 - return -1;
114.119 - }
114.120 - }
114.121 - istream& is = (inputName.empty() ? cin : input);
114.122 -
114.123 - ofstream output;
114.124 - if (!outputName.empty()) {
114.125 - output.open(outputName.c_str());
114.126 - if (!output) {
114.127 - cerr << "File open error" << endl;
114.128 - return -1;
114.129 - }
114.130 - }
114.131 - ostream& os = (outputName.empty() ? cout : output);
114.132 -
114.133 - if (typeName.empty()) {
114.134 - typeName = "maxflow";
114.135 - }
114.136 -
114.137 - if (typeName == "mincostflow") {
114.138 - Graph graph;
114.139 - Node s, t;
114.140 - StringMap cost(graph), capacity(graph);
114.141 - readDimacs(is, graph, capacity, s, t, cost);
114.142 - writeGraph(os, graph, capacity, s, t, cost);
114.143 - } else if (typeName == "maxflow") {
114.144 - Graph graph;
114.145 - Node s, t;
114.146 - StringMap capacity(graph);
114.147 - readDimacs(is, graph, capacity, s, t);
114.148 - writeGraph(os, graph, capacity, s, t);
114.149 - } else if (typeName == "shortestpath") {
114.150 - Graph graph;
114.151 - Node s;
114.152 - StringMap capacity(graph);
114.153 - readDimacs(is, graph, capacity, s);
114.154 - writeGraph(os, graph, capacity, s);
114.155 - } else if (typeName == "capacitated") {
114.156 - Graph graph;
114.157 - StringMap capacity(graph);
114.158 - readDimacs(is, graph, capacity);
114.159 - writeGraph(os, graph, capacity);
114.160 - } else if (typeName == "plain") {
114.161 - Graph graph;
114.162 - readDimacs(is, graph);
114.163 - writeGraph(os, graph);
114.164 - } else {
114.165 - cerr << "Invalid type error" << endl;
114.166 - return -1;
114.167 - }
114.168 - return 0;
114.169 -}
115.1 --- a/src/demo/graph_to_eps_demo.cc Sat May 21 21:04:57 2005 +0000
115.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
115.3 @@ -1,169 +0,0 @@
115.4 -/* -*- C++ -*-
115.5 - * src/lemon/demo/graph_to_eps.cc -
115.6 - * Part of LEMON, a generic C++ optimization library
115.7 - *
115.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
115.9 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
115.10 - *
115.11 - * Permission to use, modify and distribute this software is granted
115.12 - * provided that this copyright notice appears in all copies. For
115.13 - * precise terms see the accompanying LICENSE file.
115.14 - *
115.15 - * This software is provided "AS IS" with no warranty of any kind,
115.16 - * express or implied, and with no claim as to its suitability for any
115.17 - * purpose.
115.18 - *
115.19 - */
115.20 -
115.21 -#include<lemon/graph_to_eps.h>
115.22 -#include<lemon/maps.h>
115.23 -#include<lemon/list_graph.h>
115.24 -#include<lemon/graph_utils.h>
115.25 -
115.26 -#include <cmath>
115.27 -
115.28 -
115.29 -using namespace std;
115.30 -using namespace lemon;
115.31 -
115.32 -int main()
115.33 -{
115.34 - ColorSet colorSet;
115.35 -
115.36 - ListGraph g;
115.37 - typedef ListGraph::Node Node;
115.38 - typedef ListGraph::NodeIt NodeIt;
115.39 - typedef ListGraph::Edge Edge;
115.40 - typedef xy<int> Xy;
115.41 -
115.42 - Node n1=g.addNode();
115.43 - Node n2=g.addNode();
115.44 - Node n3=g.addNode();
115.45 - Node n4=g.addNode();
115.46 - Node n5=g.addNode();
115.47 -
115.48 - ListGraph::NodeMap<Xy> coords(g);
115.49 - ListGraph::NodeMap<double> sizes(g);
115.50 - ListGraph::NodeMap<int> colors(g);
115.51 - ListGraph::NodeMap<int> shapes(g);
115.52 - ListGraph::EdgeMap<int> ecolors(g);
115.53 - ListGraph::EdgeMap<int> widths(g);
115.54 -
115.55 - coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
115.56 - coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
115.57 - coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
115.58 - coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
115.59 - coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
115.60 -
115.61 - Edge e;
115.62 -
115.63 - e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
115.64 - e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
115.65 - e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
115.66 - e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
115.67 - e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
115.68 - e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
115.69 - e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
115.70 -
115.71 - IdMap<ListGraph,Node> id(g);
115.72 -
115.73 - graphToEps(g,"graph_to_eps_demo_out.eps").scale(10).coords(coords).
115.74 - title("Sample .eps figure").
115.75 - copyright("(C) 2005 LEMON Project").
115.76 - nodeScale(2).nodeSizes(sizes).
115.77 - nodeShapes(shapes).
115.78 - nodeColors(composeMap(colorSet,colors)).
115.79 - edgeColors(composeMap(colorSet,ecolors)).
115.80 - edgeWidthScale(.4).edgeWidths(widths).
115.81 - nodeTexts(id).nodeTextSize(3).
115.82 - run();
115.83 -
115.84 - graphToEps(g,"graph_to_eps_demo_out_arr.eps").scale(10).
115.85 - title("Sample .eps figure (with arrowheads)").
115.86 - copyright("(C) 2005 LEMON Project").
115.87 - nodeColors(composeMap(colorSet,colors)).
115.88 - coords(coords).
115.89 - nodeScale(2).nodeSizes(sizes).
115.90 - nodeShapes(shapes).
115.91 - edgeColors(composeMap(colorSet,ecolors)).
115.92 - edgeWidthScale(.4).edgeWidths(widths).
115.93 - nodeTexts(id).nodeTextSize(3).
115.94 - drawArrows().arrowWidth(1).arrowLength(1).
115.95 - run();
115.96 -
115.97 - e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
115.98 - e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
115.99 -
115.100 - e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
115.101 - e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
115.102 - e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
115.103 - e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
115.104 - e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
115.105 - e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
115.106 - e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
115.107 -
115.108 - graphToEps(g,"graph_to_eps_demo_out_par.eps").scale(10).
115.109 - title("Sample .eps figure (parallel edges)").
115.110 - copyright("(C) 2005 LEMON Project").
115.111 - nodeShapes(shapes).
115.112 - coords(coords).
115.113 - nodeScale(2).nodeSizes(sizes).
115.114 - nodeColors(composeMap(colorSet,colors)).
115.115 - edgeColors(composeMap(colorSet,ecolors)).
115.116 - edgeWidthScale(.4).edgeWidths(widths).
115.117 - nodeTexts(id).nodeTextSize(3).
115.118 - enableParallel().parEdgeDist(1.5).
115.119 - run();
115.120 -
115.121 - graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").scale(10).
115.122 - title("Sample .eps figure (parallel edges and arrowheads)").
115.123 - copyright("(C) 2005 LEMON Project").
115.124 - nodeScale(2).nodeSizes(sizes).
115.125 - coords(coords).
115.126 - nodeShapes(shapes).
115.127 - nodeColors(composeMap(colorSet,colors)).
115.128 - edgeColors(composeMap(colorSet,ecolors)).
115.129 - edgeWidthScale(.3).edgeWidths(widths).
115.130 - nodeTexts(id).nodeTextSize(3).
115.131 - enableParallel().parEdgeDist(1).
115.132 - drawArrows().arrowWidth(1).arrowLength(1).
115.133 - run();
115.134 -
115.135 - graphToEps(g,"graph_to_eps_demo_out_a4.eps").scaleToA4().
115.136 - title("Sample .eps figure (fits to A4)").
115.137 - copyright("(C) 2005 LEMON Project").
115.138 - nodeScale(2).nodeSizes(sizes).
115.139 - coords(coords).
115.140 - nodeShapes(shapes).
115.141 - nodeColors(composeMap(colorSet,colors)).
115.142 - edgeColors(composeMap(colorSet,ecolors)).
115.143 - edgeWidthScale(.3).edgeWidths(widths).
115.144 - nodeTexts(id).nodeTextSize(3).
115.145 - enableParallel().parEdgeDist(1).
115.146 - drawArrows().arrowWidth(1).arrowLength(1).
115.147 - run();
115.148 -
115.149 - ListGraph h;
115.150 - ListGraph::NodeMap<int> hcolors(h);
115.151 - ListGraph::NodeMap<Xy> hcoords(h);
115.152 -
115.153 - int cols=int(sqrt(double(colorSet.size())));
115.154 - for(int i=0;i<int(colorSet.size());i++) {
115.155 - Node n=h.addNode();
115.156 - hcoords[n]=Xy(i%cols,i/cols);
115.157 - hcolors[n]=i;
115.158 - }
115.159 -
115.160 - graphToEps(h,"graph_to_eps_demo_out_colors.eps").scale(60).
115.161 - title("Sample .eps figure (parallel edges and arrowheads)").
115.162 - copyright("(C) 2005 LEMON Project").
115.163 - coords(hcoords).
115.164 - nodeScale(.45).
115.165 - distantColorNodeTexts().
115.166 - // distantBWNodeTexts().
115.167 - nodeTexts(hcolors).nodeTextSize(.6).
115.168 - nodeColors(composeMap(colorSet,hcolors)).
115.169 - run();
115.170 -
115.171 -
115.172 -}
116.1 --- a/src/demo/helloworld.cc Sat May 21 21:04:57 2005 +0000
116.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
116.3 @@ -1,34 +0,0 @@
116.4 -#include <iostream>
116.5 -#include <lemon/list_graph.h>
116.6 -
116.7 -using namespace lemon;
116.8 -
116.9 -int main()
116.10 -{
116.11 - typedef ListGraph Graph;
116.12 - typedef Graph::Edge Edge;
116.13 - typedef Graph::InEdgeIt InEdgeIt;
116.14 - typedef Graph::OutEdgeIt OutEdgeIt;
116.15 - typedef Graph::EdgeIt EdgeIt;
116.16 - typedef Graph::Node Node;
116.17 - typedef Graph::NodeIt NodeIt;
116.18 -
116.19 - Graph g;
116.20 -
116.21 - for (int i = 0; i < 3; i++)
116.22 - g.addNode();
116.23 -
116.24 - for (NodeIt i(g); i!=INVALID; ++i)
116.25 - for (NodeIt j(g); j!=INVALID; ++j)
116.26 - if (i != j) g.addEdge(i, j);
116.27 -
116.28 - std::cout << "Nodes:";
116.29 - for (NodeIt i(g); i!=INVALID; ++i)
116.30 - std::cout << " " << g.id(i);
116.31 - std::cout << std::endl;
116.32 -
116.33 - std::cout << "Edges:";
116.34 - for (EdgeIt i(g); i!=INVALID; ++i)
116.35 - std::cout << " (" << g.id(g.source(i)) << "," << g.id(g.target(i)) << ")";
116.36 - std::cout << std::endl;
116.37 -}
117.1 --- a/src/demo/kruskal_demo.cc Sat May 21 21:04:57 2005 +0000
117.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
117.3 @@ -1,95 +0,0 @@
117.4 -#include <iostream>
117.5 -#include <vector>
117.6 -
117.7 -#include <lemon/maps.h>
117.8 -#include <lemon/kruskal.h>
117.9 -#include <lemon/list_graph.h>
117.10 -
117.11 -
117.12 -using namespace std;
117.13 -using namespace lemon;
117.14 -
117.15 -
117.16 -int main() {
117.17 -
117.18 - typedef ListGraph::Node Node;
117.19 - typedef ListGraph::Edge Edge;
117.20 - typedef ListGraph::NodeIt NodeIt;
117.21 - typedef ListGraph::EdgeIt EdgeIt;
117.22 -
117.23 - ListGraph G;
117.24 -
117.25 - Node s=G.addNode();
117.26 - Node v1=G.addNode();
117.27 - Node v2=G.addNode();
117.28 - Node v3=G.addNode();
117.29 - Node v4=G.addNode();
117.30 - Node t=G.addNode();
117.31 -
117.32 - Edge e1 = G.addEdge(s, v1);
117.33 - Edge e2 = G.addEdge(s, v2);
117.34 - Edge e3 = G.addEdge(v1, v2);
117.35 - Edge e4 = G.addEdge(v2, v1);
117.36 - Edge e5 = G.addEdge(v1, v3);
117.37 - Edge e6 = G.addEdge(v3, v2);
117.38 - Edge e7 = G.addEdge(v2, v4);
117.39 - Edge e8 = G.addEdge(v4, v3);
117.40 - Edge e9 = G.addEdge(v3, t);
117.41 - Edge e10 = G.addEdge(v4, t);
117.42 -
117.43 - typedef ListGraph::EdgeMap<int> ECostMap;
117.44 - typedef ListGraph::EdgeMap<bool> EBoolMap;
117.45 -
117.46 - ECostMap edge_cost_map(G, 2);
117.47 - EBoolMap tree_map(G);
117.48 -
117.49 -
117.50 - //Test with const map.
117.51 - std::cout << "The weight of the minimum spanning tree is " << kruskalEdgeMap(G, ConstMap<ListGraph::Edge,int>(2), tree_map)<<std::endl;
117.52 -
117.53 -/*
117.54 - ==10,
117.55 - "Total cost should be 10");
117.56 - //Test with a edge map (filled with uniform costs).
117.57 - check(kruskalEdgeMap(G, edge_cost_map, tree_map)==10,
117.58 - "Total cost should be 10");
117.59 -
117.60 - edge_cost_map.set(e1, -10);
117.61 - edge_cost_map.set(e2, -9);
117.62 - edge_cost_map.set(e3, -8);
117.63 - edge_cost_map.set(e4, -7);
117.64 - edge_cost_map.set(e5, -6);
117.65 - edge_cost_map.set(e6, -5);
117.66 - edge_cost_map.set(e7, -4);
117.67 - edge_cost_map.set(e8, -3);
117.68 - edge_cost_map.set(e9, -2);
117.69 - edge_cost_map.set(e10, -1);
117.70 -
117.71 - vector<Edge> tree_edge_vec;
117.72 -
117.73 - //Test with a edge map and inserter.
117.74 - check(kruskalEdgeMap_IteratorOut(G, edge_cost_map,
117.75 - back_inserter(tree_edge_vec))
117.76 - ==-31,
117.77 - "Total cost should be -31.");
117.78 -
117.79 - tree_edge_vec.clear();
117.80 -
117.81 - //The above test could also be coded like this:
117.82 - check(kruskal(G,
117.83 - makeKruskalMapInput(G, edge_cost_map),
117.84 - makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
117.85 - ==-31,
117.86 - "Total cost should be -31.");
117.87 -
117.88 - check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
117.89 -
117.90 - check(tree_edge_vec[0]==e1 &&
117.91 - tree_edge_vec[1]==e2 &&
117.92 - tree_edge_vec[2]==e5 &&
117.93 - tree_edge_vec[3]==e7 &&
117.94 - tree_edge_vec[4]==e9,
117.95 - "Wrong tree.");
117.96 -*/
117.97 - return 0;
117.98 -}
118.1 --- a/src/demo/lp_demo.cc Sat May 21 21:04:57 2005 +0000
118.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
118.3 @@ -1,113 +0,0 @@
118.4 -#ifdef HAVE_CONFIG_H
118.5 -#include <config.h>
118.6 -#endif
118.7 -
118.8 -#include <iostream>
118.9 -
118.10 -
118.11 -#ifdef HAVE_GLPK
118.12 -#include <lemon/lp_glpk.h>
118.13 -#elif HAVE_CPLEX
118.14 -#include <lemon/lp_cplex.h>
118.15 -#endif
118.16 -
118.17 -using namespace lemon;
118.18 -
118.19 -#ifdef HAVE_GLPK
118.20 -typedef LpGlpk LpDefault;
118.21 -#elif HAVE_CPLEX
118.22 -typedef LpCplex LpDefault;
118.23 -#endif
118.24 -
118.25 -int main()
118.26 -{
118.27 - //The following example is taken from the documentation of the GLPK library.
118.28 - //See it in the GLPK reference manual and among the GLPK sample files (sample.c)
118.29 - LpDefault lp;
118.30 - typedef LpDefault::Row Row;
118.31 - typedef LpDefault::Col Col;
118.32 -
118.33 - lp.max();
118.34 -
118.35 - Col x1 = lp.addCol();
118.36 - Col x2 = lp.addCol();
118.37 - Col x3 = lp.addCol();
118.38 -
118.39 - //One solution
118.40 - // Row p = lp.addRow();
118.41 - // Row q = lp.addRow();
118.42 - // Row r = lp.addRow();
118.43 - // lp.setRow(p,x1+x2+x3 <=100);
118.44 - // lp.setRow(q,10*x1+4*x2+5*x3<=600);
118.45 - // lp.setRow(r,2*x1+2*x2+6*x3<=300);
118.46 -
118.47 - //A more elegant one
118.48 - //Constraints
118.49 - lp.addRow(x1+x2+x3 <=100);
118.50 - lp.addRow(10*x1+4*x2+5*x3<=600);
118.51 - lp.addRow(2*x1+2*x2+6*x3<=300);
118.52 - //Nonnegativity of the variables
118.53 - lp.colLowerBound(x1, 0);
118.54 - lp.colLowerBound(x2, 0);
118.55 - lp.colLowerBound(x3, 0);
118.56 - //Objective function
118.57 - lp.setObj(10*x1+6*x2+4*x3);
118.58 -
118.59 - lp.solve();
118.60 -
118.61 - if (lp.primalStatus()==LpSolverBase::OPTIMAL){
118.62 - printf("Z = %g; x1 = %g; x2 = %g; x3 = %g\n",
118.63 - lp.primalValue(),
118.64 - lp.primal(x1), lp.primal(x2), lp.primal(x3));
118.65 - }
118.66 - else{
118.67 - std::cout<<"Optimal solution not found!"<<std::endl;
118.68 - }
118.69 -
118.70 -
118.71 - //Here comes the same problem written in C using GLPK API routines
118.72 -
118.73 -// LPX *lp;
118.74 -// int ia[1+1000], ja[1+1000];
118.75 -// double ar[1+1000], Z, x1, x2, x3;
118.76 -// s1: lp = lpx_create_prob();
118.77 -// s2: lpx_set_prob_name(lp, "sample");
118.78 -// s3: lpx_set_obj_dir(lp, LPX_MAX);
118.79 -// s4: lpx_add_rows(lp, 3);
118.80 -// s5: lpx_set_row_name(lp, 1, "p");
118.81 -// s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0);
118.82 -// s7: lpx_set_row_name(lp, 2, "q");
118.83 -// s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0);
118.84 -// s9: lpx_set_row_name(lp, 3, "r");
118.85 -// s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0);
118.86 -// s11: lpx_add_cols(lp, 3);
118.87 -// s12: lpx_set_col_name(lp, 1, "x1");
118.88 -// s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0);
118.89 -// s14: lpx_set_obj_coef(lp, 1, 10.0);
118.90 -// s15: lpx_set_col_name(lp, 2, "x2");
118.91 -// s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0);
118.92 -// s17: lpx_set_obj_coef(lp, 2, 6.0);
118.93 -// s18: lpx_set_col_name(lp, 3, "x3");
118.94 -// s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0);
118.95 -// s20: lpx_set_obj_coef(lp, 3, 4.0);
118.96 -// s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
118.97 -// s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */
118.98 -// s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */
118.99 -// s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */
118.100 -// s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */
118.101 -// s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */
118.102 -// s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */
118.103 -// s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */
118.104 -// s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */
118.105 -// s30: lpx_load_matrix(lp, 9, ia, ja, ar);
118.106 -// s31: lpx_simplex(lp);
118.107 -// s32: Z = lpx_get_obj_val(lp);
118.108 -// s33: x1 = lpx_get_col_prim(lp, 1);
118.109 -// s34: x2 = lpx_get_col_prim(lp, 2);
118.110 -// s35: x3 = lpx_get_col_prim(lp, 3);
118.111 -// s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3);
118.112 -// s37: lpx_delete_prob(lp);
118.113 -// return 0;
118.114 -
118.115 - return 0;
118.116 -}
119.1 --- a/src/demo/lp_maxflow_demo.cc Sat May 21 21:04:57 2005 +0000
119.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
119.3 @@ -1,86 +0,0 @@
119.4 -#ifdef HAVE_CONFIG_H
119.5 -#include <config.h>
119.6 -#endif
119.7 -
119.8 -#include<lemon/graph_reader.h>
119.9 -#include<lemon/list_graph.h>
119.10 -
119.11 -
119.12 -#ifdef HAVE_GLPK
119.13 -#include <lemon/lp_glpk.h>
119.14 -#elif HAVE_CPLEX
119.15 -#include <lemon/lp_cplex.h>
119.16 -#endif
119.17 -
119.18 -using namespace lemon;
119.19 -
119.20 -#ifdef HAVE_GLPK
119.21 -typedef LpGlpk LpDefault;
119.22 -#elif HAVE_CPLEX
119.23 -typedef LpCplex LpDefault;
119.24 -#endif
119.25 -
119.26 -
119.27 -template<class G,class C>
119.28 -double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
119.29 -{
119.30 - LpDefault lp;
119.31 -
119.32 - typedef G Graph;
119.33 - typedef typename G::Node Node;
119.34 - typedef typename G::NodeIt NodeIt;
119.35 - typedef typename G::Edge Edge;
119.36 - typedef typename G::EdgeIt EdgeIt;
119.37 - typedef typename G::OutEdgeIt OutEdgeIt;
119.38 - typedef typename G::InEdgeIt InEdgeIt;
119.39 -
119.40 - typename G::template EdgeMap<LpDefault::Col> x(g);
119.41 - lp.addColSet(x);
119.42 -
119.43 - for(EdgeIt e(g);e!=INVALID;++e) {
119.44 - lp.colUpperBound(x[e],cap[e]);
119.45 - lp.colLowerBound(x[e],0);
119.46 - }
119.47 -
119.48 - for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
119.49 - LpDefault::Expr ex;
119.50 - for(InEdgeIt e(g,n);e!=INVALID;++e) ex+=x[e];
119.51 - for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
119.52 - lp.addRow(ex==0);
119.53 - }
119.54 - {
119.55 - LpDefault::Expr ex;
119.56 - for(InEdgeIt e(g,t);e!=INVALID;++e) ex+=x[e];
119.57 - for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
119.58 - lp.setObj(ex);
119.59 - }
119.60 - lp.max();
119.61 -
119.62 -#ifdef HAVE_GLPK
119.63 - lp.presolver(true);
119.64 - lp.messageLevel(3);
119.65 -#endif
119.66 -
119.67 - lp.solve();
119.68 -
119.69 - return lp.primalValue();
119.70 -}
119.71 -
119.72 -int main()
119.73 -{
119.74 - ListGraph g;
119.75 - ListGraph::Node s;
119.76 - ListGraph::Node t;
119.77 -
119.78 - ListGraph::EdgeMap<double> cap(g);
119.79 -
119.80 - GraphReader<ListGraph> reader(std::cin,g);
119.81 - reader.readNode("source",s).readNode("target",t)
119.82 - .readEdgeMap("capacity",cap).run();
119.83 -
119.84 - // std::ifstream file("../test/preflow_");
119.85 -// readDimacs(file, g, cap, s, t);
119.86 -
119.87 - std::cout << "Max flow value = " << maxFlow(g,cap,s,t) << std::endl;
119.88 -
119.89 -}
120.1 --- a/src/demo/min_route.cc Sat May 21 21:04:57 2005 +0000
120.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
120.3 @@ -1,114 +0,0 @@
120.4 -#include <iostream>
120.5 -#include <fstream>
120.6 -
120.7 -#include <lemon/smart_graph.h>
120.8 -#include <lemon/dijkstra.h>
120.9 -#include <lemon/maps.h>
120.10 -#include <lemon/xy.h>
120.11 -#include <lemon/graph_reader.h>
120.12 -
120.13 -#include <lemon/time_measure.h>
120.14 -
120.15 -#include <cmath>
120.16 -
120.17 -
120.18 -using namespace lemon;
120.19 -
120.20 -template <typename CoordMap>
120.21 -class PotentialMap {
120.22 -public:
120.23 - typedef double Value;
120.24 - typedef typename CoordMap::Key Key;
120.25 -
120.26 - PotentialMap(const CoordMap& _coord, const xy<double>& _target)
120.27 - : coord(_coord), target(_target) {}
120.28 -
120.29 - double operator[](const Key& node) const {
120.30 - return std::sqrt((coord[node].x - target.x) * (coord[node].x - target.x) +
120.31 - (coord[node].y - target.y) * (coord[node].y - target.y));
120.32 - }
120.33 -private:
120.34 - const CoordMap& coord;
120.35 - xy<double> target;
120.36 -};
120.37 -
120.38 -template <typename Graph, typename LengthMap, typename PotentialMap>
120.39 -class ReducedLengthMap {
120.40 -public:
120.41 - typedef double Value;
120.42 - typedef typename LengthMap::Key Key;
120.43 -
120.44 - ReducedLengthMap(const Graph& _graph, const LengthMap& _length,
120.45 - const PotentialMap& _pot)
120.46 - : graph(_graph), length(_length), pot(_pot) {}
120.47 -
120.48 - Value operator[](const Key& edge) const {
120.49 - return length[edge] - (pot[graph.source(edge)] - pot[graph.target(edge)]);
120.50 - }
120.51 -
120.52 -private:
120.53 - const Graph& graph;
120.54 - const LengthMap& length;
120.55 - const PotentialMap& pot;
120.56 -};
120.57 -
120.58 -int main() {
120.59 - typedef SmartGraph Graph;
120.60 -
120.61 - typedef Graph::Edge Edge;
120.62 - typedef Graph::Node Node;
120.63 - typedef Graph::EdgeIt EdgeIt;
120.64 - typedef Graph::NodeIt NodeIt;
120.65 - typedef Graph::EdgeMap<double> LengthMap;
120.66 - typedef Graph::NodeMap<xy<double> > CoordMap;
120.67 -
120.68 - SmartGraph graph;
120.69 -
120.70 - std::ifstream is("route.lgf");
120.71 - GraphReader<Graph> reader(is, graph);
120.72 -
120.73 - CoordMap coord(graph);
120.74 - XMap<CoordMap> xcoord = xMap(coord);
120.75 - reader.readNodeMap("coordinates_x", xcoord);
120.76 - YMap<CoordMap> ycoord = yMap(coord);
120.77 - reader.readNodeMap("coordinates_y", ycoord);
120.78 -
120.79 - LengthMap length(graph);
120.80 - reader.readEdgeMap("length", length);
120.81 -
120.82 - Node source, target;
120.83 - reader.readNode("source", source);
120.84 - reader.readNode("target", target);
120.85 -
120.86 - reader.run();
120.87 -
120.88 - {
120.89 - Timer timer;
120.90 - Dijkstra<Graph, LengthMap> dijkstra(graph, length);
120.91 - dijkstra.init();
120.92 - dijkstra.addSource(source);
120.93 - dijkstra.start(target);
120.94 -
120.95 - std::cout << dijkstra.dist(target) << std::endl;
120.96 - std::cout << timer << std::endl;
120.97 - }
120.98 - {
120.99 - Timer timer;
120.100 - typedef PotentialMap<CoordMap> Potential;
120.101 - Potential potential(coord, coord[target]);
120.102 -
120.103 - typedef ReducedLengthMap<Graph, LengthMap, Potential> ReducedLength;
120.104 - ReducedLength reduced(graph, length, potential);
120.105 -
120.106 - Dijkstra<Graph, ReducedLength> dijkstra(graph, reduced);
120.107 -
120.108 - dijkstra.init();
120.109 - dijkstra.addSource(source);
120.110 - dijkstra.start(target);
120.111 -
120.112 - std::cout << dijkstra.dist(target) + potential[source] << std::endl;
120.113 - std::cout << timer << std::endl;
120.114 - }
120.115 -
120.116 - return 0;
120.117 -}
121.1 --- a/src/demo/route.lgf Sat May 21 21:04:57 2005 +0000
121.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
121.3 @@ -1,41 +0,0 @@
121.4 -@nodeset
121.5 -id coordinates_x coordinates_y
121.6 -9 447.907 578.328
121.7 -8 79.2573 909.464
121.8 -7 878.677 960.04
121.9 -6 11.5504 938.413
121.10 -5 327.398 815.035
121.11 -4 427.002 954.002
121.12 -3 148.549 753.748
121.13 -2 903.889 326.476
121.14 -1 408.248 577.327
121.15 -0 189.239 92.5316
121.16 -@edgeset
121.17 - length
121.18 -2 3 901.074
121.19 -8 5 270.85
121.20 -6 9 601.553
121.21 -5 9 285.022
121.22 -9 4 408.091
121.23 -3 0 719.712
121.24 -7 5 612.836
121.25 -0 4 933.353
121.26 -5 0 778.871
121.27 -5 5 0
121.28 -7 1 664.049
121.29 -5 5 0
121.30 -0 9 560.464
121.31 -4 8 352.36
121.32 -4 9 399.625
121.33 -4 1 402.171
121.34 -1 2 591.688
121.35 -3 8 182.376
121.36 -4 5 180.254
121.37 -3 1 345.283
121.38 -5 4 184.511
121.39 -6 2 1112.45
121.40 -0 1 556.624
121.41 -@nodes
121.42 -source 1
121.43 -target 8
121.44 -@end
122.1 --- a/src/demo/sub_graph_adaptor_demo.cc Sat May 21 21:04:57 2005 +0000
122.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
122.3 @@ -1,80 +0,0 @@
122.4 -// -*- c++ -*-
122.5 -
122.6 -// Use a DIMACS max flow file as stdin.
122.7 -// sub_graph_adaptor_demo < dimacs_max_flow_file
122.8 -// This program computes a maximum number of edge-disjoint shortest paths
122.9 -// between s and t.
122.10 -
122.11 -#include <iostream>
122.12 -#include <fstream>
122.13 -
122.14 -#include <lemon/smart_graph.h>
122.15 -#include <lemon/dijkstra.h>
122.16 -#include <lemon/maps.h>
122.17 -#include <lemon/graph_adaptor.h>
122.18 -#include <lemon/dimacs.h>
122.19 -#include <lemon/preflow.h>
122.20 -#include <tight_edge_filter_map.h>
122.21 -
122.22 -using namespace lemon;
122.23 -
122.24 -using std::cout;
122.25 -using std::endl;
122.26 -
122.27 -int main()
122.28 -{
122.29 - typedef SmartGraph Graph;
122.30 -
122.31 - typedef Graph::Edge Edge;
122.32 - typedef Graph::Node Node;
122.33 - typedef Graph::EdgeIt EdgeIt;
122.34 - typedef Graph::NodeIt NodeIt;
122.35 - typedef Graph::EdgeMap<int> LengthMap;
122.36 -
122.37 - Graph g;
122.38 - Node s, t;
122.39 - LengthMap length(g);
122.40 -
122.41 - readDimacs(std::cin, g, length, s, t);
122.42 -
122.43 - cout << "edges with lengths (of form id, source--length->target): " << endl;
122.44 - for(EdgeIt e(g); e!=INVALID; ++e)
122.45 - cout << " " << g.id(e) << ", " << g.id(g.source(e)) << "--"
122.46 - << length[e] << "->" << g.id(g.target(e)) << endl;
122.47 -
122.48 - cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
122.49 -
122.50 - typedef Dijkstra<Graph, LengthMap> Dijkstra;
122.51 - Dijkstra dijkstra(g, length);
122.52 - dijkstra.run(s);
122.53 -
122.54 - // This map returns true exactly for those edges which are
122.55 - // tight w.r.t the length funcion and the potential
122.56 - // given by the dijkstra algorithm.
122.57 - typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
122.58 - TightEdgeFilter;
122.59 - TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
122.60 -
122.61 -// ConstMap<Node, bool> const_true_map(true);
122.62 - // This graph contains exaclty the tight edges.
122.63 -// typedef SubGraphAdaptor<Graph, ConstMap<Node, bool>, TightEdgeFilter> SubGW;
122.64 - typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
122.65 - SubGW gw(g, tight_edge_filter);
122.66 -
122.67 - ConstMap<Edge, int> const_1_map(1);
122.68 - Graph::EdgeMap<int> flow(g, 0);
122.69 - // Max flow between s and t in the graph of tight edges.
122.70 - Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
122.71 - preflow(gw, s, t, const_1_map, flow);
122.72 - preflow.run();
122.73 -
122.74 - cout << "maximum number of edge-disjoint shortest path: "
122.75 - << preflow.flowValue() << endl;
122.76 - cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
122.77 - << endl;
122.78 - for(EdgeIt e(g); e!=INVALID; ++e)
122.79 - if (flow[e])
122.80 - cout << " " << g.id(e) << ", "
122.81 - << g.id(g.source(e)) << "--"
122.82 - << length[e] << "->" << g.id(g.target(e)) << endl;
122.83 -}
123.1 --- a/src/demo/sub_graph_adaptor_demo.dim Sat May 21 21:04:57 2005 +0000
123.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
123.3 @@ -1,14 +0,0 @@
123.4 -c LEMON max flow problem
123.5 -p max 7 9
123.6 -n 1 s
123.7 -n 7 t
123.8 -a 1 2 3
123.9 -a 1 3 2
123.10 -a 1 4 1
123.11 -a 2 5 3
123.12 -a 3 5 2
123.13 -a 3 7 5
123.14 -a 3 6 3
123.15 -a 4 6 1
123.16 -a 5 7 2
123.17 -a 6 7 4
124.1 --- a/src/demo/tight_edge_filter_map.h Sat May 21 21:04:57 2005 +0000
124.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
124.3 @@ -1,67 +0,0 @@
124.4 -/* -*- C++ -*-
124.5 - * src/lemon/tight_edge_filter_map.h - Part of LEMON, a generic C++ optimization library
124.6 - *
124.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
124.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
124.9 - *
124.10 - * Permission to use, modify and distribute this software is granted
124.11 - * provided that this copyright notice appears in all copies. For
124.12 - * precise terms see the accompanying LICENSE file.
124.13 - *
124.14 - * This software is provided "AS IS" with no warranty of any kind,
124.15 - * express or implied, and with no claim as to its suitability for any
124.16 - * purpose.
124.17 - *
124.18 - */
124.19 -
124.20 -#ifndef LEMON_TIGHT_EDGE_FILTER_MAP_H
124.21 -#define LEMON_TIGHT_EDGE_FILTER_MAP_H
124.22 -
124.23 -#include <lemon/maps.h>
124.24 -
124.25 -// /// \file
124.26 -// /// \brief Maximum flow algorithms.
124.27 -// /// \ingroup galgs
124.28 -
124.29 -namespace lemon {
124.30 -
124.31 - /*!
124.32 - \brief A map for filtering the edge-set to those edges
124.33 - which are tight w.r.t. a node-potential and
124.34 - edge-distance.
124.35 -
124.36 - Let \f$G=(V,A)\f$ be a directed graph (graph for short) and
124.37 - let \f$\mathbb{F}\f$ be a number type.
124.38 - Given a distance function
124.39 - \f$d:E\to\mathbb{F}\f$,
124.40 - \f$\pi:V\to\mathbb{F}\f$ is said to be a potetial
124.41 - w.r.t. \f$d\f$
124.42 - if and only if
124.43 - \f$\pi(v)\le d(uv)+\pi(u)\f$ holds for each edge \f$uv\in E\f$
124.44 - (or the reverse inequality holds for each edge).
124.45 - An edge is said to be tight if this inequality holds with equality,
124.46 - and the map returns \c true exactly for those edges.
124.47 - To avoid rounding errors, it is recommended to use this class with exact
124.48 - number types, e.g. with \c int.
124.49 - */
124.50 - template<typename Graph,
124.51 - typename NodePotentialMap, typename EdgeDistanceMap>
124.52 - class TightEdgeFilterMap : public MapBase<typename Graph::Edge, bool> {
124.53 - protected:
124.54 - const Graph* g;
124.55 - NodePotentialMap* node_potential;
124.56 - EdgeDistanceMap* edge_distance;
124.57 - public:
124.58 - TightEdgeFilterMap(Graph& _g, NodePotentialMap& _node_potential,
124.59 - EdgeDistanceMap& _edge_distance) :
124.60 - g(&_g), node_potential(&_node_potential),
124.61 - edge_distance(&_edge_distance) { }
124.62 - bool operator[](const typename Graph::Edge& e) const {
124.63 - return ((*node_potential)[g->target(e)] ==
124.64 - (*edge_distance)[e]+(*node_potential)[g->source(e)]);
124.65 - }
124.66 - };
124.67 -
124.68 -} //namespace lemon
124.69 -
124.70 -#endif //LEMON_TIGHT_EDGE_FILTER_MAP_H
125.1 --- a/src/gui/Makefile.am Sat May 21 21:04:57 2005 +0000
125.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
125.3 @@ -1,19 +0,0 @@
125.4 -AM_CPPFLAGS = -I$(top_srcdir)/src
125.5 -LDADD = $(top_builddir)/src/lemon/libemon.la
125.6 -
125.7 -bin_PROGRAMS = gd
125.8 -
125.9 -gd_SOURCES = \
125.10 - all_include.h \
125.11 - graph_displayer_canvas.cc \
125.12 - graph_displayer_canvas.h \
125.13 - graph-displayer.cc \
125.14 - main_win.cc \
125.15 - main_win.h \
125.16 - mapstorage.cc \
125.17 - mapstorage.h \
125.18 - map_win.cc \
125.19 - map_win.h
125.20 -
125.21 -gd_CXXFLAGS = $(GTK_CFLAGS)
125.22 -gd_LDFLAGS = $(GTK_LIBS)
126.1 --- a/src/gui/all_include.h Sat May 21 21:04:57 2005 +0000
126.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
126.3 @@ -1,39 +0,0 @@
126.4 -// -*- C++ -*- //
126.5 -
126.6 -#ifndef ALL_INCLUDE_H
126.7 -#define ALL_INCLUDE_H
126.8 -
126.9 -#include <fstream>
126.10 -#include <iostream>
126.11 -
126.12 -#include <vector>
126.13 -
126.14 -#include <lemon/list_graph.h>
126.15 -#include <lemon/graph_reader.h>
126.16 -#include <lemon/graph_writer.h>
126.17 -#include <lemon/graph_utils.h>
126.18 -#include <lemon/maps.h>
126.19 -#include <lemon/error.h>
126.20 -#include <lemon/xy.h>
126.21 -
126.22 -enum {WIDTH, COLOR, TEXT, PROPERTY_NUM};// properties;
126.23 -#define RANGE 3
126.24 -#define WIN_WIDTH 900
126.25 -#define WIN_HEIGHT 600
126.26 -
126.27 -
126.28 -#ifndef MAIN_PART
126.29 -extern std::string * property_strings;
126.30 -extern double * property_defaults;
126.31 -#endif //MAIN_PART
126.32 -
126.33 -using namespace lemon;
126.34 -
126.35 -typedef xy<double> Coordinates;
126.36 -typedef ListGraph Graph;
126.37 -typedef Graph::NodeMap<Coordinates> CoordinatesMap;
126.38 -typedef Graph::Node Node;
126.39 -typedef Graph::EdgeIt EdgeIt;
126.40 -typedef Graph::NodeIt NodeIt;
126.41 -
126.42 -#endif // ALL_INCLUDE_H
127.1 --- a/src/gui/graph-displayer.cc Sat May 21 21:04:57 2005 +0000
127.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
127.3 @@ -1,73 +0,0 @@
127.4 -#include <all_include.h>
127.5 -#include <mapstorage.h>
127.6 -#include <main_win.h>
127.7 -#include <libgnomecanvasmm.h>
127.8 -#include <libgnomecanvasmm/polygon.h>
127.9 -
127.10 -#define MAIN_PART
127.11 -
127.12 -std::string * property_strings;
127.13 -double * property_defaults;
127.14 -
127.15 -
127.16 -int main(int argc, char *argv[])
127.17 -{
127.18 - property_strings=new std::string[PROPERTY_NUM];
127.19 - property_strings[WIDTH]="Width";
127.20 - property_strings[COLOR]="Color";
127.21 - property_strings[TEXT]="Text";
127.22 -
127.23 - property_defaults=new double[PROPERTY_NUM];
127.24 - property_defaults[WIDTH]=10.0;
127.25 - property_defaults[COLOR]=100;
127.26 - property_defaults[TEXT]=0;
127.27 -
127.28 - if(argc<2)
127.29 - {
127.30 - std::cerr << "USAGE: gd <input filename.lgf>" << std::endl;
127.31 - return 0;
127.32 - }
127.33 -
127.34 - Coordinates coosvector;
127.35 -
127.36 - Graph g;
127.37 -
127.38 - CoordinatesMap cm(g);
127.39 - Graph::EdgeMap<double> cap(g), map1(g), map2(g), map3(g), map4(g);
127.40 -
127.41 - //we create one object to read x coordinates
127.42 - //and one to read y coordinate of nodes and write them to cm NodeMap.
127.43 -
127.44 - XMap <CoordinatesMap> xreader (cm);
127.45 - YMap <CoordinatesMap> yreader (cm);
127.46 - Graph::NodeMap<double> nodedata (g);
127.47 -
127.48 - std::ifstream is(argv[1]);
127.49 -
127.50 - GraphReader<Graph> reader(is, g);
127.51 - reader.readNodeMap("coordinates_x", xreader);
127.52 - reader.readNodeMap("coordinates_y", yreader);
127.53 - reader.readNodeMap("data", nodedata);
127.54 - reader.readEdgeMap("cap", cap);
127.55 - reader.readEdgeMap("map1", map1);
127.56 - reader.readEdgeMap("map2", map2);
127.57 - reader.readEdgeMap("map3", map3);
127.58 - reader.readEdgeMap("map4", map4);
127.59 - reader.run();
127.60 -
127.61 - MapStorage ms(g);
127.62 - ms.addNodeMap("data",&nodedata);
127.63 - ms.addEdgeMap("cap",&cap);
127.64 - ms.addEdgeMap("map1",&map1);
127.65 - ms.addEdgeMap("map2",&map2);
127.66 - ms.addEdgeMap("map3",&map3);
127.67 - ms.addEdgeMap("map4",&map4);
127.68 -
127.69 - Gnome::Canvas::init();
127.70 - Gtk::Main app(argc, argv);
127.71 -
127.72 - MainWin mainwin("Displayed Graph", g, cm, ms);
127.73 - app.run(mainwin);
127.74 -
127.75 - return 0;
127.76 -}
128.1 --- a/src/gui/graph_displayer_canvas.cc Sat May 21 21:04:57 2005 +0000
128.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
128.3 @@ -1,259 +0,0 @@
128.4 -#include <graph_displayer_canvas.h>
128.5 -
128.6 -GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm, MapStorage & ms):g(gr),nodesmap(g),edgesmap(g),edgetextmap(g),displayed_graph(*(root()), 0, 0),mapstorage(ms),isbutton(false),active_item(NULL)
128.7 -{
128.8 -
128.9 - for (EdgeIt i(g); i!=INVALID; ++i)
128.10 - {
128.11 - Gnome::Canvas::Points coos;
128.12 - coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));
128.13 - coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));
128.14 -
128.15 - edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);
128.16 - *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
128.17 - edgesmap[i]->property_width_pixels().set_value(10);
128.18 -
128.19 -
128.20 - double x1, x2, y1, y2;
128.21 - edgesmap[i]->get_bounds(x1, y1, x2, y2);
128.22 -
128.23 - edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");
128.24 - edgetextmap[i]->property_fill_color().set_value("black");
128.25 - }
128.26 -
128.27 - NodeIt i(g);
128.28 - int maxx=0, maxy=0, minx=(int)cm[i].x, miny=(int)cm[i].y;
128.29 -
128.30 - for (; i!=INVALID; ++i)
128.31 - {
128.32 - if(cm[i].x>maxx)maxx=(int)cm[i].x;
128.33 - if(cm[i].y>maxy)maxy=(int)cm[i].y;
128.34 - if(cm[i].x<minx)minx=(int)cm[i].x;
128.35 - if(cm[i].y<miny)miny=(int)cm[i].y;
128.36 -
128.37 - nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
128.38 - *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
128.39 - *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
128.40 - (nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));
128.41 - }
128.42 -
128.43 - double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);
128.44 - double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);
128.45 -
128.46 - set_pixels_per_unit((biggest_x>biggest_y)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));
128.47 - std::cout<<abs(maxx)<<" "<<abs(minx)<<" big x "<<biggest_x<<" "<<abs(maxy)<<" "<<abs(miny)<<" big y "<<biggest_y<<std::endl;
128.48 - std::cout<<maxx<<" "<<minx<<" big x "<<biggest_x<<" "<<maxy<<" "<<miny<<" big y "<<biggest_y<<std::endl;
128.49 - std::cout<<"dx "<<(maxx-minx)<<" dy "<<(maxy-miny)<<" xrate "<<((maxx-minx)/WIN_WIDTH)<<" yrate "<<((maxy-miny)/WIN_HEIGHT)<<std::endl;
128.50 -
128.51 -}
128.52 -
128.53 -GraphDisplayerCanvas::~GraphDisplayerCanvas()
128.54 -{
128.55 - Graph::NodeMap <int> id(g);
128.56 - Graph::NodeMap <double> xc(g);
128.57 - Graph::NodeMap <double> yc(g);
128.58 -
128.59 - int j=1;
128.60 -
128.61 - for (NodeIt i(g); i!=INVALID; ++i)
128.62 - {
128.63 - double x1,y1,x2,y2;
128.64 - nodesmap[i]->get_bounds(x1, y1, x2, y2);
128.65 -
128.66 - id[i]=j++;
128.67 - xc[i]=(x1+x2)/2;
128.68 - yc[i]=(y1+y2)/2;
128.69 - }
128.70 -
128.71 - GraphWriter<Graph> writer(std::cout,g);
128.72 -
128.73 - writer.writeNodeMap("id", id);
128.74 - writer.writeNodeMap("coordinates_x", xc);
128.75 - writer.writeNodeMap("coordinates_y", yc);
128.76 - writer.run();
128.77 -}
128.78 -
128.79 -int GraphDisplayerCanvas::changeLineWidth (std::string mapname)
128.80 -{
128.81 - for (EdgeIt i(g); i!=INVALID; ++i)
128.82 - {
128.83 - int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];
128.84 - edgesmap[i]->property_width_pixels().set_value(w);
128.85 - }
128.86 - return 0;
128.87 -};
128.88 -
128.89 -int GraphDisplayerCanvas::changeColor (std::string mapname)
128.90 -{
128.91 - for (EdgeIt i(g); i!=INVALID; ++i)
128.92 - {
128.93 - double w=(*(mapstorage.edgemap_storage)[mapname])[i];
128.94 - double max=mapstorage.maxOfEdgeMap(mapname);
128.95 - double min=mapstorage.minOfEdgeMap(mapname);
128.96 -
128.97 - //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(w-min)/(max-min)<<std::endl;
128.98 - Gdk::Color color;
128.99 - if(max!=min)
128.100 - {
128.101 - color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
128.102 - }
128.103 - else
128.104 - {
128.105 - color.set_rgb_p (0, 100, 0);
128.106 - }
128.107 -
128.108 - edgesmap[i]->property_fill_color_gdk().set_value(color);
128.109 - }
128.110 - return 0;
128.111 -};
128.112 -
128.113 -int GraphDisplayerCanvas::changeText (std::string mapname)
128.114 -{
128.115 - for (EdgeIt i(g); i!=INVALID; ++i)
128.116 - {
128.117 - if(mapname!="Text")
128.118 - {
128.119 - double number=(*(mapstorage.edgemap_storage)[mapname])[i];
128.120 - int length=(int)(floor(log(number)/log(10)))+1;
128.121 - int maxpos=(int)(pow(10,length-1));
128.122 - int strl=length+1+RANGE;
128.123 - char * str=new char[strl];
128.124 - str[length]='.';
128.125 - str[strl]='\0';
128.126 -
128.127 - for(int j=0;j<strl;j++)
128.128 - {
128.129 - if(j!=length)
128.130 - {
128.131 - int digit=(int)(number/maxpos);
128.132 - str[j]=(digit+'0');
128.133 - number-=digit*maxpos;
128.134 - number*=10;
128.135 - }
128.136 - }
128.137 -
128.138 - edgetextmap[i]->property_text().set_value(str);
128.139 - }
128.140 - else
128.141 - {
128.142 - edgetextmap[i]->property_text().set_value("");
128.143 - }
128.144 - }
128.145 - return 0;
128.146 -};
128.147 -
128.148 -
128.149 -int GraphDisplayerCanvas::rezoom ()
128.150 -{
128.151 - double x1, x2, y1, y2;
128.152 - int x,y;
128.153 -
128.154 - NodeIt i(g);
128.155 - nodesmap[i]->get_bounds(x1, y1, x2, y2);
128.156 -
128.157 - x=(int)((x1+x2)/2);
128.158 - y=(int)((y1+y2)/2);
128.159 -
128.160 - int maxx=0, maxy=0, minx=(int)x, miny=(int)y;
128.161 -
128.162 - for (; i!=INVALID; ++i)
128.163 - {
128.164 - nodesmap[i]->get_bounds(x1, y1, x2, y2);
128.165 -
128.166 - x=(int)((x1+x2)/2);
128.167 - y=(int)((y1+y2)/2);
128.168 -
128.169 - if(x>maxx)maxx=x;
128.170 - if(y>maxy)maxy=y;
128.171 - if(x<minx)minx=x;
128.172 - if(y<miny)miny=y;
128.173 - }
128.174 -
128.175 - double biggest_x=(abs(maxx)>abs(minx))?(abs(maxx)+80):(abs(minx)+80);
128.176 - double biggest_y=(abs(maxy)>abs(miny))?(abs(maxy)+80):(abs(miny)+80);
128.177 -
128.178 - set_pixels_per_unit((biggest_x-WIN_WIDTH>biggest_y-WIN_HEIGHT)?(WIN_WIDTH/biggest_x/2):(WIN_HEIGHT/biggest_y/2));
128.179 - return 0;
128.180 -};
128.181 -
128.182 -
128.183 -///This function moves only one node of displayed_graph,
128.184 -///but recalculate the location of weight point,
128.185 -///and also redraw the sides of the planefigure.
128.186 -bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
128.187 -{
128.188 - switch(e->type)
128.189 - {
128.190 - case GDK_BUTTON_PRESS:
128.191 - clicked_x=e->button.x;
128.192 - clicked_y=e->button.y;
128.193 - active_item=(get_item_at(e->button.x, e->button.y));
128.194 - isbutton=true;
128.195 - break;
128.196 - case GDK_BUTTON_RELEASE:
128.197 - isbutton=false;
128.198 - active_item=NULL;
128.199 - break;
128.200 - case GDK_MOTION_NOTIFY:
128.201 - if(isbutton)
128.202 - {
128.203 - double dx=e->motion.x-clicked_x;
128.204 - double dy=e->motion.y-clicked_y;
128.205 - active_item->move(dx, dy);
128.206 - clicked_x=e->motion.x;
128.207 - clicked_y=e->motion.y;
128.208 -
128.209 - EdgeIt e;
128.210 -
128.211 - g.firstOut(e,n);
128.212 - for(;e!=INVALID;g.nextOut(e))
128.213 - {
128.214 - Gnome::Canvas::Points coos;
128.215 - double x1, x2, y1, y2;
128.216 -
128.217 - nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
128.218 - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
128.219 -
128.220 - nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
128.221 - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
128.222 -
128.223 - edgesmap[e]->property_points().set_value(coos);
128.224 -
128.225 - edgesmap[e]->get_bounds(x1, y1, x2, y2);
128.226 -
128.227 - edgetextmap[e]->property_x().set_value((x1+x2)/2);
128.228 - edgetextmap[e]->property_y().set_value((y1+y2)/2);
128.229 - }
128.230 -
128.231 - g.firstIn(e,n);
128.232 - for(;e!=INVALID;g.nextIn(e))
128.233 - {
128.234 - Gnome::Canvas::Points coos;
128.235 - double x1, x2, y1, y2;
128.236 -
128.237 - nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
128.238 - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
128.239 -
128.240 - nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
128.241 - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
128.242 -
128.243 - edgesmap[e]->property_points().set_value(coos);
128.244 -
128.245 - edgesmap[e]->get_bounds(x1, y1, x2, y2);
128.246 -
128.247 - edgetextmap[e]->property_x().set_value((x1+x2)/2);
128.248 - edgetextmap[e]->property_y().set_value((y1+y2)/2);
128.249 - }
128.250 - }
128.251 - default: break;
128.252 - }
128.253 - return true;
128.254 -}
128.255 -
128.256 -bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
128.257 -{
128.258 - Gnome::Canvas::CanvasAA::on_expose_event(event);
128.259 - //usleep(10000);
128.260 - //rezoom();
128.261 - return true;
128.262 -}
129.1 --- a/src/gui/graph_displayer_canvas.h Sat May 21 21:04:57 2005 +0000
129.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
129.3 @@ -1,65 +0,0 @@
129.4 -// -*- C++ -*- //
129.5 -
129.6 -#ifndef GRAPH_DISPLAYER_CANVAS_H
129.7 -#define GRAPH_DISPLAYER_CANVAS_H
129.8 -
129.9 -#include <all_include.h>
129.10 -#include <mapstorage.h>
129.11 -#include <libgnomecanvasmm.h>
129.12 -#include <libgnomecanvasmm/polygon.h>
129.13 -
129.14 -class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
129.15 -{
129.16 - typedef Gnome::Canvas::CanvasAA Parent;
129.17 -
129.18 -public:
129.19 - GraphDisplayerCanvas(Graph &, CoordinatesMap &, MapStorage &);
129.20 - virtual ~GraphDisplayerCanvas();
129.21 -
129.22 - int changeLineWidth (std::string mapname);
129.23 - int changeColor (std::string mapname);
129.24 - int changeText (std::string mapname);
129.25 - int rezoom();
129.26 -
129.27 -protected:
129.28 -
129.29 - virtual bool on_expose_event(GdkEventExpose *);
129.30 -
129.31 -private:
129.32 -
129.33 - ///Event handler function that handles dragging nodes of displayed_graph
129.34 - bool event_handler(GdkEvent* e, Node n);
129.35 -
129.36 - ///The graph, on which we work
129.37 - Graph g;
129.38 - ///Map of nodes of planefigure
129.39 - Graph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
129.40 - ///Map of edges of planefigure
129.41 - Graph::EdgeMap<Gnome::Canvas::Line *> edgesmap;
129.42 -
129.43 - ///Map of texts to write on edges
129.44 - Graph::EdgeMap<Gnome::Canvas::Text *> edgetextmap;
129.45 -
129.46 - ///Group of graphical elements of displayed_graph
129.47 - Gnome::Canvas::Group displayed_graph;
129.48 -
129.49 - ///Here we store the maps that can be displayed through properties.
129.50 - MapStorage mapstorage;
129.51 -
129.52 - ///Indicates whether the button of mouse is pressed or not
129.53 - bool isbutton;
129.54 -
129.55 - ///At this location was the mousebutton pressed.
129.56 - ///It helps to calculate the distance of dragging.
129.57 - double clicked_x, clicked_y;
129.58 -
129.59 - ///Remembers which Gnome::Canvas::Item was pressed.
129.60 - ///this variable is needed, because
129.61 - ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
129.62 - ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
129.63 - Gnome::Canvas::Item * active_item;
129.64 -
129.65 -
129.66 -};
129.67 -
129.68 -#endif //GRAPH_DISPLAYER_CANVAS_H
130.1 --- a/src/gui/graphocska.lgf Sat May 21 21:04:57 2005 +0000
130.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
130.3 @@ -1,39 +0,0 @@
130.4 -@nodeset
130.5 -id coordinates_x coordinates_y data
130.6 -1 230 -80 1
130.7 -2 230 100 3
130.8 -3 120 -80 5
130.9 -4 120 100 7
130.10 -5 20 100 9
130.11 -6 20 -80 11
130.12 -7 -40 10 13
130.13 -8 -100 100 15
130.14 -9 -100 10 17
130.15 -10 -100 -80 19
130.16 -11 -200 -80 21
130.17 -12 -200 10 23
130.18 -13 -200 100 25
130.19 -14 -300 100 27
130.20 -15 -300 -80 29
130.21 -
130.22 -@edgeset
130.23 - cap map1 map2 map3 map4
130.24 -15 14 1 21 111 231 3
130.25 -14 13 2 22 112 232 6
130.26 -13 12 3 23 113 233 9
130.27 -13 8 4 24 114 234 12
130.28 -12 11 5 25 115 235 15
130.29 -12 9 6 26 116 236 18
130.30 -11 10 7 27 117 237 21
130.31 -10 9 8 28 118 238 24
130.32 -10 7 9 29 119 239 27
130.33 -9 8 10 30 120 230 30
130.34 -7 6 11 31 121 241 33
130.35 -6 5 12 32 122 242 36
130.36 -6 3 13 33 123 243 39
130.37 -5 4 14 34 124 244 42
130.38 -4 3 15 35 125 245 45
130.39 -3 2 16 36 126 246 48
130.40 -2 1 17 37 127 247 51
130.41 -
130.42 -@end
130.43 \ No newline at end of file
131.1 --- a/src/gui/main_win.cc Sat May 21 21:04:57 2005 +0000
131.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
131.3 @@ -1,69 +0,0 @@
131.4 -#include <main_win.h>
131.5 -
131.6 -MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm, MapStorage & ms):mapwin("Map Setup", ms, gd_canvas),gd_canvas(graph, cm, ms)
131.7 -{
131.8 - set_title (title);
131.9 - set_default_size(WIN_WIDTH,WIN_HEIGHT);
131.10 - add(vbox);
131.11 -
131.12 - ag=Gtk::ActionGroup::create();
131.13 - ag->add( Gtk::Action::create("ShowMenu", "_Show") );
131.14 - ag->add( Gtk::Action::create("ShowMaps", "_Maps"), sigc::mem_fun(*this, &MainWin::showMaps));
131.15 - ag->add( Gtk::Action::create("FileMenu", "_File") );
131.16 - ag->add( Gtk::Action::create("FileQuit", "_Quit"), sigc::mem_fun(*this, &MainWin::quit));
131.17 - ag->add( Gtk::Action::create("ZoomMenu", "_Zoom") );
131.18 - ag->add( Gtk::Action::create("ZoomRezoom", "_Rezoom"), sigc::mem_fun(*this, &MainWin::rezoom)); //!!!!!!
131.19 -
131.20 - uim=Gtk::UIManager::create();
131.21 - uim->insert_action_group(ag);
131.22 - add_accel_group(uim->get_accel_group());
131.23 -
131.24 - try
131.25 - {
131.26 -
131.27 - Glib::ustring ui_info =
131.28 - "<ui>"
131.29 - " <menubar name='MenuBar'>"
131.30 - " <menu action='FileMenu'>"
131.31 - " <menuitem action='FileQuit'/>"
131.32 - " </menu>"
131.33 - " <menu action='ShowMenu'>"
131.34 - " <menuitem action='ShowMaps'/>"
131.35 - " </menu>"
131.36 - " <menu action='ZoomMenu'>"
131.37 - " <menuitem action='ZoomRezoom'/>"
131.38 - " </menu>"
131.39 - " </menubar>"
131.40 - "</ui>";
131.41 -
131.42 - uim->add_ui_from_string(ui_info);
131.43 -
131.44 - }
131.45 - catch(const Glib::Error& ex)
131.46 - {
131.47 - std::cerr << "building menus failed: " << ex.what();
131.48 - }
131.49 -
131.50 - Gtk::Widget* menubar = uim->get_widget("/MenuBar");
131.51 - if(menubar)vbox.pack_start(*menubar, Gtk::PACK_SHRINK);
131.52 -
131.53 - vbox.pack_start(gd_canvas);
131.54 -
131.55 - show_all_children();
131.56 -}
131.57 -
131.58 -void MainWin::showMaps()
131.59 -{
131.60 - mapwin.show();
131.61 -}
131.62 -
131.63 -void MainWin::quit()
131.64 -{
131.65 - hide();
131.66 -}
131.67 -
131.68 -void MainWin::rezoom()
131.69 -{
131.70 - gd_canvas.rezoom();
131.71 -}
131.72 -
132.1 --- a/src/gui/main_win.h Sat May 21 21:04:57 2005 +0000
132.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
132.3 @@ -1,44 +0,0 @@
132.4 -// -*- C++ -*- //
132.5 -
132.6 -#ifndef MAIN_WIN_H
132.7 -#define MAIN_WIN_H
132.8 -
132.9 -#include <all_include.h>
132.10 -#include <mapstorage.h>
132.11 -#include <map_win.h>
132.12 -#include <libgnomecanvasmm.h>
132.13 -#include <libgnomecanvasmm/polygon.h>
132.14 -
132.15 -class MainWin : public Gtk::Window
132.16 -{
132.17 -public:
132.18 - MainWin(const std::string& title, Graph &, CoordinatesMap &, MapStorage &);
132.19 -
132.20 -protected:
132.21 - //Window of map-showing setup
132.22 - MapWin mapwin;
132.23 -
132.24 - //Member widgets:
132.25 - GraphDisplayerCanvas gd_canvas;
132.26 -
132.27 - //ActionGroup for menu
132.28 - Glib::RefPtr<Gtk::ActionGroup> ag;
132.29 -
132.30 - //UIManager for menu
132.31 - Glib::RefPtr<Gtk::UIManager> uim;
132.32 -
132.33 - //Container
132.34 - Gtk::VBox vbox;
132.35 -
132.36 - //Pops up map-setup window
132.37 - virtual void showMaps();
132.38 -
132.39 - //Exit
132.40 - virtual void quit();
132.41 -
132.42 - //Refit screen
132.43 - virtual void rezoom();
132.44 -
132.45 -};
132.46 -
132.47 -#endif //MAIN_WIN_H
133.1 --- a/src/gui/map_win.cc Sat May 21 21:04:57 2005 +0000
133.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
133.3 @@ -1,116 +0,0 @@
133.4 -#include <map_win.h>
133.5 -#include <set>
133.6 -
133.7 -MapWin::MapWin(const std::string& title, MapStorage & mapst, GraphDisplayerCanvas & grdispc):gdc(grdispc),ms(mapst)
133.8 -{
133.9 - set_title(title);
133.10 - set_default_size(400, 200);
133.11 -
133.12 - rb_array=new Gtk::RadioButton * [PROPERTY_NUM];
133.13 - vbox_r1=new Gtk::VBox[PROPERTY_NUM];
133.14 - vbox_r2=new Gtk::VBox[PROPERTY_NUM];
133.15 - radios=new Gtk::HBox[PROPERTY_NUM];
133.16 - for(int i=0;i<PROPERTY_NUM;i++)
133.17 - {
133.18 - rb_array[i]=new Gtk::RadioButton[ms.numOfEdgeMaps()+1];
133.19 -
133.20 - Gtk::RadioButton::Group group;
133.21 -
133.22 - std::map< std::string,Graph::EdgeMap<double> * >::iterator emsi=ms.beginOfEdgeMaps();
133.23 - std::set<int> props;
133.24 -
133.25 - int actprop;
133.26 - for(int j=0;j<ms.numOfEdgeMaps();j++)
133.27 - {
133.28 -
133.29 - if(emsi->second==&(ms.default_edgemaps[i]))
133.30 - {
133.31 - actprop=j;
133.32 - }
133.33 - for(int k=0;k<PROPERTY_NUM;k++)
133.34 - {
133.35 - if(emsi->second==&(ms.default_edgemaps[k]))
133.36 - {
133.37 - props.insert(j);
133.38 - }
133.39 - }
133.40 - emsi++;
133.41 - }
133.42 -
133.43 - rb_array[i][0].set_group(group);
133.44 - rb_array[i][0].set_label("Default");
133.45 - rb_array[i][0].signal_clicked().connect( sigc::bind( sigc::bind( sigc::mem_fun(*this, &MapWin::radio_click), 0), i) );
133.46 - vbox_r1[i].pack_start(rb_array[i][0]);
133.47 -
133.48 -
133.49 - emsi=ms.beginOfEdgeMaps();
133.50 - int actpos=1;
133.51 - for(int j=0;j<ms.numOfEdgeMaps();j++)
133.52 - {
133.53 - if( ( props.find(j) )==( props.end() ) )
133.54 - {
133.55 - rb_array[i][actpos].set_group(group);
133.56 - rb_array[i][actpos].set_label(emsi->first);
133.57 - rb_array[i][actpos].signal_clicked().connect
133.58 - (
133.59 - sigc::bind(
133.60 - sigc::bind(
133.61 - sigc::mem_fun(*this, &MapWin::radio_click),
133.62 - actpos
133.63 - ),
133.64 - i
133.65 - )
133.66 - );
133.67 -
133.68 - if(actpos<(ms.numOfEdgeMaps()-PROPERTY_NUM+1)/2)
133.69 - {
133.70 - vbox_r1[i].pack_start(rb_array[i][actpos]);
133.71 - }
133.72 - else
133.73 - {
133.74 - vbox_r2[i].pack_start(rb_array[i][actpos]);
133.75 - }
133.76 - actpos++;
133.77 - }
133.78 - emsi++;
133.79 - }
133.80 - radios[i].pack_start(vbox_r1[i]);
133.81 - radios[i].pack_start(vbox_r2[i]);
133.82 - notebook.append_page(radios[i], property_strings[i]);
133.83 - }
133.84 -
133.85 - add(vbox_b);
133.86 - vbox_b.pack_start(notebook);
133.87 -
133.88 - show_all_children();
133.89 -
133.90 -}
133.91 -
133.92 -void MapWin::radio_click(int prop, int actpos)
133.93 -{
133.94 - if(rb_array[prop][actpos].get_active())
133.95 - {
133.96 -
133.97 - std::string mapname=rb_array[prop][actpos].get_label();
133.98 -
133.99 - if(mapname=="Default")
133.100 - {
133.101 - mapname=property_strings[prop];
133.102 - }
133.103 -
133.104 - switch(prop)
133.105 - {
133.106 - case WIDTH:
133.107 - gdc.changeLineWidth(mapname);
133.108 - break;
133.109 - case COLOR:
133.110 - gdc.changeColor(mapname);
133.111 - break;
133.112 - case TEXT:
133.113 - gdc.changeText(mapname);
133.114 - break;
133.115 - default:
133.116 - std::cout<<"Error\n";
133.117 - }
133.118 - }
133.119 -};
134.1 --- a/src/gui/map_win.h Sat May 21 21:04:57 2005 +0000
134.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
134.3 @@ -1,30 +0,0 @@
134.4 -// -*- C++ -*- //
134.5 -
134.6 -#ifndef MAP_WIN_H
134.7 -#define MAP_WIN_H
134.8 -
134.9 -#include <all_include.h>
134.10 -#include <mapstorage.h>
134.11 -#include <graph_displayer_canvas.h>
134.12 -#include <libgnomecanvasmm.h>
134.13 -#include <libgnomecanvasmm/polygon.h>
134.14 -
134.15 -class MapWin : public Gtk::Window
134.16 -{
134.17 -protected:
134.18 - GraphDisplayerCanvas & gdc;
134.19 - MapStorage & ms;
134.20 -
134.21 - Gtk::HBox * radios;
134.22 - Gtk::RadioButton ** rb_array;
134.23 -
134.24 - Gtk::VBox vbox_b, * vbox_r1, * vbox_r2;
134.25 - Gtk::Notebook notebook;
134.26 - Gtk::Label * labels;
134.27 -
134.28 -public:
134.29 - MapWin(const std::string& title, MapStorage &, GraphDisplayerCanvas &);
134.30 - virtual void radio_click(int, int);
134.31 -};
134.32 -
134.33 -#endif //MAP_WIN_H
135.1 --- a/src/gui/mapstorage.cc Sat May 21 21:04:57 2005 +0000
135.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
135.3 @@ -1,89 +0,0 @@
135.4 -#include <mapstorage.h>
135.5 -
135.6 -MapStorage::MapStorage(Graph & graph):g(graph)
135.7 -{
135.8 - for(int i=0;i<PROPERTY_NUM;i++)
135.9 - {
135.10 - Graph::EdgeMap<double> emd(g);
135.11 - default_edgemaps.push_back(emd);
135.12 - Graph::NodeMap<double> nmd(g);
135.13 - default_nodemaps.push_back(nmd);
135.14 - }
135.15 -
135.16 - //std::string defaultstr="Default ";
135.17 - for(int i=0;i<PROPERTY_NUM;i++)
135.18 - {
135.19 - for (EdgeIt j(g); j!=INVALID; ++j)
135.20 - {
135.21 - (default_edgemaps[i])[j]=property_defaults[i];
135.22 - }
135.23 - addEdgeMap(property_strings[i],&(default_edgemaps[i]));
135.24 - }
135.25 -
135.26 -};
135.27 -
135.28 -int MapStorage::addNodeMap(const std::string & name, Graph::NodeMap<double> *nodemap)
135.29 -{
135.30 - nodemap_storage[name]=nodemap;
135.31 - return 0;
135.32 -}
135.33 -int MapStorage::addEdgeMap(const std::string & name, Graph::EdgeMap<double> *edgemap)
135.34 -{
135.35 - edgemap_storage[name]=edgemap;
135.36 - return 0;
135.37 -}
135.38 -
135.39 -double MapStorage::maxOfNodeMap(const std::string & name)
135.40 -{
135.41 - double max=0;
135.42 - for (NodeIt j(g); j!=INVALID; ++j)
135.43 - {
135.44 - if( (*nodemap_storage[name])[j]>max )
135.45 - {
135.46 - max=(*nodemap_storage[name])[j];
135.47 - }
135.48 - }
135.49 - return max;
135.50 -}
135.51 -
135.52 -double MapStorage::maxOfEdgeMap(const std::string & name)
135.53 -{
135.54 - double max=0;
135.55 - for (EdgeIt j(g); j!=INVALID; ++j)
135.56 - {
135.57 - if( (*edgemap_storage[name])[j]>max )
135.58 - {
135.59 - max=(*edgemap_storage[name])[j];
135.60 - }
135.61 - }
135.62 - return max;
135.63 -}
135.64 -
135.65 -double MapStorage::minOfNodeMap(const std::string & name)
135.66 -{
135.67 - NodeIt j(g);
135.68 - double min=(*nodemap_storage[name])[j];
135.69 - for (; j!=INVALID; ++j)
135.70 - {
135.71 - if( (*nodemap_storage[name])[j]<min )
135.72 - {
135.73 - min=(*nodemap_storage[name])[j];
135.74 - }
135.75 - }
135.76 - return min;
135.77 -}
135.78 -
135.79 -double MapStorage::minOfEdgeMap(const std::string & name)
135.80 -{
135.81 - EdgeIt j(g);
135.82 - double min=(*edgemap_storage[name])[j];
135.83 - for (EdgeIt j(g); j!=INVALID; ++j)
135.84 - {
135.85 - if( (*edgemap_storage[name])[j]<min )
135.86 - {
135.87 - min=(*edgemap_storage[name])[j];
135.88 - }
135.89 - }
135.90 - return min;
135.91 -}
135.92 -
136.1 --- a/src/gui/mapstorage.h Sat May 21 21:04:57 2005 +0000
136.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
136.3 @@ -1,37 +0,0 @@
136.4 -// -*- C++ -*- //
136.5 -
136.6 -#ifndef MAPSTORAGE_H
136.7 -#define MAPSTORAGE_H
136.8 -
136.9 -#include <all_include.h>
136.10 -
136.11 -class MapStorage
136.12 -{
136.13 -
136.14 -public: ///!!!!!!!!
136.15 - Graph g;
136.16 - std::map< std::string,Graph::NodeMap<double> * > nodemap_storage;
136.17 - std::map< std::string,Graph::EdgeMap<double> * > edgemap_storage;
136.18 -
136.19 - std::vector<Graph::NodeMap<double> > default_nodemaps;
136.20 - std::vector<Graph::EdgeMap<double> > default_edgemaps;
136.21 -
136.22 -public:
136.23 - MapStorage(Graph &);
136.24 - int addNodeMap(const std::string &,Graph::NodeMap<double> *);
136.25 - int addEdgeMap(const std::string &,Graph::EdgeMap<double> *);
136.26 -
136.27 - int numOfNodeMaps() {return nodemap_storage.size();};
136.28 - int numOfEdgeMaps() {return edgemap_storage.size();};
136.29 -
136.30 - double maxOfNodeMap(const std::string &);
136.31 - double maxOfEdgeMap(const std::string &);
136.32 -
136.33 - double minOfNodeMap(const std::string &);
136.34 - double minOfEdgeMap(const std::string &);
136.35 -
136.36 - std::map< std::string,Graph::NodeMap<double> * >::iterator beginOfNodeMaps(){return nodemap_storage.begin();};
136.37 - std::map< std::string,Graph::EdgeMap<double> * >::iterator beginOfEdgeMaps(){return edgemap_storage.begin();};
136.38 -};
136.39 -
136.40 -#endif //MAPSTORAGE_H
137.1 --- a/src/gui/xml.h Sat May 21 21:04:57 2005 +0000
137.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
137.3 @@ -1,442 +0,0 @@
137.4 -/* -*- C++ -*- */
137.5 -
137.6 -#include <iostream>
137.7 -#include <string>
137.8 -#include <vector>
137.9 -#include <list>
137.10 -#include <map>
137.11 -#include <lemon/xy.h>
137.12 -
137.13 -class XmlWriter
137.14 -{
137.15 - std::ostream& os;
137.16 - int level;
137.17 -
137.18 -protected:
137.19 - void indent(int level) {
137.20 - os << std::endl;
137.21 - for(int i=0;i<level;i++) os << ' ';
137.22 - }
137.23 - void tag(const std::string &_tag) {
137.24 - os << '<' << _tag << '>';
137.25 - }
137.26 - void etag(const std::string &_tag) {
137.27 - os << "</" << _tag << '>';
137.28 - }
137.29 - void itag(const std::string &_tag) { indent();tag(_tag); }
137.30 - void ietag(const std::string &_tag) { indent();etag(_tag); }
137.31 -
137.32 - void beginTag(const std::string &_tag) {
137.33 - itag(_tag);
137.34 - level++;
137.35 - }
137.36 - void endTag(const std::string &_tag) {
137.37 - level--;
137.38 - ietag(_tag);
137.39 - }
137.40 -
137.41 -public:
137.42 -
137.43 - void indent()
137.44 - {
137.45 - if(level>=0) indent(level);
137.46 - else level=0;
137.47 - }
137.48 -
137.49 - ///\e
137.50 -
137.51 - ///\e
137.52 - ///
137.53 - class ContTag
137.54 - {
137.55 - XmlWriter &ix;
137.56 - const std::string _tag;
137.57 - public:
137.58 - ///\e
137.59 -
137.60 - ///\e
137.61 - ///
137.62 - ContTag(XmlWriter &_ix,const std::string &_t) :
137.63 - ix(_ix), _tag(_t)
137.64 - {
137.65 - ix.tag(_tag);
137.66 - }
137.67 - ~ContTag() { ix.etag(_tag);}
137.68 - };
137.69 -
137.70 - class LineTag
137.71 - {
137.72 - XmlWriter &ix;
137.73 - const std::string _tag;
137.74 - public:
137.75 - ///\e
137.76 -
137.77 - ///\e
137.78 - ///
137.79 - LineTag(XmlWriter &_ix,const std::string &_t) :
137.80 - ix(_ix), _tag(_t)
137.81 - {
137.82 - ix.itag(_tag);
137.83 - }
137.84 - ~LineTag() { ix.etag(_tag);}
137.85 - };
137.86 -
137.87 - ///\e
137.88 -
137.89 - ///\e
137.90 - ///
137.91 - class Tag
137.92 - {
137.93 - XmlWriter &ix;
137.94 - const std::string _tag;
137.95 - public:
137.96 - ///\e
137.97 -
137.98 - ///\e
137.99 - ///
137.100 - Tag(XmlWriter &_ix,const std::string &_t) :
137.101 - ix(_ix), _tag(_t)
137.102 - {
137.103 - ix.beginTag(_tag);
137.104 - }
137.105 - ~Tag() {
137.106 - ix.endTag(_tag);
137.107 - }
137.108 - };
137.109 -
137.110 - ///\e
137.111 -
137.112 - ///\e
137.113 - ///
137.114 - XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
137.115 - ~XmlWriter() { os<< std::endl; }
137.116 -
137.117 - XmlWriter &operator()(int v)
137.118 - {
137.119 - if(!(os << v)) throw (std::ios::failure ("data format error"));
137.120 - return *this;
137.121 - }
137.122 - XmlWriter &operator()(const std::string &_tag,int v)
137.123 - {
137.124 - LineTag t(*this,_tag);
137.125 - if(!(os << v)) throw (std::ios::failure ("data format error"));
137.126 - return *this;
137.127 - }
137.128 - XmlWriter &operator()(const std::string &_tag,double v)
137.129 - {
137.130 - LineTag t(*this,_tag);
137.131 - if(os << v) throw (std::ios::failure ("data format error"));
137.132 - return *this;
137.133 - }
137.134 - XmlWriter &operator()(double v)
137.135 - {
137.136 - os << v;
137.137 - return *this;
137.138 - }
137.139 - XmlWriter &operator()(const std::string &v)
137.140 - {
137.141 - for(std::string::const_iterator i=v.begin();i!=v.end();++i)
137.142 - switch(*i) {
137.143 - case '\\':
137.144 - os << "\\\\";
137.145 - break;
137.146 - case '<':
137.147 - os << "\\<";
137.148 - break;
137.149 - case '&':
137.150 - os << "\\&";
137.151 - break;
137.152 - case '\n':
137.153 - os << "\\n";
137.154 - break;
137.155 - default:
137.156 - os<<*i;
137.157 - break;
137.158 - }
137.159 - return *this;
137.160 - }
137.161 - XmlWriter &operator()(const std::string &_tag,const std::string &v)
137.162 - {
137.163 - LineTag t(*this,_tag);
137.164 - (*this)(v);
137.165 - return *this;
137.166 - }
137.167 - ///\e
137.168 -
137.169 - ///\e
137.170 - ///
137.171 - template<class V>
137.172 - XmlWriter &operator()(const std::string &_tag,const V &v)
137.173 - {
137.174 - Tag t(*this,_tag);
137.175 - out(*this,v);
137.176 - return *this;
137.177 - }
137.178 - ///\e
137.179 -
137.180 - ///\e
137.181 - ///
137.182 - template<class V>
137.183 - XmlWriter &operator()(const V &v)
137.184 - {
137.185 - out(*this,v);
137.186 - return *this;
137.187 - }
137.188 -};
137.189 -
137.190 -//////////////////////////////////////////////////////////////////////
137.191 -
137.192 -class XmlReader
137.193 -{
137.194 - std::istream& is;
137.195 -
137.196 - std::string next_tag;
137.197 - void skipWhiteSpaces()
137.198 - {
137.199 - char c;
137.200 - while (is.get(c) && std::isspace(c,is.getloc()));
137.201 - is.unget();
137.202 - }
137.203 -protected:
137.204 - ///\e
137.205 -
137.206 - ///\e
137.207 - ///
137.208 - void useTag() {next_tag.clear();}
137.209 -
137.210 - void useTag(const std::string &_tag) {
137.211 - if(nextTag()==_tag) useTag();
137.212 - else throw (std::ios::failure ("data format error"));
137.213 - }
137.214 -public:
137.215 - ///\e
137.216 -
137.217 - ///\e
137.218 - ///
137.219 - const std::string &nextTag()
137.220 - {
137.221 - if(next_tag.empty()) {
137.222 - char c;
137.223 - skipWhiteSpaces();
137.224 - if(!is.get(c) || c!='<')
137.225 - throw (std::ios::failure ("data format error"));
137.226 - next_tag.clear();
137.227 - while (is.get(c) && c!='>') next_tag.push_back(c);
137.228 - if(c!='>')
137.229 - throw (std::ios::failure ("data format error"));
137.230 - }
137.231 - return next_tag;
137.232 - }
137.233 -
137.234 - ///\e
137.235 -
137.236 - ///\e
137.237 - ///
137.238 - class Tag
137.239 - {
137.240 - XmlReader &ix;
137.241 - const std::string tag;
137.242 - public:
137.243 - ///\e
137.244 -
137.245 - ///\e
137.246 - ///
137.247 - Tag(XmlReader &_ix,const std::string &_tag) :
137.248 - ix(_ix), tag(_tag)
137.249 - {
137.250 - ix.useTag(_tag);
137.251 - }
137.252 - ~Tag() {
137.253 - if(!std::uncaught_exception())
137.254 - ix.useTag('/'+tag);
137.255 - }
137.256 - };
137.257 -
137.258 - ///\e
137.259 -
137.260 - ///\e
137.261 - ///
137.262 - XmlReader(std::istream& _is) : is(_is) {}
137.263 -
137.264 - int operator()(const std::string &tag,int &v)
137.265 - {
137.266 - Tag t(*this,tag);
137.267 - if(!(is >> v)) throw (std::ios::failure ("data format error"));
137.268 - return v;
137.269 - }
137.270 - double operator()(const std::string &tag,double &v)
137.271 - {
137.272 - Tag t(*this,tag);
137.273 - if(!(is >> v)) throw (std::ios::failure ("data format error"));
137.274 - return v;
137.275 - }
137.276 - std::string &operator()(const std::string &tag,std::string &v)
137.277 - {
137.278 - Tag t(*this,tag);
137.279 - v.clear();
137.280 - char c;
137.281 - while (is.get(c) && c!='<')
137.282 - if(c=='\\')
137.283 - if(!is.get(c)) throw (std::ios::failure ("data format error"));
137.284 - else switch(c) {
137.285 - case 'n':
137.286 - v.push_back('\n');
137.287 - break;
137.288 - default:
137.289 - v.push_back(c);
137.290 - break;
137.291 - }
137.292 - else v.push_back(c);
137.293 - if(c!='<')
137.294 - throw (std::ios::failure ("data format error"));
137.295 - is.unget();
137.296 - return v;
137.297 - }
137.298 - ///\e
137.299 -
137.300 - ///\e
137.301 - ///
137.302 - template<class V>
137.303 - V &operator()(const std::string &tag,V &v)
137.304 - {
137.305 - Tag t(*this,tag);
137.306 - in(*this,v);
137.307 - return v;
137.308 - }
137.309 - ///\e
137.310 -
137.311 - ///\e
137.312 - ///
137.313 - template<class V>
137.314 - V &operator()(V &v)
137.315 - {
137.316 - in(*this,v);
137.317 - return v;
137.318 - }
137.319 - ///\e
137.320 -
137.321 - ///\e
137.322 - ///
137.323 - template<class V>
137.324 - V load(const std::string &tag)
137.325 - {
137.326 - Tag t(*this,tag);
137.327 - V v;
137.328 - (*this)(tag,v);
137.329 - return v;
137.330 - }
137.331 -};
137.332 -
137.333 -//////////////////////////////////////////////////////////////////////
137.334 -
137.335 -template<class A,class B>
137.336 -void out(XmlWriter &i,const std::pair<A,B> &v)
137.337 -{
137.338 - i("first",v.first);
137.339 - i("second",v.second);
137.340 -}
137.341 -
137.342 -template<class A,class B>
137.343 -void in(XmlReader &i,std::pair<A,B> &v)
137.344 -{
137.345 - i("first",v.first);
137.346 - i("second",v.second);
137.347 -}
137.348 -
137.349 -//////////////////////////////
137.350 -
137.351 -template<class T>
137.352 -void out(XmlWriter &i,const std::list<T> &v)
137.353 -{
137.354 - for(typename std::list<T>::const_iterator it=v.begin();
137.355 - it!=v.end();++it) i("item",*it);
137.356 -}
137.357 -
137.358 -template<class T>
137.359 -void in(XmlReader &i,std::list<T> &v)
137.360 -{
137.361 - while(i.nextTag()=="item")
137.362 - {
137.363 - v.push_back(T());
137.364 - i("item",v.back());
137.365 - }
137.366 -}
137.367 -
137.368 -//////////////////////////////
137.369 -
137.370 -template<class T>
137.371 -void out(XmlWriter &i,const std::vector<T> &v)
137.372 -{
137.373 - for(typename std::vector<T>::const_iterator it=v.begin();
137.374 - it!=v.end();++it) i("item",*it);
137.375 -}
137.376 -
137.377 -template<class T>
137.378 -void in(XmlReader &i,std::vector<T> &v)
137.379 -{
137.380 - while(i.nextTag()=="item")
137.381 - {
137.382 - v.push_back(T());
137.383 - i("item",v.back());
137.384 - }
137.385 -}
137.386 -
137.387 -//////////////////////////////
137.388 -
137.389 -template<class K,class V>
137.390 -void out(XmlWriter &i,const std::map<K,V> &v)
137.391 -{
137.392 - for(typename std::map<K,V>::const_iterator it=v.begin();
137.393 - it!=v.end();++it) i("item",*it);
137.394 -}
137.395 -
137.396 -template<class K,class V>
137.397 -void in(XmlReader &i,std::map<K,V> &v)
137.398 -{
137.399 - while(i.nextTag()=="item")
137.400 - {
137.401 - typename std::map<K,V>::value_type it;
137.402 - i("item",it);
137.403 - v.insert(it);
137.404 - }
137.405 -}
137.406 -
137.407 -//////////////////////////////
137.408 -
137.409 -template<class T>
137.410 -void out(XmlWriter &i,const lemon::xy<T> &v)
137.411 -{
137.412 -// i("x",v.x);
137.413 -// i("y",v.y);
137.414 - { XmlWriter::LineTag t(i,"x"); i(v.x); }
137.415 - { XmlWriter::ContTag t(i,"y"); i(v.y); }
137.416 -}
137.417 -
137.418 -template<class T>
137.419 -void in(XmlReader &i,lemon::xy<T> &v)
137.420 -{
137.421 - i("x",v.x);
137.422 - i("y",v.y);
137.423 -}
137.424 -
137.425 -//////////////////////////////
137.426 -
137.427 -template<class T>
137.428 -void out(XmlWriter &i,const lemon::BoundingBox<T> &v)
137.429 -{
137.430 - if(!v.empty()) {
137.431 - i("point",v.bottomLeft());
137.432 - if(v.bottomLeft()!=v.topRight()) i("point",v.topRight());
137.433 - }
137.434 -}
137.435 -
137.436 -template<class T>
137.437 -void in(XmlReader &i,lemon::BoundingBox<T> &v)
137.438 -{
137.439 - v.clear();
137.440 - while(i.nextTag()=="point") {
137.441 - lemon::xy<T> co;
137.442 - i("point",co);
137.443 - v+=co;
137.444 - }
137.445 -}
138.1 --- a/src/lemon/Makefile.am Sat May 21 21:04:57 2005 +0000
138.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
138.3 @@ -1,81 +0,0 @@
138.4 -AM_CPPFLAGS = -I$(top_srcdir)/src
138.5 -
138.6 -pkgconfigdir = $(libdir)/pkgconfig
138.7 -pkgconfig_DATA = lemon.pc
138.8 -
138.9 -lib_LTLIBRARIES = libemon.la
138.10 -
138.11 -libemon_la_SOURCES = \
138.12 - lp_base.cc \
138.13 - lp_skeleton.cc
138.14 -libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
138.15 -libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS)
138.16 -
138.17 -if HAVE_GLPK
138.18 -libemon_la_SOURCES += lp_glpk.cc
138.19 -endif
138.20 -
138.21 -if HAVE_CPLEX
138.22 -libemon_la_SOURCES += lp_cplex.cc
138.23 -endif
138.24 -
138.25 -nobase_pkginclude_HEADERS = \
138.26 - bezier.h \
138.27 - bfs.h \
138.28 - dfs.h \
138.29 - bin_heap.h \
138.30 - config.h \
138.31 - dijkstra.h \
138.32 - dimacs.h \
138.33 - error.h \
138.34 - fib_heap.h \
138.35 - full_graph.h \
138.36 - graph_adaptor.h \
138.37 - graph_utils.h \
138.38 - graph_to_eps.h \
138.39 - invalid.h \
138.40 - kruskal.h \
138.41 - list_graph.h \
138.42 - lp_base.h \
138.43 - lp_cplex.h \
138.44 - lp_glpk.h \
138.45 - lp_skeleton.h \
138.46 - maps.h \
138.47 - max_matching.h \
138.48 - min_cost_flow.h \
138.49 - suurballe.h \
138.50 - preflow.h \
138.51 - path.h \
138.52 - radix_heap.h \
138.53 - smart_graph.h \
138.54 - time_measure.h \
138.55 - unionfind.h \
138.56 - xy.h \
138.57 - concept_check.h \
138.58 - utility.h \
138.59 - lemon_reader.h \
138.60 - lemon_writer.h \
138.61 - graph_reader.h \
138.62 - graph_writer.h \
138.63 - bits/alteration_notifier.h \
138.64 - bits/map_iterator.h \
138.65 - bits/array_map.h \
138.66 - bits/default_map.h \
138.67 - bits/extended_pair.h \
138.68 - bits/vector_map.h \
138.69 - bits/iterable_graph_extender.h \
138.70 - bits/extendable_graph_extender.h \
138.71 - bits/clearable_graph_extender.h \
138.72 - bits/erasable_graph_extender.h \
138.73 - bits/undir_graph_extender.h \
138.74 - bits/item_reader.h \
138.75 - bits/item_writer.h
138.76 -
138.77 -noinst_HEADERS = \
138.78 - concept/graph.h \
138.79 - concept/graph_component.h \
138.80 - concept/undir_graph.h \
138.81 - concept/sym_graph.h \
138.82 - concept/maps.h \
138.83 - concept/heap.h \
138.84 - concept/path.h
139.1 --- a/src/lemon/attic/debug.h Sat May 21 21:04:57 2005 +0000
139.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
139.3 @@ -1,70 +0,0 @@
139.4 -/* -*- C++ -*-
139.5 - * src/lemon/debug.h - Part of LEMON, a generic C++ optimization library
139.6 - *
139.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
139.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
139.9 - *
139.10 - * Permission to use, modify and distribute this software is granted
139.11 - * provided that this copyright notice appears in all copies. For
139.12 - * precise terms see the accompanying LICENSE file.
139.13 - *
139.14 - * This software is provided "AS IS" with no warranty of any kind,
139.15 - * express or implied, and with no claim as to its suitability for any
139.16 - * purpose.
139.17 - *
139.18 - */
139.19 -
139.20 -#ifndef LEMON_DEBUG_H
139.21 -#define LEMON_DEBUG_H
139.22 -
139.23 -//! \file
139.24 -//! \brief Basic definitions for debug control.
139.25 -
139.26 -namespace lemon {
139.27 -
139.28 - //! Debug mode for testing/debugging
139.29 -
139.30 - //! Use this debug mode if you want exhaustive range and consistency checks.
139.31 - //! It also produces verbose debug messages.
139.32 - struct DebugOn {
139.33 - //! Example: check whether the edges added to a path are adjacent
139.34 - static const bool consistensy_check = true;
139.35 -
139.36 - static const bool range_check = true;
139.37 -
139.38 - //! Examples: initialize maps with some value;
139.39 - //! after deleting an item from UnionFindEnum set its value in the
139.40 - //! corresponding map to NULL...
139.41 - static const bool ensure_safe_state = true;
139.42 -
139.43 - static const int verbose = 5;
139.44 - };
139.45 -
139.46 - //! Debug mode for turning off debug aids.
139.47 -
139.48 - //! This debud mode switches off all range and consistency checks,
139.49 - //! as well as the debug messages.
139.50 - //!
139.51 - struct DebugOff {
139.52 - static const bool consistensy_check = false;
139.53 - static const bool range_check = false;
139.54 - static const bool ensure_safe_state = false;
139.55 - static const int verbose = 0;
139.56 - };
139.57 -
139.58 -#ifdef DEBUG
139.59 - //! The default debug mode.
139.60 -
139.61 - //! The default debug mode.
139.62 - //!
139.63 - typedef DebugOn DefaultDebugMode;
139.64 -#else
139.65 - //! The default debug mode.
139.66 -
139.67 - //! The default debug mode.
139.68 - //!
139.69 - typedef DebugOff DefaultDebugMode;
139.70 -#endif
139.71 -
139.72 -}
139.73 -#endif // LEMON_DEBUG_H
140.1 --- a/src/lemon/bezier.h Sat May 21 21:04:57 2005 +0000
140.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
140.3 @@ -1,147 +0,0 @@
140.4 -/* -*- C++ -*-
140.5 - * src/lemon/bezier.h - Part of LEMON, a generic C++ optimization library
140.6 - *
140.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
140.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
140.9 - *
140.10 - * Permission to use, modify and distribute this software is granted
140.11 - * provided that this copyright notice appears in all copies. For
140.12 - * precise terms see the accompanying LICENSE file.
140.13 - *
140.14 - * This software is provided "AS IS" with no warranty of any kind,
140.15 - * express or implied, and with no claim as to its suitability for any
140.16 - * purpose.
140.17 - *
140.18 - */
140.19 -
140.20 -#ifndef LEMON_BEZIER_H
140.21 -#define LEMON_BEZIER_H
140.22 -
140.23 -///\ingroup misc
140.24 -///\file
140.25 -///\brief Classes to compute with Bezier curves.
140.26 -///
140.27 -///Up to now this file is used internally by \ref graph_to_eps.h
140.28 -///
140.29 -///\author Alpar Juttner
140.30 -
140.31 -#include<lemon/xy.h>
140.32 -
140.33 -namespace lemon {
140.34 -
140.35 -class BezierBase {
140.36 -public:
140.37 - typedef xy<double> xy;
140.38 -protected:
140.39 - static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
140.40 -};
140.41 -
140.42 -class Bezier1 : public BezierBase
140.43 -{
140.44 -public:
140.45 - xy p1,p2;
140.46 -
140.47 - Bezier1() {}
140.48 - Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
140.49 -
140.50 - xy operator()(double t) const
140.51 - {
140.52 - // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
140.53 - return conv(p1,p2,t);
140.54 - }
140.55 - Bezier1 before(double t) const
140.56 - {
140.57 - return Bezier1(p1,conv(p1,p2,t));
140.58 - }
140.59 -
140.60 - Bezier1 after(double t) const
140.61 - {
140.62 - return Bezier1(conv(p1,p2,t),p2);
140.63 - }
140.64 - Bezier1 revert() { return Bezier1(p2,p1);}
140.65 - Bezier1 operator()(double a,double b) { return before(b).after(a/b); }
140.66 - xy grad() { return p2-p1; }
140.67 - xy grad(double t) { return grad(); }
140.68 -
140.69 -};
140.70 -
140.71 -class Bezier2 : public BezierBase
140.72 -{
140.73 -public:
140.74 - xy p1,p2,p3;
140.75 -
140.76 - Bezier2() {}
140.77 - Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
140.78 - Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
140.79 - xy operator()(double t) const
140.80 - {
140.81 - // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
140.82 - return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
140.83 - }
140.84 - Bezier2 before(double t) const
140.85 - {
140.86 - xy q(conv(p1,p2,t));
140.87 - xy r(conv(p2,p3,t));
140.88 - return Bezier2(p1,q,conv(q,r,t));
140.89 - }
140.90 -
140.91 - Bezier2 after(double t) const
140.92 - {
140.93 - xy q(conv(p1,p2,t));
140.94 - xy r(conv(p2,p3,t));
140.95 - return Bezier2(conv(q,r,t),r,p3);
140.96 - }
140.97 - Bezier2 revert() { return Bezier2(p3,p2,p1);}
140.98 - Bezier2 operator()(double a,double b) { return before(b).after(a/b); }
140.99 - Bezier1 grad() { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
140.100 - xy grad(double t) { return grad()(t); }
140.101 -};
140.102 -
140.103 -class Bezier3 : public BezierBase
140.104 -{
140.105 -public:
140.106 - xy p1,p2,p3,p4;
140.107 -
140.108 - Bezier3() {}
140.109 - Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
140.110 - Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
140.111 - p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
140.112 - Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
140.113 - p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
140.114 -
140.115 - xy operator()(double t) const
140.116 - {
140.117 - // return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
140.118 - return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
140.119 - (3*t*t*(1-t))*p3+(t*t*t)*p4;
140.120 - }
140.121 - Bezier3 before(double t) const
140.122 - {
140.123 - xy p(conv(p1,p2,t));
140.124 - xy q(conv(p2,p3,t));
140.125 - xy r(conv(p3,p4,t));
140.126 - xy a(conv(p,q,t));
140.127 - xy b(conv(q,r,t));
140.128 - xy c(conv(a,b,t));
140.129 - return Bezier3(p1,p,a,c);
140.130 - }
140.131 -
140.132 - Bezier3 after(double t) const
140.133 - {
140.134 - xy p(conv(p1,p2,t));
140.135 - xy q(conv(p2,p3,t));
140.136 - xy r(conv(p3,p4,t));
140.137 - xy a(conv(p,q,t));
140.138 - xy b(conv(q,r,t));
140.139 - xy c(conv(a,b,t));
140.140 - return Bezier3(c,b,r,p4);
140.141 - }
140.142 - Bezier3 revert() { return Bezier3(p4,p3,p2,p1);}
140.143 - Bezier3 operator()(double a,double b) { return before(b).after(a/b); }
140.144 - Bezier2 grad() { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
140.145 - xy grad(double t) { return grad()(t); }
140.146 -};
140.147 -
140.148 -} //END OF NAMESPACE LEMON
140.149 -
140.150 -#endif // LEMON_BEZIER_H
141.1 --- a/src/lemon/bfs.h Sat May 21 21:04:57 2005 +0000
141.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
141.3 @@ -1,1130 +0,0 @@
141.4 -/* -*- C++ -*-
141.5 - * src/lemon/bfs.h - Part of LEMON, a generic C++ optimization library
141.6 - *
141.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
141.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
141.9 - *
141.10 - * Permission to use, modify and distribute this software is granted
141.11 - * provided that this copyright notice appears in all copies. For
141.12 - * precise terms see the accompanying LICENSE file.
141.13 - *
141.14 - * This software is provided "AS IS" with no warranty of any kind,
141.15 - * express or implied, and with no claim as to its suitability for any
141.16 - * purpose.
141.17 - *
141.18 - */
141.19 -
141.20 -#ifndef LEMON_BFS_H
141.21 -#define LEMON_BFS_H
141.22 -
141.23 -///\ingroup flowalgs
141.24 -///\file
141.25 -///\brief Bfs algorithm.
141.26 -
141.27 -#include <lemon/list_graph.h>
141.28 -#include <lemon/graph_utils.h>
141.29 -#include <lemon/invalid.h>
141.30 -#include <lemon/error.h>
141.31 -#include <lemon/maps.h>
141.32 -
141.33 -namespace lemon {
141.34 -
141.35 -
141.36 -
141.37 - ///Default traits class of Bfs class.
141.38 -
141.39 - ///Default traits class of Bfs class.
141.40 - ///\param GR Graph type.
141.41 - template<class GR>
141.42 - struct BfsDefaultTraits
141.43 - {
141.44 - ///The graph type the algorithm runs on.
141.45 - typedef GR Graph;
141.46 - ///\brief The type of the map that stores the last
141.47 - ///edges of the shortest paths.
141.48 - ///
141.49 - ///The type of the map that stores the last
141.50 - ///edges of the shortest paths.
141.51 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.52 - ///
141.53 - typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
141.54 - ///Instantiates a PredMap.
141.55 -
141.56 - ///This function instantiates a \ref PredMap.
141.57 - ///\param G is the graph, to which we would like to define the PredMap.
141.58 - ///\todo The graph alone may be insufficient to initialize
141.59 - static PredMap *createPredMap(const GR &G)
141.60 - {
141.61 - return new PredMap(G);
141.62 - }
141.63 -// ///\brief The type of the map that stores the last but one
141.64 -// ///nodes of the shortest paths.
141.65 -// ///
141.66 -// ///The type of the map that stores the last but one
141.67 -// ///nodes of the shortest paths.
141.68 -// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.69 -// ///
141.70 -// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
141.71 -// ///Instantiates a PredNodeMap.
141.72 -
141.73 -// ///This function instantiates a \ref PredNodeMap.
141.74 -// ///\param G is the graph, to which
141.75 -// ///we would like to define the \ref PredNodeMap
141.76 -// static PredNodeMap *createPredNodeMap(const GR &G)
141.77 -// {
141.78 -// return new PredNodeMap();
141.79 -// }
141.80 -
141.81 - ///The type of the map that indicates which nodes are processed.
141.82 -
141.83 - ///The type of the map that indicates which nodes are processed.
141.84 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.85 - ///\todo named parameter to set this type, function to read and write.
141.86 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
141.87 - ///Instantiates a ProcessedMap.
141.88 -
141.89 - ///This function instantiates a \ref ProcessedMap.
141.90 - ///\param G is the graph, to which
141.91 - ///we would like to define the \ref ProcessedMap
141.92 - static ProcessedMap *createProcessedMap(const GR &)
141.93 - {
141.94 - return new ProcessedMap();
141.95 - }
141.96 - ///The type of the map that indicates which nodes are reached.
141.97 -
141.98 - ///The type of the map that indicates which nodes are reached.
141.99 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.100 - ///\todo named parameter to set this type, function to read and write.
141.101 - typedef typename Graph::template NodeMap<bool> ReachedMap;
141.102 - ///Instantiates a ReachedMap.
141.103 -
141.104 - ///This function instantiates a \ref ReachedMap.
141.105 - ///\param G is the graph, to which
141.106 - ///we would like to define the \ref ReachedMap.
141.107 - static ReachedMap *createReachedMap(const GR &G)
141.108 - {
141.109 - return new ReachedMap(G);
141.110 - }
141.111 - ///The type of the map that stores the dists of the nodes.
141.112 -
141.113 - ///The type of the map that stores the dists of the nodes.
141.114 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.115 - ///
141.116 - typedef typename Graph::template NodeMap<int> DistMap;
141.117 - ///Instantiates a DistMap.
141.118 -
141.119 - ///This function instantiates a \ref DistMap.
141.120 - ///\param G is the graph, to which we would like to define the \ref DistMap
141.121 - static DistMap *createDistMap(const GR &G)
141.122 - {
141.123 - return new DistMap(G);
141.124 - }
141.125 - };
141.126 -
141.127 - ///%BFS algorithm class.
141.128 -
141.129 - ///\ingroup flowalgs
141.130 - ///This class provides an efficient implementation of the %BFS algorithm.
141.131 - ///
141.132 - ///\param GR The graph type the algorithm runs on. The default value is
141.133 - ///\ref ListGraph. The value of GR is not used directly by Bfs, it
141.134 - ///is only passed to \ref BfsDefaultTraits.
141.135 - ///\param TR Traits class to set various data types used by the algorithm.
141.136 - ///The default traits class is
141.137 - ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
141.138 - ///See \ref BfsDefaultTraits for the documentation of
141.139 - ///a Bfs traits class.
141.140 - ///
141.141 - ///\author Alpar Juttner
141.142 - ///\todo A compare object would be nice.
141.143 -
141.144 -#ifdef DOXYGEN
141.145 - template <typename GR,
141.146 - typename TR>
141.147 -#else
141.148 - template <typename GR=ListGraph,
141.149 - typename TR=BfsDefaultTraits<GR> >
141.150 -#endif
141.151 - class Bfs {
141.152 - public:
141.153 - /**
141.154 - * \brief \ref Exception for uninitialized parameters.
141.155 - *
141.156 - * This error represents problems in the initialization
141.157 - * of the parameters of the algorithms.
141.158 - */
141.159 - class UninitializedParameter : public lemon::UninitializedParameter {
141.160 - public:
141.161 - virtual const char* exceptionName() const {
141.162 - return "lemon::Bfs::UninitializedParameter";
141.163 - }
141.164 - };
141.165 -
141.166 - typedef TR Traits;
141.167 - ///The type of the underlying graph.
141.168 - typedef typename TR::Graph Graph;
141.169 - ///\e
141.170 - typedef typename Graph::Node Node;
141.171 - ///\e
141.172 - typedef typename Graph::NodeIt NodeIt;
141.173 - ///\e
141.174 - typedef typename Graph::Edge Edge;
141.175 - ///\e
141.176 - typedef typename Graph::OutEdgeIt OutEdgeIt;
141.177 -
141.178 - ///\brief The type of the map that stores the last
141.179 - ///edges of the shortest paths.
141.180 - typedef typename TR::PredMap PredMap;
141.181 -// ///\brief The type of the map that stores the last but one
141.182 -// ///nodes of the shortest paths.
141.183 -// typedef typename TR::PredNodeMap PredNodeMap;
141.184 - ///The type of the map indicating which nodes are reached.
141.185 - typedef typename TR::ReachedMap ReachedMap;
141.186 - ///The type of the map indicating which nodes are processed.
141.187 - typedef typename TR::ProcessedMap ProcessedMap;
141.188 - ///The type of the map that stores the dists of the nodes.
141.189 - typedef typename TR::DistMap DistMap;
141.190 - private:
141.191 - /// Pointer to the underlying graph.
141.192 - const Graph *G;
141.193 - ///Pointer to the map of predecessors edges.
141.194 - PredMap *_pred;
141.195 - ///Indicates if \ref _pred is locally allocated (\c true) or not.
141.196 - bool local_pred;
141.197 -// ///Pointer to the map of predecessors nodes.
141.198 -// PredNodeMap *_predNode;
141.199 -// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
141.200 -// bool local_predNode;
141.201 - ///Pointer to the map of distances.
141.202 - DistMap *_dist;
141.203 - ///Indicates if \ref _dist is locally allocated (\c true) or not.
141.204 - bool local_dist;
141.205 - ///Pointer to the map of reached status of the nodes.
141.206 - ReachedMap *_reached;
141.207 - ///Indicates if \ref _reached is locally allocated (\c true) or not.
141.208 - bool local_reached;
141.209 - ///Pointer to the map of processed status of the nodes.
141.210 - ProcessedMap *_processed;
141.211 - ///Indicates if \ref _processed is locally allocated (\c true) or not.
141.212 - bool local_processed;
141.213 -
141.214 - std::vector<typename Graph::Node> _queue;
141.215 - int _queue_head,_queue_tail,_queue_next_dist;
141.216 - int _curr_dist;
141.217 -// ///The source node of the last execution.
141.218 -// Node source;
141.219 -
141.220 - ///Creates the maps if necessary.
141.221 -
141.222 - ///\todo Error if \c G are \c NULL.
141.223 - ///\todo Better memory allocation (instead of new).
141.224 - void create_maps()
141.225 - {
141.226 - if(!_pred) {
141.227 - local_pred = true;
141.228 - _pred = Traits::createPredMap(*G);
141.229 - }
141.230 -// if(!_predNode) {
141.231 -// local_predNode = true;
141.232 -// _predNode = Traits::createPredNodeMap(*G);
141.233 -// }
141.234 - if(!_dist) {
141.235 - local_dist = true;
141.236 - _dist = Traits::createDistMap(*G);
141.237 - }
141.238 - if(!_reached) {
141.239 - local_reached = true;
141.240 - _reached = Traits::createReachedMap(*G);
141.241 - }
141.242 - if(!_processed) {
141.243 - local_processed = true;
141.244 - _processed = Traits::createProcessedMap(*G);
141.245 - }
141.246 - }
141.247 -
141.248 - public :
141.249 -
141.250 - ///\name Named template parameters
141.251 -
141.252 - ///@{
141.253 -
141.254 - template <class T>
141.255 - struct DefPredMapTraits : public Traits {
141.256 - typedef T PredMap;
141.257 - static PredMap *createPredMap(const Graph &G)
141.258 - {
141.259 - throw UninitializedParameter();
141.260 - }
141.261 - };
141.262 - ///\ref named-templ-param "Named parameter" for setting PredMap type
141.263 -
141.264 - ///\ref named-templ-param "Named parameter" for setting PredMap type
141.265 - ///
141.266 - template <class T>
141.267 - class DefPredMap : public Bfs< Graph,
141.268 - DefPredMapTraits<T> > { };
141.269 -
141.270 -// template <class T>
141.271 -// struct DefPredNodeMapTraits : public Traits {
141.272 -// typedef T PredNodeMap;
141.273 -// static PredNodeMap *createPredNodeMap(const Graph &G)
141.274 -// {
141.275 -// throw UninitializedParameter();
141.276 -// }
141.277 -// };
141.278 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
141.279 -
141.280 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
141.281 -// ///
141.282 -// template <class T>
141.283 -// class DefPredNodeMap : public Bfs< Graph,
141.284 -// LengthMap,
141.285 -// DefPredNodeMapTraits<T> > { };
141.286 -
141.287 - template <class T>
141.288 - struct DefDistMapTraits : public Traits {
141.289 - typedef T DistMap;
141.290 - static DistMap *createDistMap(const Graph &G)
141.291 - {
141.292 - throw UninitializedParameter();
141.293 - }
141.294 - };
141.295 - ///\ref named-templ-param "Named parameter" for setting DistMap type
141.296 -
141.297 - ///\ref named-templ-param "Named parameter" for setting DistMap type
141.298 - ///
141.299 - template <class T>
141.300 - class DefDistMap : public Bfs< Graph,
141.301 - DefDistMapTraits<T> > { };
141.302 -
141.303 - template <class T>
141.304 - struct DefReachedMapTraits : public Traits {
141.305 - typedef T ReachedMap;
141.306 - static ReachedMap *createReachedMap(const Graph &G)
141.307 - {
141.308 - throw UninitializedParameter();
141.309 - }
141.310 - };
141.311 - ///\ref named-templ-param "Named parameter" for setting ReachedMap type
141.312 -
141.313 - ///\ref named-templ-param "Named parameter" for setting ReachedMap type
141.314 - ///
141.315 - template <class T>
141.316 - class DefReachedMap : public Bfs< Graph,
141.317 - DefReachedMapTraits<T> > { };
141.318 -
141.319 - struct DefGraphReachedMapTraits : public Traits {
141.320 - typedef typename Graph::template NodeMap<bool> ReachedMap;
141.321 - static ReachedMap *createReachedMap(const Graph &G)
141.322 - {
141.323 - return new ReachedMap(G);
141.324 - }
141.325 - };
141.326 - template <class T>
141.327 - struct DefProcessedMapTraits : public Traits {
141.328 - typedef T ProcessedMap;
141.329 - static ProcessedMap *createProcessedMap(const Graph &G)
141.330 - {
141.331 - throw UninitializedParameter();
141.332 - }
141.333 - };
141.334 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
141.335 -
141.336 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
141.337 - ///
141.338 - template <class T>
141.339 - class DefProcessedMap : public Bfs< Graph,
141.340 - DefProcessedMapTraits<T> > { };
141.341 -
141.342 - struct DefGraphProcessedMapTraits : public Traits {
141.343 - typedef typename Graph::template NodeMap<bool> ProcessedMap;
141.344 - static ProcessedMap *createProcessedMap(const Graph &G)
141.345 - {
141.346 - return new ProcessedMap(G);
141.347 - }
141.348 - };
141.349 - ///\brief \ref named-templ-param "Named parameter"
141.350 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
141.351 - ///
141.352 - ///\ref named-templ-param "Named parameter"
141.353 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
141.354 - ///If you don't set it explicitly, it will be automatically allocated.
141.355 - template <class T>
141.356 - class DefProcessedMapToBeDefaultMap :
141.357 - public Bfs< Graph,
141.358 - DefGraphProcessedMapTraits> { };
141.359 -
141.360 - ///@}
141.361 -
141.362 - public:
141.363 -
141.364 - ///Constructor.
141.365 -
141.366 - ///\param _G the graph the algorithm will run on.
141.367 - ///
141.368 - Bfs(const Graph& _G) :
141.369 - G(&_G),
141.370 - _pred(NULL), local_pred(false),
141.371 -// _predNode(NULL), local_predNode(false),
141.372 - _dist(NULL), local_dist(false),
141.373 - _reached(NULL), local_reached(false),
141.374 - _processed(NULL), local_processed(false)
141.375 - { }
141.376 -
141.377 - ///Destructor.
141.378 - ~Bfs()
141.379 - {
141.380 - if(local_pred) delete _pred;
141.381 -// if(local_predNode) delete _predNode;
141.382 - if(local_dist) delete _dist;
141.383 - if(local_reached) delete _reached;
141.384 - if(local_processed) delete _processed;
141.385 - }
141.386 -
141.387 - ///Sets the map storing the predecessor edges.
141.388 -
141.389 - ///Sets the map storing the predecessor edges.
141.390 - ///If you don't use this function before calling \ref run(),
141.391 - ///it will allocate one. The destructor deallocates this
141.392 - ///automatically allocated map, of course.
141.393 - ///\return <tt> (*this) </tt>
141.394 - Bfs &predMap(PredMap &m)
141.395 - {
141.396 - if(local_pred) {
141.397 - delete _pred;
141.398 - local_pred=false;
141.399 - }
141.400 - _pred = &m;
141.401 - return *this;
141.402 - }
141.403 -
141.404 - ///Sets the map indicating the reached nodes.
141.405 -
141.406 - ///Sets the map indicating the reached nodes.
141.407 - ///If you don't use this function before calling \ref run(),
141.408 - ///it will allocate one. The destructor deallocates this
141.409 - ///automatically allocated map, of course.
141.410 - ///\return <tt> (*this) </tt>
141.411 - Bfs &reachedMap(ReachedMap &m)
141.412 - {
141.413 - if(local_reached) {
141.414 - delete _reached;
141.415 - local_reached=false;
141.416 - }
141.417 - _reached = &m;
141.418 - return *this;
141.419 - }
141.420 -
141.421 - ///Sets the map indicating the processed nodes.
141.422 -
141.423 - ///Sets the map indicating the processed nodes.
141.424 - ///If you don't use this function before calling \ref run(),
141.425 - ///it will allocate one. The destructor deallocates this
141.426 - ///automatically allocated map, of course.
141.427 - ///\return <tt> (*this) </tt>
141.428 - Bfs &processedMap(ProcessedMap &m)
141.429 - {
141.430 - if(local_processed) {
141.431 - delete _processed;
141.432 - local_processed=false;
141.433 - }
141.434 - _processed = &m;
141.435 - return *this;
141.436 - }
141.437 -
141.438 -// ///Sets the map storing the predecessor nodes.
141.439 -
141.440 -// ///Sets the map storing the predecessor nodes.
141.441 -// ///If you don't use this function before calling \ref run(),
141.442 -// ///it will allocate one. The destructor deallocates this
141.443 -// ///automatically allocated map, of course.
141.444 -// ///\return <tt> (*this) </tt>
141.445 -// Bfs &predNodeMap(PredNodeMap &m)
141.446 -// {
141.447 -// if(local_predNode) {
141.448 -// delete _predNode;
141.449 -// local_predNode=false;
141.450 -// }
141.451 -// _predNode = &m;
141.452 -// return *this;
141.453 -// }
141.454 -
141.455 - ///Sets the map storing the distances calculated by the algorithm.
141.456 -
141.457 - ///Sets the map storing the distances calculated by the algorithm.
141.458 - ///If you don't use this function before calling \ref run(),
141.459 - ///it will allocate one. The destructor deallocates this
141.460 - ///automatically allocated map, of course.
141.461 - ///\return <tt> (*this) </tt>
141.462 - Bfs &distMap(DistMap &m)
141.463 - {
141.464 - if(local_dist) {
141.465 - delete _dist;
141.466 - local_dist=false;
141.467 - }
141.468 - _dist = &m;
141.469 - return *this;
141.470 - }
141.471 -
141.472 - public:
141.473 - ///\name Execution control
141.474 - ///The simplest way to execute the algorithm is to use
141.475 - ///one of the member functions called \c run(...).
141.476 - ///\n
141.477 - ///If you need more control on the execution,
141.478 - ///first you must call \ref init(), then you can add several source nodes
141.479 - ///with \ref addSource().
141.480 - ///Finally \ref start() will perform the actual path
141.481 - ///computation.
141.482 -
141.483 - ///@{
141.484 -
141.485 - ///Initializes the internal data structures.
141.486 -
141.487 - ///Initializes the internal data structures.
141.488 - ///
141.489 - void init()
141.490 - {
141.491 - create_maps();
141.492 - _queue.resize(countNodes(*G));
141.493 - _queue_head=_queue_tail=0;
141.494 - _curr_dist=1;
141.495 - for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
141.496 - _pred->set(u,INVALID);
141.497 -// _predNode->set(u,INVALID);
141.498 - _reached->set(u,false);
141.499 - _processed->set(u,false);
141.500 - }
141.501 - }
141.502 -
141.503 - ///Adds a new source node.
141.504 -
141.505 - ///Adds a new source node to the set of nodes to be processed.
141.506 - ///
141.507 - void addSource(Node s)
141.508 - {
141.509 - if(!(*_reached)[s])
141.510 - {
141.511 - _reached->set(s,true);
141.512 - _pred->set(s,INVALID);
141.513 - _dist->set(s,0);
141.514 - _queue[_queue_head++]=s;
141.515 - _queue_next_dist=_queue_head;
141.516 - }
141.517 - }
141.518 -
141.519 - ///Processes the next node.
141.520 -
141.521 - ///Processes the next node.
141.522 - ///
141.523 - ///\warning The queue must not be empty!
141.524 - void processNextNode()
141.525 - {
141.526 - if(_queue_tail==_queue_next_dist) {
141.527 - _curr_dist++;
141.528 - _queue_next_dist=_queue_head;
141.529 - }
141.530 - Node n=_queue[_queue_tail++];
141.531 - _processed->set(n,true);
141.532 - Node m;
141.533 - for(OutEdgeIt e(*G,n);e!=INVALID;++e)
141.534 - if(!(*_reached)[m=G->target(e)]) {
141.535 - _queue[_queue_head++]=m;
141.536 - _reached->set(m,true);
141.537 - _pred->set(m,e);
141.538 -// _pred_node->set(m,n);
141.539 - _dist->set(m,_curr_dist);
141.540 - }
141.541 - }
141.542 -
141.543 - ///\brief Returns \c false if there are nodes
141.544 - ///to be processed in the queue
141.545 - ///
141.546 - ///Returns \c false if there are nodes
141.547 - ///to be processed in the queue
141.548 - bool emptyQueue() { return _queue_tail==_queue_head; }
141.549 - ///Returns the number of the nodes to be processed.
141.550 -
141.551 - ///Returns the number of the nodes to be processed in the queue.
141.552 - ///
141.553 - int queueSize() { return _queue_head-_queue_tail; }
141.554 -
141.555 - ///Executes the algorithm.
141.556 -
141.557 - ///Executes the algorithm.
141.558 - ///
141.559 - ///\pre init() must be called and at least one node should be added
141.560 - ///with addSource() before using this function.
141.561 - ///
141.562 - ///This method runs the %BFS algorithm from the root node(s)
141.563 - ///in order to
141.564 - ///compute the
141.565 - ///shortest path to each node. The algorithm computes
141.566 - ///- The shortest path tree.
141.567 - ///- The distance of each node from the root(s).
141.568 - ///
141.569 - void start()
141.570 - {
141.571 - while ( !emptyQueue() ) processNextNode();
141.572 - }
141.573 -
141.574 - ///Executes the algorithm until \c dest is reached.
141.575 -
141.576 - ///Executes the algorithm until \c dest is reached.
141.577 - ///
141.578 - ///\pre init() must be called and at least one node should be added
141.579 - ///with addSource() before using this function.
141.580 - ///
141.581 - ///This method runs the %BFS algorithm from the root node(s)
141.582 - ///in order to
141.583 - ///compute the
141.584 - ///shortest path to \c dest. The algorithm computes
141.585 - ///- The shortest path to \c dest.
141.586 - ///- The distance of \c dest from the root(s).
141.587 - ///
141.588 - void start(Node dest)
141.589 - {
141.590 - while ( !emptyQueue() && _queue[_queue_tail]!=dest ) processNextNode();
141.591 - }
141.592 -
141.593 - ///Executes the algorithm until a condition is met.
141.594 -
141.595 - ///Executes the algorithm until a condition is met.
141.596 - ///
141.597 - ///\pre init() must be called and at least one node should be added
141.598 - ///with addSource() before using this function.
141.599 - ///
141.600 - ///\param nm must be a bool (or convertible) node map. The algorithm
141.601 - ///will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
141.602 - template<class NM>
141.603 - void start(const NM &nm)
141.604 - {
141.605 - while ( !emptyQueue() && !nm[_queue[_queue_tail]] ) processNextNode();
141.606 - }
141.607 -
141.608 - ///Runs %BFS algorithm from node \c s.
141.609 -
141.610 - ///This method runs the %BFS algorithm from a root node \c s
141.611 - ///in order to
141.612 - ///compute the
141.613 - ///shortest path to each node. The algorithm computes
141.614 - ///- The shortest path tree.
141.615 - ///- The distance of each node from the root.
141.616 - ///
141.617 - ///\note d.run(s) is just a shortcut of the following code.
141.618 - ///\code
141.619 - /// d.init();
141.620 - /// d.addSource(s);
141.621 - /// d.start();
141.622 - ///\endcode
141.623 - void run(Node s) {
141.624 - init();
141.625 - addSource(s);
141.626 - start();
141.627 - }
141.628 -
141.629 - ///Finds the shortest path between \c s and \c t.
141.630 -
141.631 - ///Finds the shortest path between \c s and \c t.
141.632 - ///
141.633 - ///\return The length of the shortest s---t path if there exists one,
141.634 - ///0 otherwise.
141.635 - ///\note Apart from the return value, d.run(s) is
141.636 - ///just a shortcut of the following code.
141.637 - ///\code
141.638 - /// d.init();
141.639 - /// d.addSource(s);
141.640 - /// d.start(t);
141.641 - ///\endcode
141.642 - int run(Node s,Node t) {
141.643 - init();
141.644 - addSource(s);
141.645 - start(t);
141.646 - return reached(t)?_curr_dist-1+(_queue_tail==_queue_next_dist):0;
141.647 - }
141.648 -
141.649 - ///@}
141.650 -
141.651 - ///\name Query Functions
141.652 - ///The result of the %BFS algorithm can be obtained using these
141.653 - ///functions.\n
141.654 - ///Before the use of these functions,
141.655 - ///either run() or start() must be called.
141.656 -
141.657 - ///@{
141.658 -
141.659 - ///Copies the shortest path to \c t into \c p
141.660 -
141.661 - ///This function copies the shortest path to \c t into \c p.
141.662 - ///If it \c \t is a source itself or unreachable, then it does not
141.663 - ///alter \c p.
141.664 - ///\todo Is it the right way to handle unreachable nodes?
141.665 - ///\return Returns \c true if a path to \c t was actually copied to \c p,
141.666 - ///\c false otherwise.
141.667 - ///\sa DirPath
141.668 - template<class P>
141.669 - bool getPath(P &p,Node t)
141.670 - {
141.671 - if(reached(t)) {
141.672 - p.clear();
141.673 - typename P::Builder b(p);
141.674 - for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
141.675 - b.pushFront(pred(t));
141.676 - b.commit();
141.677 - return true;
141.678 - }
141.679 - return false;
141.680 - }
141.681 -
141.682 - ///The distance of a node from the root(s).
141.683 -
141.684 - ///Returns the distance of a node from the root(s).
141.685 - ///\pre \ref run() must be called before using this function.
141.686 - ///\warning If node \c v in unreachable from the root(s) the return value
141.687 - ///of this function is undefined.
141.688 - int dist(Node v) const { return (*_dist)[v]; }
141.689 -
141.690 - ///Returns the 'previous edge' of the shortest path tree.
141.691 -
141.692 - ///For a node \c v it returns the 'previous edge'
141.693 - ///of the shortest path tree,
141.694 - ///i.e. it returns the last edge of a shortest path from the root(s) to \c
141.695 - ///v. It is \ref INVALID
141.696 - ///if \c v is unreachable from the root(s) or \c v is a root. The
141.697 - ///shortest path tree used here is equal to the shortest path tree used in
141.698 - ///\ref predNode(Node v).
141.699 - ///\pre Either \ref run() or \ref start() must be called before using
141.700 - ///this function.
141.701 - ///\todo predEdge could be a better name.
141.702 - Edge pred(Node v) const { return (*_pred)[v];}
141.703 -
141.704 - ///Returns the 'previous node' of the shortest path tree.
141.705 -
141.706 - ///For a node \c v it returns the 'previous node'
141.707 - ///of the shortest path tree,
141.708 - ///i.e. it returns the last but one node from a shortest path from the
141.709 - ///root(a) to \c /v.
141.710 - ///It is INVALID if \c v is unreachable from the root(s) or
141.711 - ///if \c v itself a root.
141.712 - ///The shortest path tree used here is equal to the shortest path
141.713 - ///tree used in \ref pred(Node v).
141.714 - ///\pre Either \ref run() or \ref start() must be called before
141.715 - ///using this function.
141.716 - Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
141.717 - G->source((*_pred)[v]); }
141.718 -
141.719 - ///Returns a reference to the NodeMap of distances.
141.720 -
141.721 - ///Returns a reference to the NodeMap of distances.
141.722 - ///\pre Either \ref run() or \ref init() must
141.723 - ///be called before using this function.
141.724 - const DistMap &distMap() const { return *_dist;}
141.725 -
141.726 - ///Returns a reference to the shortest path tree map.
141.727 -
141.728 - ///Returns a reference to the NodeMap of the edges of the
141.729 - ///shortest path tree.
141.730 - ///\pre Either \ref run() or \ref init()
141.731 - ///must be called before using this function.
141.732 - const PredMap &predMap() const { return *_pred;}
141.733 -
141.734 -// ///Returns a reference to the map of nodes of shortest paths.
141.735 -
141.736 -// ///Returns a reference to the NodeMap of the last but one nodes of the
141.737 -// ///shortest path tree.
141.738 -// ///\pre \ref run() must be called before using this function.
141.739 -// const PredNodeMap &predNodeMap() const { return *_predNode;}
141.740 -
141.741 - ///Checks if a node is reachable from the root.
141.742 -
141.743 - ///Returns \c true if \c v is reachable from the root.
141.744 - ///\warning The source nodes are indicated as unreached.
141.745 - ///\pre Either \ref run() or \ref start()
141.746 - ///must be called before using this function.
141.747 - ///
141.748 - bool reached(Node v) { return (*_reached)[v]; }
141.749 -
141.750 - ///@}
141.751 - };
141.752 -
141.753 - ///Default traits class of Bfs function.
141.754 -
141.755 - ///Default traits class of Bfs function.
141.756 - ///\param GR Graph type.
141.757 - template<class GR>
141.758 - struct BfsWizardDefaultTraits
141.759 - {
141.760 - ///The graph type the algorithm runs on.
141.761 - typedef GR Graph;
141.762 - ///\brief The type of the map that stores the last
141.763 - ///edges of the shortest paths.
141.764 - ///
141.765 - ///The type of the map that stores the last
141.766 - ///edges of the shortest paths.
141.767 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.768 - ///
141.769 - typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
141.770 - ///Instantiates a PredMap.
141.771 -
141.772 - ///This function instantiates a \ref PredMap.
141.773 - ///\param G is the graph, to which we would like to define the PredMap.
141.774 - ///\todo The graph alone may be insufficient to initialize
141.775 - static PredMap *createPredMap(const GR &)
141.776 - {
141.777 - return new PredMap();
141.778 - }
141.779 -// ///\brief The type of the map that stores the last but one
141.780 -// ///nodes of the shortest paths.
141.781 -// ///
141.782 -// ///The type of the map that stores the last but one
141.783 -// ///nodes of the shortest paths.
141.784 -// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.785 -// ///
141.786 -// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
141.787 -// ///Instantiates a PredNodeMap.
141.788 -
141.789 -// ///This function instantiates a \ref PredNodeMap.
141.790 -// ///\param G is the graph, to which
141.791 -// ///we would like to define the \ref PredNodeMap
141.792 -// static PredNodeMap *createPredNodeMap(const GR &G)
141.793 -// {
141.794 -// return new PredNodeMap();
141.795 -// }
141.796 -
141.797 - ///The type of the map that indicates which nodes are processed.
141.798 -
141.799 - ///The type of the map that indicates which nodes are processed.
141.800 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.801 - ///\todo named parameter to set this type, function to read and write.
141.802 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
141.803 - ///Instantiates a ProcessedMap.
141.804 -
141.805 - ///This function instantiates a \ref ProcessedMap.
141.806 - ///\param G is the graph, to which
141.807 - ///we would like to define the \ref ProcessedMap
141.808 - static ProcessedMap *createProcessedMap(const GR &)
141.809 - {
141.810 - return new ProcessedMap();
141.811 - }
141.812 - ///The type of the map that indicates which nodes are reached.
141.813 -
141.814 - ///The type of the map that indicates which nodes are reached.
141.815 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.816 - ///\todo named parameter to set this type, function to read and write.
141.817 - typedef typename Graph::template NodeMap<bool> ReachedMap;
141.818 - ///Instantiates a ReachedMap.
141.819 -
141.820 - ///This function instantiates a \ref ReachedMap.
141.821 - ///\param G is the graph, to which
141.822 - ///we would like to define the \ref ReachedMap.
141.823 - static ReachedMap *createReachedMap(const GR &G)
141.824 - {
141.825 - return new ReachedMap(G);
141.826 - }
141.827 - ///The type of the map that stores the dists of the nodes.
141.828 -
141.829 - ///The type of the map that stores the dists of the nodes.
141.830 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
141.831 - ///
141.832 - typedef NullMap<typename Graph::Node,int> DistMap;
141.833 - ///Instantiates a DistMap.
141.834 -
141.835 - ///This function instantiates a \ref DistMap.
141.836 - ///\param G is the graph, to which we would like to define the \ref DistMap
141.837 - static DistMap *createDistMap(const GR &)
141.838 - {
141.839 - return new DistMap();
141.840 - }
141.841 - };
141.842 -
141.843 - /// Default traits used by \ref BfsWizard
141.844 -
141.845 - /// To make it easier to use Bfs algorithm
141.846 - ///we have created a wizard class.
141.847 - /// This \ref BfsWizard class needs default traits,
141.848 - ///as well as the \ref Bfs class.
141.849 - /// The \ref BfsWizardBase is a class to be the default traits of the
141.850 - /// \ref BfsWizard class.
141.851 - template<class GR>
141.852 - class BfsWizardBase : public BfsWizardDefaultTraits<GR>
141.853 - {
141.854 -
141.855 - typedef BfsWizardDefaultTraits<GR> Base;
141.856 - protected:
141.857 - /// Type of the nodes in the graph.
141.858 - typedef typename Base::Graph::Node Node;
141.859 -
141.860 - /// Pointer to the underlying graph.
141.861 - void *_g;
141.862 - ///Pointer to the map of reached nodes.
141.863 - void *_reached;
141.864 - ///Pointer to the map of processed nodes.
141.865 - void *_processed;
141.866 - ///Pointer to the map of predecessors edges.
141.867 - void *_pred;
141.868 -// ///Pointer to the map of predecessors nodes.
141.869 -// void *_predNode;
141.870 - ///Pointer to the map of distances.
141.871 - void *_dist;
141.872 - ///Pointer to the source node.
141.873 - Node _source;
141.874 -
141.875 - public:
141.876 - /// Constructor.
141.877 -
141.878 - /// This constructor does not require parameters, therefore it initiates
141.879 - /// all of the attributes to default values (0, INVALID).
141.880 - BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
141.881 -// _predNode(0),
141.882 - _dist(0), _source(INVALID) {}
141.883 -
141.884 - /// Constructor.
141.885 -
141.886 - /// This constructor requires some parameters,
141.887 - /// listed in the parameters list.
141.888 - /// Others are initiated to 0.
141.889 - /// \param g is the initial value of \ref _g
141.890 - /// \param s is the initial value of \ref _source
141.891 - BfsWizardBase(const GR &g, Node s=INVALID) :
141.892 - _g((void *)&g), _reached(0), _processed(0), _pred(0),
141.893 -// _predNode(0),
141.894 - _dist(0), _source(s) {}
141.895 -
141.896 - };
141.897 -
141.898 - /// A class to make the usage of Bfs algorithm easier
141.899 -
141.900 - /// This class is created to make it easier to use Bfs algorithm.
141.901 - /// It uses the functions and features of the plain \ref Bfs,
141.902 - /// but it is much simpler to use it.
141.903 - ///
141.904 - /// Simplicity means that the way to change the types defined
141.905 - /// in the traits class is based on functions that returns the new class
141.906 - /// and not on templatable built-in classes.
141.907 - /// When using the plain \ref Bfs
141.908 - /// the new class with the modified type comes from
141.909 - /// the original class by using the ::
141.910 - /// operator. In the case of \ref BfsWizard only
141.911 - /// a function have to be called and it will
141.912 - /// return the needed class.
141.913 - ///
141.914 - /// It does not have own \ref run method. When its \ref run method is called
141.915 - /// it initiates a plain \ref Bfs class, and calls the \ref Bfs::run
141.916 - /// method of it.
141.917 - template<class TR>
141.918 - class BfsWizard : public TR
141.919 - {
141.920 - typedef TR Base;
141.921 -
141.922 - ///The type of the underlying graph.
141.923 - typedef typename TR::Graph Graph;
141.924 - //\e
141.925 - typedef typename Graph::Node Node;
141.926 - //\e
141.927 - typedef typename Graph::NodeIt NodeIt;
141.928 - //\e
141.929 - typedef typename Graph::Edge Edge;
141.930 - //\e
141.931 - typedef typename Graph::OutEdgeIt OutEdgeIt;
141.932 -
141.933 - ///\brief The type of the map that stores
141.934 - ///the reached nodes
141.935 - typedef typename TR::ReachedMap ReachedMap;
141.936 - ///\brief The type of the map that stores
141.937 - ///the processed nodes
141.938 - typedef typename TR::ProcessedMap ProcessedMap;
141.939 - ///\brief The type of the map that stores the last
141.940 - ///edges of the shortest paths.
141.941 - typedef typename TR::PredMap PredMap;
141.942 -// ///\brief The type of the map that stores the last but one
141.943 -// ///nodes of the shortest paths.
141.944 -// typedef typename TR::PredNodeMap PredNodeMap;
141.945 - ///The type of the map that stores the dists of the nodes.
141.946 - typedef typename TR::DistMap DistMap;
141.947 -
141.948 -public:
141.949 - /// Constructor.
141.950 - BfsWizard() : TR() {}
141.951 -
141.952 - /// Constructor that requires parameters.
141.953 -
141.954 - /// Constructor that requires parameters.
141.955 - /// These parameters will be the default values for the traits class.
141.956 - BfsWizard(const Graph &g, Node s=INVALID) :
141.957 - TR(g,s) {}
141.958 -
141.959 - ///Copy constructor
141.960 - BfsWizard(const TR &b) : TR(b) {}
141.961 -
141.962 - ~BfsWizard() {}
141.963 -
141.964 - ///Runs Bfs algorithm from a given node.
141.965 -
141.966 - ///Runs Bfs algorithm from a given node.
141.967 - ///The node can be given by the \ref source function.
141.968 - void run()
141.969 - {
141.970 - if(Base::_source==INVALID) throw UninitializedParameter();
141.971 - Bfs<Graph,TR> alg(*(Graph*)Base::_g);
141.972 - if(Base::_reached)
141.973 - alg.reachedMap(*(ReachedMap*)Base::_reached);
141.974 - if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
141.975 - if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
141.976 -// if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
141.977 - if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
141.978 - alg.run(Base::_source);
141.979 - }
141.980 -
141.981 - ///Runs Bfs algorithm from the given node.
141.982 -
141.983 - ///Runs Bfs algorithm from the given node.
141.984 - ///\param s is the given source.
141.985 - void run(Node s)
141.986 - {
141.987 - Base::_source=s;
141.988 - run();
141.989 - }
141.990 -
141.991 - template<class T>
141.992 - struct DefPredMapBase : public Base {
141.993 - typedef T PredMap;
141.994 - static PredMap *createPredMap(const Graph &) { return 0; };
141.995 - DefPredMapBase(const TR &b) : TR(b) {}
141.996 - };
141.997 -
141.998 - ///\brief \ref named-templ-param "Named parameter"
141.999 - ///function for setting PredMap
141.1000 - ///
141.1001 - /// \ref named-templ-param "Named parameter"
141.1002 - ///function for setting PredMap
141.1003 - ///
141.1004 - template<class T>
141.1005 - BfsWizard<DefPredMapBase<T> > predMap(const T &t)
141.1006 - {
141.1007 - Base::_pred=(void *)&t;
141.1008 - return BfsWizard<DefPredMapBase<T> >(*this);
141.1009 - }
141.1010 -
141.1011 -
141.1012 - template<class T>
141.1013 - struct DefReachedMapBase : public Base {
141.1014 - typedef T ReachedMap;
141.1015 - static ReachedMap *createReachedMap(const Graph &) { return 0; };
141.1016 - DefReachedMapBase(const TR &b) : TR(b) {}
141.1017 - };
141.1018 -
141.1019 - ///\brief \ref named-templ-param "Named parameter"
141.1020 - ///function for setting ReachedMap
141.1021 - ///
141.1022 - /// \ref named-templ-param "Named parameter"
141.1023 - ///function for setting ReachedMap
141.1024 - ///
141.1025 - template<class T>
141.1026 - BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
141.1027 - {
141.1028 - Base::_pred=(void *)&t;
141.1029 - return BfsWizard<DefReachedMapBase<T> >(*this);
141.1030 - }
141.1031 -
141.1032 -
141.1033 - template<class T>
141.1034 - struct DefProcessedMapBase : public Base {
141.1035 - typedef T ProcessedMap;
141.1036 - static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
141.1037 - DefProcessedMapBase(const TR &b) : TR(b) {}
141.1038 - };
141.1039 -
141.1040 - ///\brief \ref named-templ-param "Named parameter"
141.1041 - ///function for setting ProcessedMap
141.1042 - ///
141.1043 - /// \ref named-templ-param "Named parameter"
141.1044 - ///function for setting ProcessedMap
141.1045 - ///
141.1046 - template<class T>
141.1047 - BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
141.1048 - {
141.1049 - Base::_pred=(void *)&t;
141.1050 - return BfsWizard<DefProcessedMapBase<T> >(*this);
141.1051 - }
141.1052 -
141.1053 -
141.1054 -// template<class T>
141.1055 -// struct DefPredNodeMapBase : public Base {
141.1056 -// typedef T PredNodeMap;
141.1057 -// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
141.1058 -// DefPredNodeMapBase(const TR &b) : TR(b) {}
141.1059 -// };
141.1060 -
141.1061 -// ///\brief \ref named-templ-param "Named parameter"
141.1062 -// ///function for setting PredNodeMap type
141.1063 -// ///
141.1064 -// /// \ref named-templ-param "Named parameter"
141.1065 -// ///function for setting PredNodeMap type
141.1066 -// ///
141.1067 -// template<class T>
141.1068 -// BfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
141.1069 -// {
141.1070 -// Base::_predNode=(void *)&t;
141.1071 -// return BfsWizard<DefPredNodeMapBase<T> >(*this);
141.1072 -// }
141.1073 -
141.1074 - template<class T>
141.1075 - struct DefDistMapBase : public Base {
141.1076 - typedef T DistMap;
141.1077 - static DistMap *createDistMap(const Graph &) { return 0; };
141.1078 - DefDistMapBase(const TR &b) : TR(b) {}
141.1079 - };
141.1080 -
141.1081 - ///\brief \ref named-templ-param "Named parameter"
141.1082 - ///function for setting DistMap type
141.1083 - ///
141.1084 - /// \ref named-templ-param "Named parameter"
141.1085 - ///function for setting DistMap type
141.1086 - ///
141.1087 - template<class T>
141.1088 - BfsWizard<DefDistMapBase<T> > distMap(const T &t)
141.1089 - {
141.1090 - Base::_dist=(void *)&t;
141.1091 - return BfsWizard<DefDistMapBase<T> >(*this);
141.1092 - }
141.1093 -
141.1094 - /// Sets the source node, from which the Bfs algorithm runs.
141.1095 -
141.1096 - /// Sets the source node, from which the Bfs algorithm runs.
141.1097 - /// \param s is the source node.
141.1098 - BfsWizard<TR> &source(Node s)
141.1099 - {
141.1100 - Base::_source=s;
141.1101 - return *this;
141.1102 - }
141.1103 -
141.1104 - };
141.1105 -
141.1106 - ///Function type interface for Bfs algorithm.
141.1107 -
141.1108 - /// \ingroup flowalgs
141.1109 - ///Function type interface for Bfs algorithm.
141.1110 - ///
141.1111 - ///This function also has several
141.1112 - ///\ref named-templ-func-param "named parameters",
141.1113 - ///they are declared as the members of class \ref BfsWizard.
141.1114 - ///The following
141.1115 - ///example shows how to use these parameters.
141.1116 - ///\code
141.1117 - /// bfs(g,source).predMap(preds).run();
141.1118 - ///\endcode
141.1119 - ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
141.1120 - ///to the end of the parameter list.
141.1121 - ///\sa BfsWizard
141.1122 - ///\sa Bfs
141.1123 - template<class GR>
141.1124 - BfsWizard<BfsWizardBase<GR> >
141.1125 - bfs(const GR &g,typename GR::Node s=INVALID)
141.1126 - {
141.1127 - return BfsWizard<BfsWizardBase<GR> >(g,s);
141.1128 - }
141.1129 -
141.1130 -} //END OF NAMESPACE LEMON
141.1131 -
141.1132 -#endif
141.1133 -
142.1 --- a/src/lemon/bin_heap.h Sat May 21 21:04:57 2005 +0000
142.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
142.3 @@ -1,303 +0,0 @@
142.4 -/* -*- C++ -*-
142.5 - * src/lemon/bin_heap.h - Part of LEMON, a generic C++ optimization library
142.6 - *
142.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
142.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
142.9 - *
142.10 - * Permission to use, modify and distribute this software is granted
142.11 - * provided that this copyright notice appears in all copies. For
142.12 - * precise terms see the accompanying LICENSE file.
142.13 - *
142.14 - * This software is provided "AS IS" with no warranty of any kind,
142.15 - * express or implied, and with no claim as to its suitability for any
142.16 - * purpose.
142.17 - *
142.18 - */
142.19 -
142.20 -#ifndef LEMON_BIN_HEAP_H
142.21 -#define LEMON_BIN_HEAP_H
142.22 -
142.23 -///\ingroup auxdat
142.24 -///\file
142.25 -///\brief Binary Heap implementation.
142.26 -
142.27 -#include <vector>
142.28 -#include <utility>
142.29 -#include <functional>
142.30 -
142.31 -namespace lemon {
142.32 -
142.33 - /// \addtogroup auxdat
142.34 - /// @{
142.35 -
142.36 - /// A Binary Heap implementation.
142.37 -
142.38 - ///This class implements the \e binary \e heap data structure. A \e heap
142.39 - ///is a data structure for storing items with specified values called \e
142.40 - ///priorities in such a way that finding the item with minimum priority is
142.41 - ///efficient. \c Compare specifies the ordering of the priorities. In a heap
142.42 - ///one can change the priority of an item, add or erase an item, etc.
142.43 - ///
142.44 - ///\param Item Type of the items to be stored.
142.45 - ///\param Prio Type of the priority of the items.
142.46 - ///\param ItemIntMap A read and writable Item int map, used internally
142.47 - ///to handle the cross references.
142.48 - ///\param Compare A class for the ordering of the priorities. The
142.49 - ///default is \c std::less<Prio>.
142.50 - ///
142.51 - ///\sa FibHeap
142.52 - ///\sa Dijkstra
142.53 - template <typename Item, typename Prio, typename ItemIntMap,
142.54 - typename Compare = std::less<Prio> >
142.55 - class BinHeap {
142.56 -
142.57 - public:
142.58 - typedef Item ItemType;
142.59 - // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot...
142.60 - typedef Prio PrioType;
142.61 - typedef std::pair<ItemType,PrioType> PairType;
142.62 - typedef ItemIntMap ItemIntMapType;
142.63 - typedef Compare PrioCompare;
142.64 -
142.65 - /// \brief Type to represent the items states.
142.66 - ///
142.67 - /// Each Item element have a state associated to it. It may be "in heap",
142.68 - /// "pre heap" or "post heap". The latter two are indifferent from the
142.69 - /// heap's point of view, but may be useful to the user.
142.70 - ///
142.71 - /// The ItemIntMap \e should be initialized in such way that it maps
142.72 - /// PRE_HEAP (-1) to any element to be put in the heap...
142.73 - enum state_enum {
142.74 - IN_HEAP = 0,
142.75 - PRE_HEAP = -1,
142.76 - POST_HEAP = -2
142.77 - };
142.78 -
142.79 - private:
142.80 - std::vector<PairType> data;
142.81 - Compare comp;
142.82 - ItemIntMap &iim;
142.83 -
142.84 - public:
142.85 - /// \brief The constructor.
142.86 - ///
142.87 - /// The constructor.
142.88 - /// \param _iim should be given to the constructor, since it is used
142.89 - /// internally to handle the cross references. The value of the map
142.90 - /// should be PRE_HEAP (-1) for each element.
142.91 - explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
142.92 -
142.93 - /// \brief The constructor.
142.94 - ///
142.95 - /// The constructor.
142.96 - /// \param _iim should be given to the constructor, since it is used
142.97 - /// internally to handle the cross references. The value of the map
142.98 - /// should be PRE_HEAP (-1) for each element.
142.99 - ///
142.100 - /// \param _comp The comparator function object.
142.101 - BinHeap(ItemIntMap &_iim, const Compare &_comp)
142.102 - : iim(_iim), comp(_comp) {}
142.103 -
142.104 -
142.105 - /// The number of items stored in the heap.
142.106 - ///
142.107 - /// \brief Returns the number of items stored in the heap.
142.108 - int size() const { return data.size(); }
142.109 -
142.110 - /// \brief Checks if the heap stores no items.
142.111 - ///
142.112 - /// Returns \c true if and only if the heap stores no items.
142.113 - bool empty() const { return data.empty(); }
142.114 -
142.115 - private:
142.116 - static int parent(int i) { return (i-1)/2; }
142.117 - static int second_child(int i) { return 2*i+2; }
142.118 - bool less(const PairType &p1, const PairType &p2) const {
142.119 - return comp(p1.second, p2.second);
142.120 - }
142.121 -
142.122 - int bubble_up(int hole, PairType p);
142.123 - int bubble_down(int hole, PairType p, int length);
142.124 -
142.125 - void move(const PairType &p, int i) {
142.126 - data[i] = p;
142.127 - iim.set(p.first, i);
142.128 - }
142.129 -
142.130 - void rmidx(int h) {
142.131 - int n = data.size()-1;
142.132 - if( h>=0 && h<=n ) {
142.133 - iim.set(data[h].first, POST_HEAP);
142.134 - if ( h<n ) {
142.135 - bubble_down(h, data[n], n);
142.136 - }
142.137 - data.pop_back();
142.138 - }
142.139 - }
142.140 -
142.141 - public:
142.142 - /// \brief Insert a pair of item and priority into the heap.
142.143 - ///
142.144 - /// Adds \c p.first to the heap with priority \c p.second.
142.145 - /// \param p The pair to insert.
142.146 - void push(const PairType &p) {
142.147 - int n = data.size();
142.148 - data.resize(n+1);
142.149 - bubble_up(n, p);
142.150 - }
142.151 -
142.152 - /// \brief Insert an item into the heap with the given heap.
142.153 - ///
142.154 - /// Adds \c i to the heap with priority \c p.
142.155 - /// \param i The item to insert.
142.156 - /// \param p The priority of the item.
142.157 - void push(const Item &i, const Prio &p) { push(PairType(i,p)); }
142.158 -
142.159 - /// \brief Returns the item with minimum priority relative to \c Compare.
142.160 - ///
142.161 - /// This method returns the item with minimum priority relative to \c
142.162 - /// Compare.
142.163 - /// \pre The heap must be nonempty.
142.164 - Item top() const {
142.165 - return data[0].first;
142.166 - }
142.167 -
142.168 - /// \brief Returns the minimum priority relative to \c Compare.
142.169 - ///
142.170 - /// It returns the minimum priority relative to \c Compare.
142.171 - /// \pre The heap must be nonempty.
142.172 - Prio prio() const {
142.173 - return data[0].second;
142.174 - }
142.175 -
142.176 - /// \brief Deletes the item with minimum priority relative to \c Compare.
142.177 - ///
142.178 - /// This method deletes the item with minimum priority relative to \c
142.179 - /// Compare from the heap.
142.180 - /// \pre The heap must be non-empty.
142.181 - void pop() {
142.182 - rmidx(0);
142.183 - }
142.184 -
142.185 - /// \brief Deletes \c i from the heap.
142.186 - ///
142.187 - /// This method deletes item \c i from the heap, if \c i was
142.188 - /// already stored in the heap.
142.189 - /// \param i The item to erase.
142.190 - void erase(const Item &i) {
142.191 - rmidx(iim[i]);
142.192 - }
142.193 -
142.194 -
142.195 - /// \brief Returns the priority of \c i.
142.196 - ///
142.197 - /// This function returns the priority of item \c i.
142.198 - /// \pre \c i must be in the heap.
142.199 - /// \param i The item.
142.200 - Prio operator[](const Item &i) const {
142.201 - int idx = iim[i];
142.202 - return data[idx].second;
142.203 - }
142.204 -
142.205 - /// \brief \c i gets to the heap with priority \c p independently
142.206 - /// if \c i was already there.
142.207 - ///
142.208 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
142.209 - /// in the heap and sets the priority of \c i to \c p otherwise.
142.210 - /// \param i The item.
142.211 - /// \param p The priority.
142.212 - void set(const Item &i, const Prio &p) {
142.213 - int idx = iim[i];
142.214 - if( idx < 0 ) {
142.215 - push(i,p);
142.216 - }
142.217 - else if( comp(p, data[idx].second) ) {
142.218 - bubble_up(idx, PairType(i,p));
142.219 - }
142.220 - else {
142.221 - bubble_down(idx, PairType(i,p), data.size());
142.222 - }
142.223 - }
142.224 -
142.225 - /// \brief Decreases the priority of \c i to \c p.
142.226 -
142.227 - /// This method decreases the priority of item \c i to \c p.
142.228 - /// \pre \c i must be stored in the heap with priority at least \c
142.229 - /// p relative to \c Compare.
142.230 - /// \param i The item.
142.231 - /// \param p The priority.
142.232 - void decrease(const Item &i, const Prio &p) {
142.233 - int idx = iim[i];
142.234 - bubble_up(idx, PairType(i,p));
142.235 - }
142.236 -
142.237 - /// \brief Increases the priority of \c i to \c p.
142.238 - ///
142.239 - /// This method sets the priority of item \c i to \c p.
142.240 - /// \pre \c i must be stored in the heap with priority at most \c
142.241 - /// p relative to \c Compare.
142.242 - /// \param i The item.
142.243 - /// \param p The priority.
142.244 - void increase(const Item &i, const Prio &p) {
142.245 - int idx = iim[i];
142.246 - bubble_down(idx, PairType(i,p), data.size());
142.247 - }
142.248 -
142.249 - /// \brief Returns if \c item is in, has already been in, or has
142.250 - /// never been in the heap.
142.251 - ///
142.252 - /// This method returns PRE_HEAP if \c item has never been in the
142.253 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
142.254 - /// otherwise. In the latter case it is possible that \c item will
142.255 - /// get back to the heap again.
142.256 - /// \param i The item.
142.257 - state_enum state(const Item &i) const {
142.258 - int s = iim[i];
142.259 - if( s>=0 )
142.260 - s=0;
142.261 - return state_enum(s);
142.262 - }
142.263 -
142.264 - }; // class BinHeap
142.265 -
142.266 -
142.267 - template <typename K, typename V, typename M, typename C>
142.268 - int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) {
142.269 - int par = parent(hole);
142.270 - while( hole>0 && less(p,data[par]) ) {
142.271 - move(data[par],hole);
142.272 - hole = par;
142.273 - par = parent(hole);
142.274 - }
142.275 - move(p, hole);
142.276 - return hole;
142.277 - }
142.278 -
142.279 - template <typename K, typename V, typename M, typename C>
142.280 - int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) {
142.281 - int child = second_child(hole);
142.282 - while(child < length) {
142.283 - if( less(data[child-1], data[child]) ) {
142.284 - --child;
142.285 - }
142.286 - if( !less(data[child], p) )
142.287 - goto ok;
142.288 - move(data[child], hole);
142.289 - hole = child;
142.290 - child = second_child(hole);
142.291 - }
142.292 - child--;
142.293 - if( child<length && less(data[child], p) ) {
142.294 - move(data[child], hole);
142.295 - hole=child;
142.296 - }
142.297 - ok:
142.298 - move(p, hole);
142.299 - return hole;
142.300 - }
142.301 -
142.302 - ///@}
142.303 -
142.304 -} // namespace lemon
142.305 -
142.306 -#endif // LEMON_BIN_HEAP_H
143.1 --- a/src/lemon/bits/alteration_notifier.h Sat May 21 21:04:57 2005 +0000
143.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
143.3 @@ -1,438 +0,0 @@
143.4 -/* -*- C++ -*-
143.5 - * src/lemon/notifier.h - Part of LEMON, a generic C++ optimization library
143.6 - *
143.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
143.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
143.9 - *
143.10 - * Permission to use, modify and distribute this software is granted
143.11 - * provided that this copyright notice appears in all copies. For
143.12 - * precise terms see the accompanying LICENSE file.
143.13 - *
143.14 - * This software is provided "AS IS" with no warranty of any kind,
143.15 - * express or implied, and with no claim as to its suitability for any
143.16 - * purpose.
143.17 - *
143.18 - */
143.19 -
143.20 -#ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
143.21 -#define LEMON_ALTERATION_OBSERVER_REGISTRY_H
143.22 -
143.23 -#include <vector>
143.24 -#include <algorithm>
143.25 -
143.26 -///\ingroup graphmaps
143.27 -///\file
143.28 -///\brief Observer registry for graph alteration observers.
143.29 -
143.30 -namespace lemon {
143.31 -
143.32 - /// \addtogroup graphmaps
143.33 - /// @{
143.34 -
143.35 - /// \brief Registry class to register objects observes alterations in
143.36 - /// the graph.
143.37 - ///
143.38 - /// This class is a registry for the objects which observe the
143.39 - /// alterations in a container. The alteration observers can be attached
143.40 - /// to and detached from the registry. The observers have to inherit
143.41 - /// from the \ref AlterationNotifier::ObserverBase and override
143.42 - /// the virtual functions in that.
143.43 - ///
143.44 - /// The most important application of the alteration observing is the
143.45 - /// dynamic map implementation.
143.46 - ///
143.47 - /// \param _Item The item type what the observers are observing, usually
143.48 - /// edge or node.
143.49 - ///
143.50 - /// \author Balazs Dezso
143.51 -
143.52 - template <typename _Item>
143.53 - class AlterationNotifier {
143.54 - public:
143.55 - typedef _Item Item;
143.56 -
143.57 - /// ObserverBase is the base class for the observers.
143.58 -
143.59 - /// ObserverBase is the abstract base class for the observers.
143.60 - /// It will be notified about an item was inserted into or
143.61 - /// erased from the graph.
143.62 - ///
143.63 - /// The observer interface contains some pure virtual functions
143.64 - /// to override. The add() and erase() functions are
143.65 - /// to notify the oberver when one item is added or
143.66 - /// erased.
143.67 - ///
143.68 - /// The build() and clear() members are to notify the observer
143.69 - /// about the container is built from an empty container or
143.70 - /// is cleared to an empty container.
143.71 - ///
143.72 - /// \author Balazs Dezso
143.73 -
143.74 - class ObserverBase {
143.75 - protected:
143.76 - typedef AlterationNotifier Registry;
143.77 -
143.78 - friend class AlterationNotifier;
143.79 -
143.80 - /// \brief Default constructor.
143.81 - ///
143.82 - /// Default constructor for ObserverBase.
143.83 - ///
143.84 - ObserverBase() : registry(0) {}
143.85 -
143.86 - virtual ~ObserverBase() {}
143.87 -
143.88 - /// \brief Attaches the observer into an AlterationNotifier.
143.89 - ///
143.90 - /// This member attaches the observer into an AlterationNotifier.
143.91 - ///
143.92 - void attach(AlterationNotifier& r) {
143.93 - registry = &r;
143.94 - registry->attach(*this);
143.95 - }
143.96 -
143.97 - /// \brief Detaches the observer into an AlterationNotifier.
143.98 - ///
143.99 - /// This member detaches the observer from an AlterationNotifier.
143.100 - ///
143.101 - void detach() {
143.102 - if (registry) {
143.103 - registry->detach(*this);
143.104 - }
143.105 - }
143.106 -
143.107 -
143.108 - /// Gives back a pointer to the registry what the map attached into.
143.109 -
143.110 - /// This function gives back a pointer to the registry what the map
143.111 - /// attached into.
143.112 - ///
143.113 - Registry* getRegistry() const { return const_cast<Registry*>(registry); }
143.114 -
143.115 - /// Gives back true when the observer is attached into a registry.
143.116 - bool attached() const { return registry != 0; }
143.117 -
143.118 - private:
143.119 -
143.120 - ObserverBase(const ObserverBase& copy);
143.121 - ObserverBase& operator=(const ObserverBase& copy);
143.122 -
143.123 - protected:
143.124 -
143.125 - Registry* registry;
143.126 - int registry_index;
143.127 -
143.128 - public:
143.129 -
143.130 - /// \brief The member function to notificate the observer about an
143.131 - /// item is added to the container.
143.132 - ///
143.133 - /// The add() member function notificates the observer about an item
143.134 - /// is added to the container. It have to be overrided in the
143.135 - /// subclasses.
143.136 -
143.137 - virtual void add(const Item&) = 0;
143.138 -
143.139 - /// \brief The member function to notificate the observer about
143.140 - /// simulitem is added to the container.
143.141 - ///
143.142 - /// The add() member function notificates the observer about an item
143.143 - /// is added to the container. It have to be overrided in the
143.144 - /// subclasses.
143.145 -
143.146 - virtual void add(const std::vector<Item>& items) {
143.147 - for (int i = 0; i < (int)items.size(); ++i) {
143.148 - add(items[i]);
143.149 - }
143.150 - }
143.151 -
143.152 - /// \brief The member function to notificate the observer about an
143.153 - /// item is erased from the container.
143.154 - ///
143.155 - /// The erase() member function notificates the observer about an
143.156 - /// item is erased from the container. It have to be overrided in
143.157 - /// the subclasses.
143.158 -
143.159 - virtual void erase(const Item&) = 0;
143.160 -
143.161 - virtual void erase(const std::vector<Item>& items) {
143.162 - for (int i = 0; i < (int)items.size(); ++i) {
143.163 - add(items[i]);
143.164 - }
143.165 - }
143.166 -
143.167 - /// \brief The member function to notificate the observer about the
143.168 - /// container is built.
143.169 - ///
143.170 - /// The build() member function notificates the observer about the
143.171 - /// container is built from an empty container. It have to be
143.172 - /// overrided in the subclasses.
143.173 -
143.174 - virtual void build() = 0;
143.175 -
143.176 - /// \brief The member function to notificate the observer about all
143.177 - /// items are erased from the container.
143.178 - ///
143.179 - /// The clear() member function notificates the observer about all
143.180 - /// items are erased from the container. It have to be overrided in
143.181 - /// the subclasses.
143.182 -
143.183 - virtual void clear() = 0;
143.184 -
143.185 - };
143.186 -
143.187 - protected:
143.188 -
143.189 -
143.190 - typedef std::vector<ObserverBase*> Container;
143.191 -
143.192 - Container container;
143.193 -
143.194 -
143.195 - public:
143.196 -
143.197 - /// Default constructor.
143.198 -
143.199 - ///
143.200 - /// The default constructor of the AlterationNotifier.
143.201 - /// It creates an empty registry.
143.202 - AlterationNotifier() {}
143.203 -
143.204 - /// Copy Constructor of the AlterationNotifier.
143.205 -
143.206 - /// Copy constructor of the AlterationNotifier.
143.207 - /// It creates only an empty registry because the copiable
143.208 - /// registry's observers have to be registered still into that registry.
143.209 - AlterationNotifier(const AlterationNotifier&) {}
143.210 -
143.211 - /// Assign operator.
143.212 -
143.213 - /// Assign operator for the AlterationNotifier.
143.214 - /// It makes the notifier only empty because the copiable
143.215 - /// notifier's observers have to be registered still into that registry.
143.216 - AlterationNotifier& operator=(const AlterationNotifier&) {
143.217 - typename Container::iterator it;
143.218 - for (it = container.begin(); it != container.end(); ++it) {
143.219 - (*it)->registry = 0;
143.220 - }
143.221 - }
143.222 -
143.223 - /// Destructor.
143.224 -
143.225 - /// Destructor of the AlterationNotifier.
143.226 - ///
143.227 - ~AlterationNotifier() {
143.228 - typename Container::iterator it;
143.229 - for (it = container.begin(); it != container.end(); ++it) {
143.230 - (*it)->registry = 0;
143.231 - }
143.232 - }
143.233 -
143.234 -
143.235 - protected:
143.236 -
143.237 - void attach(ObserverBase& observer) {
143.238 - container.push_back(&observer);
143.239 - observer.registry = this;
143.240 - observer.registry_index = container.size()-1;
143.241 - }
143.242 -
143.243 - void detach(ObserverBase& base) {
143.244 - container.back()->registry_index = base.registry_index;
143.245 - container[base.registry_index] = container.back();
143.246 - container.pop_back();
143.247 - base.registry = 0;
143.248 - }
143.249 -
143.250 - public:
143.251 -
143.252 - /// \brief Notifies all the registered observers about an Item added to
143.253 - /// the container.
143.254 - ///
143.255 - /// It notifies all the registered observers about an Item added to
143.256 - /// the container.
143.257 - ///
143.258 - void add(const Item& item) {
143.259 - typename Container::iterator it;
143.260 - for (it = container.begin(); it != container.end(); ++it) {
143.261 - (*it)->add(item);
143.262 - }
143.263 - }
143.264 -
143.265 - /// \brief Notifies all the registered observers about more Item added to
143.266 - /// the container.
143.267 - ///
143.268 - /// It notifies all the registered observers about more Item added to
143.269 - /// the container.
143.270 - ///
143.271 - void add(const std::vector<Item>& items) {
143.272 - typename Container::iterator it;
143.273 - for (it = container.begin(); it != container.end(); ++it) {
143.274 - (*it)->add(items);
143.275 - }
143.276 - }
143.277 -
143.278 - /// \brief Notifies all the registered observers about an Item erased from
143.279 - /// the container.
143.280 - ///
143.281 - /// It notifies all the registered observers about an Item erased from
143.282 - /// the container.
143.283 - ///
143.284 - void erase(const Item& key) {
143.285 - typename Container::iterator it;
143.286 - for (it = container.begin(); it != container.end(); ++it) {
143.287 - (*it)->erase(key);
143.288 - }
143.289 - }
143.290 -
143.291 - /// \brief Notifies all the registered observers about more Item erased
143.292 - /// from the container.
143.293 - ///
143.294 - /// It notifies all the registered observers about more Item erased from
143.295 - /// the container.
143.296 - ///
143.297 - void erase(const std::vector<Item>& items) {
143.298 - typename Container::iterator it;
143.299 - for (it = container.begin(); it != container.end(); ++it) {
143.300 - (*it)->erase(items);
143.301 - }
143.302 - }
143.303 -
143.304 -
143.305 - /// \brief Notifies all the registered observers about the container is
143.306 - /// built.
143.307 - ///
143.308 - /// Notifies all the registered observers about the container is built
143.309 - /// from an empty container.
143.310 - void build() {
143.311 - typename Container::iterator it;
143.312 - for (it = container.begin(); it != container.end(); ++it) {
143.313 - (*it)->build();
143.314 - }
143.315 - }
143.316 -
143.317 -
143.318 - /// \brief Notifies all the registered observers about all Items are
143.319 - /// erased.
143.320 - ///
143.321 - /// Notifies all the registered observers about all Items are erased
143.322 - /// from the container.
143.323 - void clear() {
143.324 - typename Container::iterator it;
143.325 - for (it = container.begin(); it != container.end(); ++it) {
143.326 - (*it)->clear();
143.327 - }
143.328 - }
143.329 - };
143.330 -
143.331 -
143.332 - /// \brief Class to extend a graph with the functionality of alteration
143.333 - /// observing.
143.334 - ///
143.335 - /// AlterableGraphExtender extends the _Base graphs functionality with
143.336 - /// the possibility of alteration observing. It defines two observer
143.337 - /// registrys for the nodes and mapes.
143.338 - ///
143.339 - /// \todo Document what "alteration observing" is. And probably find a
143.340 - /// better (shorter) name.
143.341 - ///
143.342 - /// \param _Base is the base class to extend.
143.343 - ///
143.344 - /// \pre _Base is conform to the BaseGraphComponent concept.
143.345 - ///
143.346 - /// \post AlterableGraphExtender<_Base> is conform to the
143.347 - /// AlterableGraphComponent concept.
143.348 - ///
143.349 - /// \author Balazs Dezso
143.350 -
143.351 - template <typename _Base>
143.352 - class AlterableGraphExtender : public _Base {
143.353 - public:
143.354 -
143.355 - typedef AlterableGraphExtender Graph;
143.356 - typedef _Base Parent;
143.357 -
143.358 - typedef typename Parent::Node Node;
143.359 - typedef typename Parent::Edge Edge;
143.360 -
143.361 - /// The edge observer registry.
143.362 - typedef AlterationNotifier<Edge> EdgeNotifier;
143.363 - /// The node observer registry.
143.364 - typedef AlterationNotifier<Node> NodeNotifier;
143.365 -
143.366 -
143.367 - protected:
143.368 -
143.369 - mutable EdgeNotifier edge_notifier;
143.370 -
143.371 - mutable NodeNotifier node_notifier;
143.372 -
143.373 - public:
143.374 -
143.375 - /// \brief Gives back the edge alteration notifier.
143.376 - ///
143.377 - /// Gives back the edge alteration notifier.
143.378 - EdgeNotifier& getNotifier(Edge) const {
143.379 - return edge_notifier;
143.380 - }
143.381 -
143.382 - /// \brief Gives back the node alteration notifier.
143.383 - ///
143.384 - /// Gives back the node alteration notifier.
143.385 - NodeNotifier& getNotifier(Node) const {
143.386 - return node_notifier;
143.387 - }
143.388 -
143.389 - ~AlterableGraphExtender() {
143.390 - node_notifier.clear();
143.391 - edge_notifier.clear();
143.392 - }
143.393 -
143.394 - };
143.395 -
143.396 - /// \brief Class to extend an undirected graph with the functionality of
143.397 - /// alteration observing.
143.398 - ///
143.399 - /// \todo Document.
143.400 - ///
143.401 - /// \sa AlterableGraphExtender
143.402 - ///
143.403 - /// \bug This should be done some other way. Possibilities: template
143.404 - /// specialization (not very easy, if at all possible); some kind of
143.405 - /// enable_if boost technique?
143.406 -
143.407 - template <typename _Base>
143.408 - class AlterableUndirGraphExtender
143.409 - : public AlterableGraphExtender<_Base> {
143.410 - public:
143.411 -
143.412 - typedef AlterableUndirGraphExtender Graph;
143.413 - typedef AlterableGraphExtender<_Base> Parent;
143.414 -
143.415 - typedef typename Parent::UndirEdge UndirEdge;
143.416 -
143.417 - /// The edge observer registry.
143.418 - typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
143.419 -
143.420 - protected:
143.421 -
143.422 - mutable UndirEdgeNotifier undir_edge_notifier;
143.423 -
143.424 - public:
143.425 -
143.426 - using Parent::getNotifier;
143.427 - UndirEdgeNotifier& getNotifier(UndirEdge) const {
143.428 - return undir_edge_notifier;
143.429 - }
143.430 -
143.431 - ~AlterableUndirGraphExtender() {
143.432 - undir_edge_notifier.clear();
143.433 - }
143.434 - };
143.435 -
143.436 -/// @}
143.437 -
143.438 -
143.439 -}
143.440 -
143.441 -#endif
144.1 --- a/src/lemon/bits/array_map.h Sat May 21 21:04:57 2005 +0000
144.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
144.3 @@ -1,369 +0,0 @@
144.4 -/* -*- C++ -*-
144.5 - * src/lemon/bits/array_map.h - Part of LEMON, a generic C++ optimization library
144.6 - *
144.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
144.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
144.9 - *
144.10 - * Permission to use, modify and distribute this software is granted
144.11 - * provided that this copyright notice appears in all copies. For
144.12 - * precise terms see the accompanying LICENSE file.
144.13 - *
144.14 - * This software is provided "AS IS" with no warranty of any kind,
144.15 - * express or implied, and with no claim as to its suitability for any
144.16 - * purpose.
144.17 - *
144.18 - */
144.19 -
144.20 -#ifndef LEMON_ARRAY_MAP_H
144.21 -#define LEMON_ARRAY_MAP_H
144.22 -
144.23 -#include <memory>
144.24 -#include <lemon/bits/map_iterator.h>
144.25 -
144.26 -///\ingroup graphmaps
144.27 -///\file
144.28 -///\brief Graph maps that construates and destruates
144.29 -///their elements dynamically.
144.30 -
144.31 -namespace lemon {
144.32 -
144.33 -
144.34 - /// \addtogroup graphmaps
144.35 - /// @{
144.36 -
144.37 - /// The ArrayMap template class is graph map structure what
144.38 - /// automatically updates the map when a key is added to or erased from
144.39 - /// the map. This map factory uses the allocators to implement
144.40 - /// the container functionality.
144.41 - ///
144.42 - /// The template parameter is the AlterationNotifier that the maps
144.43 - /// will belong to and the Value.
144.44 -
144.45 -
144.46 - template <typename _Graph,
144.47 - typename _Item,
144.48 - typename _Value>
144.49 - class ArrayMap : public AlterationNotifier<_Item>::ObserverBase {
144.50 -
144.51 - typedef _Item Item;
144.52 - public:
144.53 -
144.54 - /// The graph type of the maps.
144.55 - typedef _Graph Graph;
144.56 - /// The key type of the maps.
144.57 - typedef _Item Key;
144.58 -
144.59 - typedef AlterationNotifier<_Item> Registry;
144.60 -
144.61 - /// The MapBase of the Map which imlements the core regisitry function.
144.62 - typedef typename Registry::ObserverBase Parent;
144.63 -
144.64 - /// The value type of the map.
144.65 - typedef _Value Value;
144.66 -
144.67 -
144.68 - private:
144.69 - typedef std::allocator<Value> Allocator;
144.70 -
144.71 -
144.72 - public:
144.73 -
144.74 - /// Graph and Registry initialized map constructor.
144.75 -
144.76 - ArrayMap(const Graph& _g) : graph(&_g) {
144.77 - Item it;
144.78 - attach(_g.getNotifier(Item()));
144.79 - allocate_memory();
144.80 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.81 - int id = graph->id(it);;
144.82 - allocator.construct(&(values[id]), Value());
144.83 - }
144.84 - }
144.85 -
144.86 - /// Constructor to use default value to initialize the map.
144.87 -
144.88 - /// It constrates a map and initialize all of the the map.
144.89 -
144.90 - ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
144.91 - Item it;
144.92 - attach(_g.getNotifier(_Item()));
144.93 - allocate_memory();
144.94 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.95 - int id = graph->id(it);;
144.96 - allocator.construct(&(values[id]), _v);
144.97 - }
144.98 - }
144.99 -
144.100 - /// Constructor to copy a map of the same map type.
144.101 -
144.102 - ArrayMap(const ArrayMap& copy) : Parent() {
144.103 - if (copy.attached()) {
144.104 - attach(*copy.getRegistry());
144.105 - }
144.106 - capacity = copy.capacity;
144.107 - if (capacity == 0) return;
144.108 - values = allocator.allocate(capacity);
144.109 - Item it;
144.110 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.111 - int id = graph->id(it);;
144.112 - allocator.construct(&(values[id]), copy.values[id]);
144.113 - }
144.114 - }
144.115 -
144.116 - using Parent::attach;
144.117 - using Parent::detach;
144.118 - using Parent::attached;
144.119 -
144.120 - /// Assign operator to copy a map of the same map type.
144.121 -
144.122 - ArrayMap& operator=(const ArrayMap& copy) {
144.123 - if (© == this) return *this;
144.124 -
144.125 - if (graph != copy.graph) {
144.126 - if (attached()) {
144.127 - clear();
144.128 - detach();
144.129 - }
144.130 - if (copy.attached()) {
144.131 - attach(*copy.getRegistry());
144.132 - }
144.133 - capacity = copy.capacity;
144.134 - if (capacity == 0) return *this;
144.135 - values = allocator.allocate(capacity);
144.136 - }
144.137 -
144.138 - Item it;
144.139 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.140 - int id = graph->id(it);;
144.141 - allocator.construct(&(values[id]), copy.values[id]);
144.142 - }
144.143 -
144.144 - return *this;
144.145 - }
144.146 -
144.147 - /// The destructor of the map.
144.148 -
144.149 - virtual ~ArrayMap() {
144.150 - if (attached()) {
144.151 - clear();
144.152 - detach();
144.153 - }
144.154 - }
144.155 -
144.156 -
144.157 - ///The subscript operator. The map can be subscripted by the
144.158 - ///actual keys of the graph.
144.159 -
144.160 - Value& operator[](const Key& key) {
144.161 - int id = graph->id(key);
144.162 - return values[id];
144.163 - }
144.164 -
144.165 -
144.166 - ///The const subscript operator. The map can be subscripted by the
144.167 - ///actual keys of the graph.
144.168 -
144.169 - const Value& operator[](const Key& key) const {
144.170 - int id = graph->id(key);
144.171 - return values[id];
144.172 - }
144.173 -
144.174 - /// Setter function of the map. Equivalent with map[key] = val.
144.175 - /// This is a compatibility feature with the not dereferable maps.
144.176 -
144.177 - void set(const Key& key, const Value& val) {
144.178 - (*this)[key] = val;
144.179 - }
144.180 -
144.181 - /// Add a new key to the map. It called by the map registry.
144.182 -
144.183 - void add(const Key& key) {
144.184 - int id = graph->id(key);
144.185 - if (id >= capacity) {
144.186 - int new_capacity = (capacity == 0 ? 1 : capacity);
144.187 - while (new_capacity <= id) {
144.188 - new_capacity <<= 1;
144.189 - }
144.190 - Value* new_values = allocator.allocate(new_capacity);
144.191 - Item it;
144.192 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.193 - int jd = graph->id(it);;
144.194 - if (id != jd) {
144.195 - allocator.construct(&(new_values[jd]), values[jd]);
144.196 - allocator.destroy(&(values[jd]));
144.197 - }
144.198 - }
144.199 - if (capacity != 0) allocator.deallocate(values, capacity);
144.200 - values = new_values;
144.201 - capacity = new_capacity;
144.202 - }
144.203 - allocator.construct(&(values[id]), Value());
144.204 - }
144.205 -
144.206 - void add(const std::vector<Key>& keys) {
144.207 - int max_id = -1;
144.208 - for (int i = 0; i < (int)keys.size(); ++i) {
144.209 - int id = graph->id(keys[i]);
144.210 - if (id > max_id) {
144.211 - max_id = id;
144.212 - }
144.213 - }
144.214 - if (max_id >= capacity) {
144.215 - int new_capacity = (capacity == 0 ? 1 : capacity);
144.216 - while (new_capacity <= max_id) {
144.217 - new_capacity <<= 1;
144.218 - }
144.219 - Value* new_values = allocator.allocate(new_capacity);
144.220 - Item it;
144.221 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.222 - int id = graph->id(it);
144.223 - bool found = false;
144.224 - for (int i = 0; i < (int)keys.size(); ++i) {
144.225 - int jd = graph->id(keys[i]);
144.226 - if (id == jd) {
144.227 - found = true;
144.228 - break;
144.229 - }
144.230 - }
144.231 - if (found) continue;
144.232 - allocator.construct(&(new_values[id]), values[id]);
144.233 - allocator.destroy(&(values[id]));
144.234 - }
144.235 - if (capacity != 0) allocator.deallocate(values, capacity);
144.236 - values = new_values;
144.237 - capacity = new_capacity;
144.238 - }
144.239 - for (int i = 0; i < (int)keys.size(); ++i) {
144.240 - int id = graph->id(keys[i]);
144.241 - allocator.construct(&(values[id]), Value());
144.242 - }
144.243 - }
144.244 -
144.245 - /// Erase a key from the map. It called by the map registry.
144.246 -
144.247 - void erase(const Key& key) {
144.248 - int id = graph->id(key);
144.249 - allocator.destroy(&(values[id]));
144.250 - }
144.251 -
144.252 - void erase(const std::vector<Key>& keys) {
144.253 - for (int i = 0; i < (int)keys.size(); ++i) {
144.254 - int id = graph->id(keys[i]);
144.255 - allocator.destroy(&(values[id]));
144.256 - }
144.257 - }
144.258 -
144.259 - void build() {
144.260 - allocate_memory();
144.261 - Item it;
144.262 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.263 - int id = graph->id(it);;
144.264 - allocator.construct(&(values[id]), Value());
144.265 - }
144.266 - }
144.267 -
144.268 - void clear() {
144.269 - if (capacity != 0) {
144.270 - Item it;
144.271 - for (graph->first(it); it != INVALID; graph->next(it)) {
144.272 - int id = graph->id(it);
144.273 - allocator.destroy(&(values[id]));
144.274 - }
144.275 - allocator.deallocate(values, capacity);
144.276 - capacity = 0;
144.277 - }
144.278 - }
144.279 -
144.280 - const Graph* getGraph() {
144.281 - return graph;
144.282 - }
144.283 -
144.284 - private:
144.285 -
144.286 - void allocate_memory() {
144.287 - int max_id = graph->maxId(_Item());
144.288 - if (max_id == -1) {
144.289 - capacity = 0;
144.290 - values = 0;
144.291 - return;
144.292 - }
144.293 - capacity = 1;
144.294 - while (capacity <= max_id) {
144.295 - capacity <<= 1;
144.296 - }
144.297 - values = allocator.allocate(capacity);
144.298 - }
144.299 -
144.300 - const Graph* graph;
144.301 - int capacity;
144.302 - Value* values;
144.303 - Allocator allocator;
144.304 -
144.305 - };
144.306 -
144.307 - template <typename _Base>
144.308 - class ArrayMappableGraphExtender : public _Base {
144.309 - public:
144.310 -
144.311 - typedef ArrayMappableGraphExtender<_Base> Graph;
144.312 - typedef _Base Parent;
144.313 -
144.314 - typedef typename Parent::Node Node;
144.315 - typedef typename Parent::NodeIt NodeIt;
144.316 - typedef typename Parent::NodeNotifier NodeObserverRegistry;
144.317 -
144.318 - typedef typename Parent::Edge Edge;
144.319 - typedef typename Parent::EdgeIt EdgeIt;
144.320 - typedef typename Parent::EdgeNotifier EdgeObserverRegistry;
144.321 -
144.322 -
144.323 -
144.324 - template <typename _Value>
144.325 - class NodeMap
144.326 - : public IterableMapExtender<ArrayMap<Graph, Node, _Value> > {
144.327 - public:
144.328 - typedef ArrayMappableGraphExtender<_Base> Graph;
144.329 -
144.330 - typedef typename Graph::Node Node;
144.331 - typedef typename Graph::NodeIt NodeIt;
144.332 -
144.333 - typedef IterableMapExtender<ArrayMap<Graph, Node, _Value> > Parent;
144.334 -
144.335 - //typedef typename Parent::Graph Graph;
144.336 - typedef typename Parent::Value Value;
144.337 -
144.338 - NodeMap(const Graph& g)
144.339 - : Parent(g) {}
144.340 - NodeMap(const Graph& g, const Value& v)
144.341 - : Parent(g, v) {}
144.342 -
144.343 - };
144.344 -
144.345 - template <typename _Value>
144.346 - class EdgeMap
144.347 - : public IterableMapExtender<ArrayMap<Graph, Edge, _Value> > {
144.348 - public:
144.349 - typedef ArrayMappableGraphExtender<_Base> Graph;
144.350 -
144.351 - typedef typename Graph::Edge Edge;
144.352 - typedef typename Graph::EdgeIt EdgeIt;
144.353 -
144.354 - typedef IterableMapExtender<ArrayMap<Graph, Edge, _Value> > Parent;
144.355 -
144.356 - //typedef typename Parent::Graph Graph;
144.357 - typedef typename Parent::Value Value;
144.358 -
144.359 - EdgeMap(const Graph& g)
144.360 - : Parent(g) {}
144.361 - EdgeMap(const Graph& g, const Value& v)
144.362 - : Parent(g, v) {}
144.363 -
144.364 - };
144.365 -
144.366 - };
144.367 -
144.368 -/// @}
144.369 -
144.370 -}
144.371 -
144.372 -#endif //LEMON_ARRAY_MAP_H
145.1 --- a/src/lemon/bits/clearable_graph_extender.h Sat May 21 21:04:57 2005 +0000
145.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
145.3 @@ -1,49 +0,0 @@
145.4 -// -*- c++ -*-
145.5 -
145.6 -#ifndef LEMON_CLEARABLE_GRAPH_EXTENDER_H
145.7 -#define LEMON_CLEARABLE_GRAPH_EXTENDER_H
145.8 -
145.9 -#include <lemon/invalid.h>
145.10 -
145.11 -
145.12 -namespace lemon {
145.13 -
145.14 - template <typename _Base>
145.15 - class ClearableGraphExtender : public _Base {
145.16 - public:
145.17 -
145.18 - typedef ClearableGraphExtender Graph;
145.19 - typedef _Base Parent;
145.20 - typedef typename Parent::Node Node;
145.21 - typedef typename Parent::Edge Edge;
145.22 -
145.23 - void clear() {
145.24 - Parent::getNotifier(Node()).clear();
145.25 - Parent::getNotifier(Edge()).clear();
145.26 - Parent::clear();
145.27 - }
145.28 -
145.29 - };
145.30 -
145.31 - template <typename _Base>
145.32 - class ClearableUndirGraphExtender : public _Base {
145.33 - public:
145.34 -
145.35 - typedef ClearableUndirGraphExtender Graph;
145.36 - typedef _Base Parent;
145.37 - typedef typename Parent::Node Node;
145.38 - typedef typename Parent::UndirEdge UndirEdge;
145.39 - typedef typename Parent::Edge Edge;
145.40 -
145.41 - void clear() {
145.42 - Parent::getNotifier(Node()).clear();
145.43 - Parent::getNotifier(UndirEdge()).clear();
145.44 - Parent::getNotifier(Edge()).clear();
145.45 - Parent::clear();
145.46 - }
145.47 -
145.48 - };
145.49 -
145.50 -}
145.51 -
145.52 -#endif
146.1 --- a/src/lemon/bits/default_map.h Sat May 21 21:04:57 2005 +0000
146.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
146.3 @@ -1,230 +0,0 @@
146.4 -/* -*- C++ -*-
146.5 - * src/lemon/default_map.h - Part of LEMON, a generic C++ optimization library
146.6 - *
146.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
146.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
146.9 - *
146.10 - * Permission to use, modify and distribute this software is granted
146.11 - * provided that this copyright notice appears in all copies. For
146.12 - * precise terms see the accompanying LICENSE file.
146.13 - *
146.14 - * This software is provided "AS IS" with no warranty of any kind,
146.15 - * express or implied, and with no claim as to its suitability for any
146.16 - * purpose.
146.17 - *
146.18 - */
146.19 -
146.20 -#ifndef LEMON_DEFAULT_MAP_H
146.21 -#define LEMON_DEFAULT_MAP_H
146.22 -
146.23 -
146.24 -#include <lemon/bits/array_map.h>
146.25 -#include <lemon/bits/vector_map.h>
146.26 -
146.27 -///\ingroup graphmaps
146.28 -///\file
146.29 -///\brief Graph maps that construct and destruct
146.30 -///their elements dynamically.
146.31 -
146.32 -namespace lemon {
146.33 -
146.34 -/// \addtogroup graphmaps
146.35 -/// @{
146.36 -
146.37 - /** The ArrayMap template class is graph map structure what
146.38 - * automatically updates the map when a key is added to or erased from
146.39 - * the map. This map uses the VectorMap if the Value is a primitive
146.40 - * type and the ArrayMap for the other cases.
146.41 - *
146.42 - * The template parameter is the MapRegistry that the maps
146.43 - * will belong to and the Value.
146.44 - */
146.45 -
146.46 -
146.47 -
146.48 - template <typename _Graph, typename _Item, typename _Value>
146.49 - struct DefaultMapSelector {
146.50 - typedef ArrayMap<_Graph, _Item, _Value> Map;
146.51 - };
146.52 -
146.53 - // bool
146.54 - template <typename _Graph, typename _Item>
146.55 - struct DefaultMapSelector<_Graph, _Item, bool> {
146.56 - typedef VectorMap<_Graph, _Item, bool> Map;
146.57 - };
146.58 -
146.59 - // char
146.60 - template <typename _Graph, typename _Item>
146.61 - struct DefaultMapSelector<_Graph, _Item, char> {
146.62 - typedef VectorMap<_Graph, _Item, char> Map;
146.63 - };
146.64 -
146.65 - template <typename _Graph, typename _Item>
146.66 - struct DefaultMapSelector<_Graph, _Item, signed char> {
146.67 - typedef VectorMap<_Graph, _Item, signed char> Map;
146.68 - };
146.69 -
146.70 - template <typename _Graph, typename _Item>
146.71 - struct DefaultMapSelector<_Graph, _Item, unsigned char> {
146.72 - typedef VectorMap<_Graph, _Item, unsigned char> Map;
146.73 - };
146.74 -
146.75 -
146.76 - // int
146.77 - template <typename _Graph, typename _Item>
146.78 - struct DefaultMapSelector<_Graph, _Item, signed int> {
146.79 - typedef VectorMap<_Graph, _Item, signed int> Map;
146.80 - };
146.81 -
146.82 - template <typename _Graph, typename _Item>
146.83 - struct DefaultMapSelector<_Graph, _Item, unsigned int> {
146.84 - typedef VectorMap<_Graph, _Item, unsigned int> Map;
146.85 - };
146.86 -
146.87 -
146.88 - // short
146.89 - template <typename _Graph, typename _Item>
146.90 - struct DefaultMapSelector<_Graph, _Item, signed short> {
146.91 - typedef VectorMap<_Graph, _Item, signed short> Map;
146.92 - };
146.93 -
146.94 - template <typename _Graph, typename _Item>
146.95 - struct DefaultMapSelector<_Graph, _Item, unsigned short> {
146.96 - typedef VectorMap<_Graph, _Item, unsigned short> Map;
146.97 - };
146.98 -
146.99 -
146.100 - // long
146.101 - template <typename _Graph, typename _Item>
146.102 - struct DefaultMapSelector<_Graph, _Item, signed long> {
146.103 - typedef VectorMap<_Graph, _Item, signed long> Map;
146.104 - };
146.105 -
146.106 - template <typename _Graph, typename _Item>
146.107 - struct DefaultMapSelector<_Graph, _Item, unsigned long> {
146.108 - typedef VectorMap<_Graph, _Item, unsigned long> Map;
146.109 - };
146.110 -
146.111 - // \todo handling long long type
146.112 -
146.113 -
146.114 - // float
146.115 - template <typename _Graph, typename _Item>
146.116 - struct DefaultMapSelector<_Graph, _Item, float> {
146.117 - typedef VectorMap<_Graph, _Item, float> Map;
146.118 - };
146.119 -
146.120 -
146.121 - // double
146.122 - template <typename _Graph, typename _Item>
146.123 - struct DefaultMapSelector<_Graph, _Item, double> {
146.124 - typedef VectorMap<_Graph, _Item, double> Map;
146.125 - };
146.126 -
146.127 -
146.128 - // long double
146.129 - template <typename _Graph, typename _Item>
146.130 - struct DefaultMapSelector<_Graph, _Item, long double> {
146.131 - typedef VectorMap<_Graph, _Item, long double> Map;
146.132 - };
146.133 -
146.134 -
146.135 - // pointer
146.136 - template <typename _Graph, typename _Item, typename _Ptr>
146.137 - struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
146.138 - typedef VectorMap<_Graph, _Item, _Ptr*> Map;
146.139 - };
146.140 -
146.141 -
146.142 -
146.143 - template <
146.144 - typename _Graph,
146.145 - typename _Item,
146.146 - typename _Value>
146.147 - class DefaultMap
146.148 - : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
146.149 - public:
146.150 - typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
146.151 - typedef DefaultMap<_Graph, _Item, _Value> Map;
146.152 -
146.153 - typedef typename Parent::Graph Graph;
146.154 - typedef typename Parent::Value Value;
146.155 -
146.156 - DefaultMap(const Graph& _g) : Parent(_g) {}
146.157 - DefaultMap(const Graph& _g, const Value& _v) : Parent(_g, _v) {}
146.158 - };
146.159 -
146.160 -
146.161 -
146.162 - template <typename _Base>
146.163 - class DefaultMappableGraphExtender : public _Base {
146.164 - public:
146.165 -
146.166 - typedef DefaultMappableGraphExtender<_Base> Graph;
146.167 - typedef _Base Parent;
146.168 -
146.169 - typedef typename Parent::Node Node;
146.170 - typedef typename Parent::NodeIt NodeIt;
146.171 -
146.172 - typedef typename Parent::Edge Edge;
146.173 - typedef typename Parent::EdgeIt EdgeIt;
146.174 -
146.175 -
146.176 - template <typename _Value>
146.177 - class NodeMap
146.178 - : public IterableMapExtender<DefaultMap<Graph, Node, _Value> > {
146.179 - public:
146.180 - typedef DefaultMappableGraphExtender Graph;
146.181 - typedef IterableMapExtender<DefaultMap<Graph, Node, _Value> > Parent;
146.182 -
146.183 - NodeMap(const Graph& _g)
146.184 - : Parent(_g) {}
146.185 - NodeMap(const Graph& _g, const _Value& _v)
146.186 - : Parent(_g, _v) {}
146.187 - };
146.188 -
146.189 - template <typename _Value>
146.190 - class EdgeMap
146.191 - : public IterableMapExtender<DefaultMap<Graph, Edge, _Value> > {
146.192 - public:
146.193 - typedef DefaultMappableGraphExtender Graph;
146.194 - typedef IterableMapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
146.195 -
146.196 - EdgeMap(const Graph& _g)
146.197 - : Parent(_g) {}
146.198 - EdgeMap(const Graph& _g, const _Value& _v)
146.199 - : Parent(_g, _v) {}
146.200 - };
146.201 -
146.202 - };
146.203 -
146.204 - template <typename _Base>
146.205 - class MappableUndirGraphExtender :
146.206 - public DefaultMappableGraphExtender<_Base> {
146.207 - public:
146.208 -
146.209 - typedef MappableUndirGraphExtender Graph;
146.210 - typedef DefaultMappableGraphExtender<_Base> Parent;
146.211 -
146.212 - typedef typename Parent::UndirEdge UndirEdge;
146.213 -
146.214 - template <typename _Value>
146.215 - class UndirEdgeMap
146.216 - : public IterableMapExtender<DefaultMap<Graph, UndirEdge, _Value> > {
146.217 - public:
146.218 - typedef MappableUndirGraphExtender Graph;
146.219 - typedef IterableMapExtender<
146.220 - DefaultMap<Graph, UndirEdge, _Value> > Parent;
146.221 -
146.222 - UndirEdgeMap(const Graph& _g)
146.223 - : Parent(_g) {}
146.224 - UndirEdgeMap(const Graph& _g, const _Value& _v)
146.225 - : Parent(_g, _v) {}
146.226 - };
146.227 -
146.228 -
146.229 - };
146.230 -
146.231 -}
146.232 -
146.233 -#endif
147.1 --- a/src/lemon/bits/erasable_graph_extender.h Sat May 21 21:04:57 2005 +0000
147.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
147.3 @@ -1,84 +0,0 @@
147.4 -// -*- c++ -*-
147.5 -
147.6 -#ifndef LEMON_ERASABLE_GRAPH_EXTENDER_H
147.7 -#define LEMON_ERASABLE_GRAPH_EXTENDER_H
147.8 -
147.9 -#include <vector>
147.10 -
147.11 -#include <lemon/invalid.h>
147.12 -
147.13 -
147.14 -namespace lemon {
147.15 -
147.16 - template <typename _Base>
147.17 - class ErasableGraphExtender : public _Base {
147.18 - public:
147.19 -
147.20 - typedef ErasableGraphExtender Graph;
147.21 - typedef _Base Parent;
147.22 -
147.23 - typedef typename Parent::Node Node;
147.24 - typedef typename Parent::Edge Edge;
147.25 -
147.26 - void erase(const Node& node) {
147.27 - Edge edge;
147.28 - Parent::firstOut(edge, node);
147.29 - while (edge != INVALID ) {
147.30 - erase(edge);
147.31 - Parent::firstOut(edge, node);
147.32 - }
147.33 -
147.34 - Parent::firstIn(edge, node);
147.35 - while (edge != INVALID ) {
147.36 - erase(edge);
147.37 - Parent::firstIn(edge, node);
147.38 - }
147.39 -
147.40 - Parent::getNotifier(Node()).erase(node);
147.41 - Parent::erase(node);
147.42 - }
147.43 -
147.44 - void erase(const Edge& edge) {
147.45 - Parent::getNotifier(Edge()).erase(edge);
147.46 - Parent::erase(edge);
147.47 - }
147.48 -
147.49 - };
147.50 -
147.51 - template <typename _Base>
147.52 - class ErasableUndirGraphExtender : public _Base {
147.53 - public:
147.54 -
147.55 - typedef ErasableUndirGraphExtender Graph;
147.56 - typedef _Base Parent;
147.57 -
147.58 - typedef typename Parent::Node Node;
147.59 - typedef typename Parent::UndirEdge UndirEdge;
147.60 - typedef typename Parent::Edge Edge;
147.61 -
147.62 - void erase(const Node& node) {
147.63 - Edge edge;
147.64 - Parent::firstOut(edge, node);
147.65 - while (edge != INVALID ) {
147.66 - erase(edge);
147.67 - Parent::firstOut(edge, node);
147.68 - }
147.69 -
147.70 - Parent::getNotifier(Node()).erase(node);
147.71 - Parent::erase(node);
147.72 - }
147.73 -
147.74 - void erase(const UndirEdge& uedge) {
147.75 - std::vector<Edge> edges;
147.76 - edges.push_back(Edge(uedge,true));
147.77 - edges.push_back(Edge(uedge,false));
147.78 - Parent::getNotifier(Edge()).erase(edges);
147.79 - Parent::getNotifier(UndirEdge()).erase(uedge);
147.80 - Parent::erase(uedge);
147.81 - }
147.82 -
147.83 - };
147.84 -
147.85 -}
147.86 -
147.87 -#endif
148.1 --- a/src/lemon/bits/extendable_graph_extender.h Sat May 21 21:04:57 2005 +0000
148.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
148.3 @@ -1,65 +0,0 @@
148.4 -// -*- c++ -*-
148.5 -
148.6 -#ifndef LEMON_EXTENDABLE_GRAPH_EXTENDER_H
148.7 -#define LEMON_EXTENDABLE_GRAPH_EXTENDER_H
148.8 -
148.9 -namespace lemon {
148.10 -
148.11 - template <typename _Base>
148.12 - class ExtendableGraphExtender : public _Base {
148.13 - public:
148.14 -
148.15 - typedef ExtendableGraphExtender Graph;
148.16 - typedef _Base Parent;
148.17 -
148.18 - typedef typename Parent::Node Node;
148.19 - typedef typename Parent::Edge Edge;
148.20 -
148.21 - Node addNode() {
148.22 - Node node = Parent::addNode();
148.23 - Parent::getNotifier(Node()).add(node);
148.24 - return node;
148.25 - }
148.26 -
148.27 - Edge addEdge(const Node& from, const Node& to) {
148.28 - Edge edge = Parent::addEdge(from, to);
148.29 - Parent::getNotifier(Edge()).add(edge);
148.30 - return edge;
148.31 - }
148.32 -
148.33 - };
148.34 -
148.35 - template <typename _Base>
148.36 - class ExtendableUndirGraphExtender : public _Base {
148.37 - public:
148.38 -
148.39 - typedef ExtendableUndirGraphExtender Graph;
148.40 - typedef _Base Parent;
148.41 -
148.42 - typedef typename Parent::Node Node;
148.43 - typedef typename Parent::Edge Edge;
148.44 - typedef typename Parent::UndirEdge UndirEdge;
148.45 -
148.46 - Node addNode() {
148.47 - Node node = Parent::addNode();
148.48 - Parent::getNotifier(Node()).add(node);
148.49 - return node;
148.50 - }
148.51 -
148.52 - UndirEdge addEdge(const Node& from, const Node& to) {
148.53 - UndirEdge uedge = Parent::addEdge(from, to);
148.54 - Parent::getNotifier(UndirEdge()).add(uedge);
148.55 -
148.56 - std::vector<Edge> edges;
148.57 - edges.push_back(Edge(uedge, true));
148.58 - edges.push_back(Edge(uedge, false));
148.59 - Parent::getNotifier(Edge()).add(edges);
148.60 -
148.61 - return uedge;
148.62 - }
148.63 -
148.64 - };
148.65 -
148.66 -}
148.67 -
148.68 -#endif
149.1 --- a/src/lemon/bits/extended_pair.h Sat May 21 21:04:57 2005 +0000
149.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
149.3 @@ -1,146 +0,0 @@
149.4 -/* -*- C++ -*-
149.5 - * src/lemon/bits/extended_pair.h - Part of LEMON, a generic C++ optimization library
149.6 - *
149.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
149.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
149.9 - *
149.10 - * Permission to use, modify and distribute this software is granted
149.11 - * provided that this copyright notice appears in all copies. For
149.12 - * precise terms see the accompanying LICENSE file.
149.13 - *
149.14 - * This software is provided "AS IS" with no warranty of any kind,
149.15 - * express or implied, and with no claim as to its suitability for any
149.16 - * purpose.
149.17 - *
149.18 - */
149.19 -
149.20 -#ifndef LEMON_EXTENDED_PAIR_H
149.21 -#define LEMON_EXTENDED_PAIR_H
149.22 -
149.23 -///\ingroup misc
149.24 -///\file
149.25 -///\brief A more customizable pair type than std::pair.
149.26 -
149.27 -namespace lemon {
149.28 -
149.29 - /// \brief A more customizable pair type than std::pair.
149.30 - ///
149.31 - /// This type is a customizable pair type. The main goal
149.32 - /// is that the constructor's parameter type does not depend
149.33 - /// on the stored data type. This way it is possible to store
149.34 - /// references in the extended_pair.
149.35 - /// \code
149.36 - /// int a; char b;
149.37 - /// typedef extended_pair<int&, int&, char&, char&> ICPair;
149.38 - /// ICPair p(a, b);
149.39 - /// // like a real reference to an std::pair<int, char>
149.40 - /// // but the pair does not exist
149.41 - /// p.first = 42;
149.42 - /// p.second = '@';
149.43 - /// \endcode
149.44 - /// \param T1 The type of first.
149.45 - /// \param A1 The parameter type for first.
149.46 - /// \param T2 The type of second.
149.47 - /// \param A2 The parameter type for second.
149.48 - template <typename T1, typename A1, typename T2, typename A2>
149.49 - struct extended_pair {
149.50 - /// \brief The type of first.
149.51 - ///
149.52 - /// The type of first.
149.53 - typedef T1 first_type;
149.54 - /// \brief The type of second.
149.55 - ///
149.56 - /// The type of second.
149.57 - typedef T2 second_type;
149.58 -
149.59 - /// \brief Default constructor.
149.60 - ///
149.61 - /// Default constructor. It calls the default constructor of
149.62 - /// first and second.
149.63 - extended_pair() : first(), second() {}
149.64 -
149.65 - /// \brief Constructor.
149.66 - ///
149.67 - /// Constructor.
149.68 - extended_pair(A1 f, A2 s) : first(f), second(s) {}
149.69 -
149.70 - /// \brief Template constructor.
149.71 - ///
149.72 - /// Template constructor. It copies everything which has
149.73 - /// \c first and \c second member.
149.74 - template <class Pair>
149.75 - extended_pair(const Pair& pair) : first(pair.first), second(pair.second) {}
149.76 -
149.77 - /// \brief The first value
149.78 - ///
149.79 - /// The first value
149.80 - T1 first;
149.81 - /// \brief The second value
149.82 - ///
149.83 - /// The second value
149.84 - T2 second;
149.85 - };
149.86 -
149.87 - /// \brief Equality operator
149.88 - ///
149.89 - /// Equality operator
149.90 - template <typename T1, typename T2,
149.91 - typename LA1, typename LA2, typename RA1, typename RA2>
149.92 - bool operator==(const extended_pair<T1, LA1, T2, LA2>& left,
149.93 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.94 - return left.first == right.first && left.second == right.second;
149.95 - }
149.96 -
149.97 - /// \brief Inequality operator.
149.98 - ///
149.99 - /// Inequality operator.
149.100 - template <typename T1, typename T2,
149.101 - typename LA1, typename LA2, typename RA1, typename RA2>
149.102 - bool operator!=(const extended_pair<T1, LA1, T2, LA2>& left,
149.103 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.104 - return !(left == right);
149.105 - }
149.106 -
149.107 - /// \brief Less operator.
149.108 - ///
149.109 - /// Less operator.
149.110 - template <typename T1, typename T2,
149.111 - typename LA1, typename LA2, typename RA1, typename RA2>
149.112 - bool operator<(const extended_pair<T1, LA1, T2, LA2>& left,
149.113 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.114 - return left.first < right.first ||
149.115 - (!(right.first<left.first) && left.second < right.second);
149.116 - }
149.117 -
149.118 - /// \brief Greater operator.
149.119 - ///
149.120 - /// Greater operator.
149.121 - template <typename T1, typename T2,
149.122 - typename LA1, typename LA2, typename RA1, typename RA2>
149.123 - bool operator>(const extended_pair<T1, LA1, T2, LA2>& left,
149.124 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.125 - return right < left;
149.126 - }
149.127 -
149.128 - /// \brief Less or equal operator.
149.129 - ///
149.130 - /// Less or equal operator.
149.131 - template <typename T1, typename T2,
149.132 - typename LA1, typename LA2, typename RA1, typename RA2>
149.133 - bool operator<=(const extended_pair<T1, LA1, T2, LA2>& left,
149.134 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.135 - return !(right > left);
149.136 - }
149.137 -
149.138 - /// \brief Greater or equal operator.
149.139 - ///
149.140 - /// Greater or equal operator.
149.141 - template <typename T1, typename T2,
149.142 - typename LA1, typename LA2, typename RA1, typename RA2>
149.143 - bool operator>=(const extended_pair<T1, LA1, T2, LA2>& left,
149.144 - const extended_pair<T1, RA1, T2, RA2>& right) {
149.145 - return !(right < left);
149.146 - }
149.147 -
149.148 -}
149.149 -#endif
150.1 --- a/src/lemon/bits/item_reader.h Sat May 21 21:04:57 2005 +0000
150.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
150.3 @@ -1,414 +0,0 @@
150.4 -/* -*- C++ -*-
150.5 - * src/lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
150.6 - *
150.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
150.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
150.9 - *
150.10 - * Permission to use, modify and distribute this software is granted
150.11 - * provided that this copyright notice appears in all copies. For
150.12 - * precise terms see the accompanying LICENSE file.
150.13 - *
150.14 - * This software is provided "AS IS" with no warranty of any kind,
150.15 - * express or implied, and with no claim as to its suitability for any
150.16 - * purpose.
150.17 - *
150.18 - */
150.19 -
150.20 -/// @defgroup item_io Item Readers and Writers
150.21 -/// @ingroup io_group
150.22 -/// \brief Item Readers and Writers
150.23 -///
150.24 -/// The Input-Output classes can handle more data type by example
150.25 -/// as map or attribute value. Each of these should be written and
150.26 -/// read some way. The module make possible to do this.
150.27 -
150.28 -/// \ingroup item_io
150.29 -/// \file
150.30 -/// \brief Item reader bits for lemon input.
150.31 -
150.32 -#ifndef LEMON_BITS_ITEM_READER_H
150.33 -#define LEMON_BITS_ITEM_READER_H
150.34 -
150.35 -#include <iostream>
150.36 -#include <string>
150.37 -
150.38 -#include <vector>
150.39 -#include <deque>
150.40 -#include <list>
150.41 -#include <set>
150.42 -
150.43 -namespace lemon {
150.44 -
150.45 - template <typename Value>
150.46 - class DefaultReader;
150.47 -
150.48 - /// \ingroup item_io
150.49 - ///
150.50 - /// \brief Reader class for quoted strings.
150.51 - ///
150.52 - /// Reader class for quoted strings. It can process the escape
150.53 - /// sequences in the string.
150.54 - ///
150.55 - /// \author Balazs Dezso
150.56 - class QuotedStringReader {
150.57 - public:
150.58 - /// \brief The value type of reader.
150.59 - ///
150.60 - /// The value type of reader.
150.61 - typedef std::string Value;
150.62 -
150.63 - /// \brief Constructor for the reader.
150.64 - ///
150.65 - /// Constructor for the reader. If the given parameter is true
150.66 - /// the reader processes the escape sequences.
150.67 - QuotedStringReader(bool _escaped = true)
150.68 - : escaped(_escaped) {}
150.69 -
150.70 - /// \brief Reads a quoted string from the given stream.
150.71 - ///
150.72 - /// Reads a quoted string from the given stream.
150.73 - void read(std::istream& is, std::string& value) const {
150.74 - char c;
150.75 - value.clear();
150.76 - is >> std::ws;
150.77 - if (!is.get(c) || c != '\"')
150.78 - throw DataFormatError("Quoted string format error");
150.79 - while (is.get(c) && c != '\"') {
150.80 - if (escaped && c == '\\') {
150.81 - value += readEscape(is);
150.82 - } else {
150.83 - value += c;
150.84 - }
150.85 - }
150.86 - if (!is) throw DataFormatError("Quoted string format error");
150.87 - }
150.88 -
150.89 - private:
150.90 -
150.91 - static char readEscape(std::istream& is) {
150.92 - char c;
150.93 - switch (is.get(c), c) {
150.94 - case '\\':
150.95 - return '\\';
150.96 - case '\"':
150.97 - return '\"';
150.98 - case '\'':
150.99 - return '\'';
150.100 - case '\?':
150.101 - return '\?';
150.102 - case 'a':
150.103 - return '\a';
150.104 - case 'b':
150.105 - return '\b';
150.106 - case 'f':
150.107 - return '\f';
150.108 - case 'n':
150.109 - return '\n';
150.110 - case 'r':
150.111 - return '\r';
150.112 - case 't':
150.113 - return '\t';
150.114 - case 'v':
150.115 - return '\v';
150.116 - case 'x':
150.117 - {
150.118 - int code;
150.119 - if (!is.get(c) || !isHex(c))
150.120 - throw DataFormatError("Escape format error");
150.121 - else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
150.122 - else code = code * 16 + valueHex(c);
150.123 - return code;
150.124 - }
150.125 - default:
150.126 - {
150.127 - int code;
150.128 - if (!isOct(c))
150.129 - throw DataFormatError("Escape format error");
150.130 - else if (code = valueOct(c), !is.get(c) || !isOct(c))
150.131 - is.putback(c);
150.132 - else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
150.133 - is.putback(c);
150.134 - else code = code * 8 + valueOct(c);
150.135 - return code;
150.136 - }
150.137 - }
150.138 - }
150.139 -
150.140 - static bool isOct(char c) {
150.141 - return '0' <= c && c <='7';
150.142 - }
150.143 -
150.144 - static int valueOct(char c) {
150.145 - return c - '0';
150.146 - }
150.147 -
150.148 - static bool isHex(char c) {
150.149 - return ('0' <= c && c <= '9') ||
150.150 - ('a' <= c && c <= 'z') ||
150.151 - ('A' <= c && c <= 'Z');
150.152 - }
150.153 -
150.154 - static int valueHex(char c) {
150.155 - if ('0' <= c && c <= '9') return c - '0';
150.156 - if ('a' <= c && c <= 'z') return c - 'a' + 10;
150.157 - return c - 'A' + 10;
150.158 - }
150.159 -
150.160 - bool escaped;
150.161 - };
150.162 -
150.163 - /// \ingroup item_io
150.164 - /// \brief Reader for standard containers.
150.165 - ///
150.166 - /// Reader for back insertable standard containers. The representation
150.167 - /// of the container is the values enumerated between an open and a
150.168 - /// close parse.
150.169 - ///
150.170 - /// \author Balazs Dezso
150.171 - template <
150.172 - typename _Container,
150.173 - typename _ItemReader = DefaultReader<typename _Container::value_type>
150.174 - >
150.175 - class PushBackReader {
150.176 - public:
150.177 - typedef _Container Value;
150.178 - typedef _ItemReader ItemReader;
150.179 -
150.180 - private:
150.181 -
150.182 - ItemReader item_reader;
150.183 -
150.184 - public:
150.185 -
150.186 - /// \brief Reads the values into the container from the given stream.
150.187 - ///
150.188 - /// Reads the values into the container from the given stream.
150.189 - void read(std::istream& is, Value& value) const {
150.190 - char c;
150.191 - if (!(is >> c) || c != '(')
150.192 - throw DataFormatError("PushBackReader format error");
150.193 - while (is >> c && c != ')') {
150.194 - is.putback(c);
150.195 - typename ItemReader::Value item;
150.196 - item_reader.read(is, item);
150.197 - value.push_back(item);
150.198 - }
150.199 - if (!is) throw DataFormatError("PushBackReader format error");
150.200 - is.putback(c);
150.201 - }
150.202 -
150.203 - };
150.204 -
150.205 - /// \ingroup item_io
150.206 - ///
150.207 - /// \brief Reader for standard containers.
150.208 - ///
150.209 - /// Reader for insertable standard containers. The representation
150.210 - /// of the container is the values enumerated between an open and a
150.211 - /// close parse.
150.212 - ///
150.213 - /// \author Balazs Dezso
150.214 - template <
150.215 - typename _Container,
150.216 - typename _ItemReader = DefaultReader<typename _Container::value_type>
150.217 - >
150.218 - class InsertReader {
150.219 - public:
150.220 - typedef _Container Value;
150.221 - typedef _ItemReader ItemReader;
150.222 -
150.223 - private:
150.224 -
150.225 - ItemReader item_reader;
150.226 -
150.227 - public:
150.228 -
150.229 - /// \brief Reads the values into the container from the given stream.
150.230 - ///
150.231 - /// Reads the values into the container from the given stream.
150.232 - void read(std::istream& is, Value& value) const {
150.233 - char c;
150.234 - if (!(is >> c) || c != '(')
150.235 - throw DataFormatError("InsertReader format error");
150.236 - while (is >> c && c != ')') {
150.237 - is.putback(c);
150.238 - typename ItemReader::Value item;
150.239 - item_reader.read(is, item);
150.240 - value.insert(item);
150.241 - }
150.242 - if (!is) throw DataFormatError("PushBackReader format error");
150.243 - is.putback(c);
150.244 - }
150.245 -
150.246 - };
150.247 -
150.248 - /// \ingroup item_io
150.249 - /// \brief Reader for parsed string.
150.250 - ///
150.251 - /// Reader for parsed strings. You can give the open and close
150.252 - /// parse characters.
150.253 - ///
150.254 - /// \author Balazs Dezso
150.255 - class ParsedStringReader {
150.256 - public:
150.257 - typedef std::string Value;
150.258 -
150.259 - /// \brief Constructor.
150.260 - ///
150.261 - /// Constructor for ParsedStringReader. You can give as parameter
150.262 - /// the open and close parse characters.
150.263 - ParsedStringReader(char _open = '(', char _close = ')')
150.264 - : open(_open), close(_close) {}
150.265 -
150.266 -
150.267 - /// \brief Reads the parsed string from the given stream.
150.268 - ///
150.269 - /// Reads the parsed string from the given stream.
150.270 - void read(std::istream& is, Value& value) const {
150.271 - char c;
150.272 - if (!(is >> c) || c != open) {
150.273 - throw DataFormatError("ParsedStringReader format error");
150.274 - }
150.275 - value += c;
150.276 - int counter = 1;
150.277 - while (counter > 0 && is >> c) {
150.278 - if (c == close) {
150.279 - --counter;
150.280 - } else if (c == open) {
150.281 - ++counter;
150.282 - }
150.283 - value += c;
150.284 - }
150.285 - if (!is) {
150.286 - throw DataFormatError("ParsedStrinReader format error");
150.287 - }
150.288 - }
150.289 -
150.290 - private:
150.291 - char open, close;
150.292 -
150.293 - };
150.294 -
150.295 - /// \ingroup item_io
150.296 - /// \brief Reader for read the whole line.
150.297 - ///
150.298 - /// Reader for read the whole line.
150.299 - ///
150.300 - /// \author Balazs Dezso
150.301 - class LineReader {
150.302 - public:
150.303 - typedef std::string Value;
150.304 -
150.305 - /// \brief Constructor.
150.306 - ///
150.307 - /// Constructor for the LineReader. If the given parameter is
150.308 - /// true then the spaces before the first not space character are
150.309 - /// skipped.
150.310 - LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
150.311 -
150.312 - /// \brief Reads the line from the given stream.
150.313 - ///
150.314 - /// Reads the line from the given stream.
150.315 - void read(std::istream& is, Value& value) {
150.316 - if (skipSpaces) is >> std::ws;
150.317 - if (!getline(is, value)) {
150.318 - throw DataFormatError("LineReader forma error");
150.319 - }
150.320 - }
150.321 - private:
150.322 - bool skipSpaces;
150.323 - };
150.324 -
150.325 - /// \ingroup item_io
150.326 - ///
150.327 - /// \brief The default item reader template class.
150.328 - ///
150.329 - /// The default item reader template class. If some section reader
150.330 - /// needs to read a value from a stream it will give the default way for it.
150.331 - ///
150.332 - /// \author Balazs Dezso
150.333 - template <typename _Value>
150.334 - class DefaultReader {
150.335 - public:
150.336 - /// The value type.
150.337 - typedef _Value Value;
150.338 - /// \brief Reads a value from the given stream.
150.339 - ///
150.340 - /// Reads a value from the given stream.
150.341 - void read(std::istream& is, Value& value) const {
150.342 - if (!(is >> value))
150.343 - throw DataFormatError("DefaultReader format error");
150.344 - }
150.345 - };
150.346 -
150.347 - template <>
150.348 - class DefaultReader<std::string> {
150.349 - public:
150.350 - typedef std::string Value;
150.351 -
150.352 - void read(std::istream& is, Value& value) const {
150.353 - char c;
150.354 - if (!(is >> std::ws >> c)) return;
150.355 - is.putback(c);
150.356 - switch (c) {
150.357 - case '\"':
150.358 - QuotedStringReader().read(is, value);
150.359 - break;
150.360 - case '(':
150.361 - ParsedStringReader().read(is, value);
150.362 - break;
150.363 - default:
150.364 - is >> value;
150.365 - break;
150.366 - }
150.367 - }
150.368 -
150.369 - };
150.370 -
150.371 - template <typename Item>
150.372 - class DefaultReader<std::vector<Item> >
150.373 - : public PushBackReader<std::vector<Item> > {};
150.374 -
150.375 - template <typename Item>
150.376 - class DefaultReader<std::deque<Item> >
150.377 - : public PushBackReader<std::deque<Item> > {};
150.378 -
150.379 - template <typename Item>
150.380 - class DefaultReader<std::list<Item> >
150.381 - : public PushBackReader<std::list<Item> > {};
150.382 -
150.383 - template <typename Item>
150.384 - class DefaultReader<std::set<Item> >
150.385 - : public InsertReader<std::set<Item> > {};
150.386 -
150.387 - template <typename Item>
150.388 - class DefaultReader<std::multiset<Item> >
150.389 - : public InsertReader<std::multiset<Item> > {};
150.390 -
150.391 - /// \ingroup item_io
150.392 - ///
150.393 - /// \brief The default item reader for skipping a value in the stream.
150.394 - ///
150.395 - /// The default item reader for skipping a value in the stream.
150.396 - ///
150.397 - /// \author Balazs Dezso
150.398 - class DefaultSkipper : public DefaultReader<std::string> {};
150.399 -
150.400 - /// \ingroup item_io
150.401 - /// \brief Standard ReaderTraits for the GraphReader class.
150.402 - ///
150.403 - /// Standard ReaderTraits for the GraphReader class.
150.404 - /// It defines standard reading method for all type of value.
150.405 - /// \author Balazs Dezso
150.406 - struct DefaultReaderTraits {
150.407 -
150.408 - template <typename _Value>
150.409 - struct Reader : DefaultReader<_Value> {};
150.410 -
150.411 - typedef DefaultSkipper Skipper;
150.412 -
150.413 - };
150.414 -
150.415 -}
150.416 -
150.417 -#endif
151.1 --- a/src/lemon/bits/item_writer.h Sat May 21 21:04:57 2005 +0000
151.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
151.3 @@ -1,219 +0,0 @@
151.4 -/* -*- C++ -*-
151.5 - * src/lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
151.6 - *
151.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
151.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
151.9 - *
151.10 - * Permission to use, modify and distribute this software is granted
151.11 - * provided that this copyright notice appears in all copies. For
151.12 - * precise terms see the accompanying LICENSE file.
151.13 - *
151.14 - * This software is provided "AS IS" with no warranty of any kind,
151.15 - * express or implied, and with no claim as to its suitability for any
151.16 - * purpose.
151.17 - *
151.18 - */
151.19 -
151.20 -/// \ingroup item_io
151.21 -/// \file
151.22 -/// \brief Item writer bits for lemon output.
151.23 -
151.24 -#ifndef LEMON_BITS_ITEM_WRITER_H
151.25 -#define LEMON_BITS_ITEM_WRITER_H
151.26 -
151.27 -#include <iostream>
151.28 -#include <string>
151.29 -
151.30 -#include <vector>
151.31 -#include <deque>
151.32 -#include <list>
151.33 -#include <set>
151.34 -
151.35 -namespace lemon {
151.36 -
151.37 - template <typename Value>
151.38 - class DefaultWriter;
151.39 -
151.40 - /// \ingroup item_io
151.41 - /// \brief Writer class for quoted strings.
151.42 - ///
151.43 - /// Writer class for quoted strings. It can process the escape
151.44 - /// sequences in the string.
151.45 - /// \author Balazs Dezso
151.46 - class QuotedStringWriter {
151.47 - public:
151.48 - typedef std::string Value;
151.49 -
151.50 - /// \brief Constructor for the writer.
151.51 - ///
151.52 - /// Constructor for the writer. If the given parameter is true
151.53 - /// the writer creates escape sequences from special characters.
151.54 - QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
151.55 -
151.56 - /// \brief Writes a quoted string to the given stream.
151.57 - ///
151.58 - /// Writes a quoted string to the given stream.
151.59 - void write(std::ostream& os, const std::string& value) {
151.60 - os << "\"";
151.61 - if (escaped) {
151.62 - std::ostringstream ls;
151.63 - for (int i = 0; i < (int)value.size(); ++i) {
151.64 - writeEscape(ls, value[i]);
151.65 - }
151.66 - os << ls.str();
151.67 - } else {
151.68 - os << value;
151.69 - }
151.70 - os << "\"";
151.71 - }
151.72 -
151.73 - private:
151.74 -
151.75 - static void writeEscape(std::ostream& os, char c) {
151.76 - switch (c) {
151.77 - case '\\':
151.78 - os << "\\\\";
151.79 - return;
151.80 - case '\"':
151.81 - os << "\\\"";
151.82 - return;
151.83 - case '\'':
151.84 - os << "\\\'";
151.85 - return;
151.86 - case '\?':
151.87 - os << "\\\?";
151.88 - return;
151.89 - case '\a':
151.90 - os << "\\a";
151.91 - return;
151.92 - case '\b':
151.93 - os << "\\b";
151.94 - return;
151.95 - case '\f':
151.96 - os << "\\f";
151.97 - return;
151.98 - case '\r':
151.99 - os << "\\r";
151.100 - return;
151.101 - case '\n':
151.102 - os << "\\n";
151.103 - return;
151.104 - case '\t':
151.105 - os << "\\t";
151.106 - return;
151.107 - case '\v':
151.108 - os << "\\v";
151.109 - return;
151.110 - default:
151.111 - if (c < 0x20) {
151.112 - os << '\\' << std::oct << (int)c;
151.113 - } else {
151.114 - os << c;
151.115 - }
151.116 - return;
151.117 - }
151.118 - }
151.119 - private:
151.120 - bool escaped;
151.121 - };
151.122 -
151.123 - /// \ingroup item_io
151.124 - ///
151.125 - /// \brief Writer for standard containers.
151.126 - ///
151.127 - /// Writer for each iterable standard containers. The representation
151.128 - /// of the container is the values enumerated between an open and a
151.129 - /// close parse.
151.130 - ///
151.131 - /// \author Balazs Dezso
151.132 - template <
151.133 - typename _Container,
151.134 - typename _ItemWriter = DefaultWriter<typename _Container::value_type>
151.135 - >
151.136 - class IterableWriter {
151.137 - public:
151.138 - typedef _Container Value;
151.139 - typedef _ItemWriter ItemWriter;
151.140 -
151.141 - private:
151.142 -
151.143 - ItemWriter item_writer;
151.144 -
151.145 - public:
151.146 -
151.147 - /// \brief Writes the values of the container to the given stream.
151.148 - ///
151.149 - /// Writes the values of the container to the given stream.
151.150 - void write(std::ostream& os, const Value& value) const {
151.151 - typename Value::const_iterator it;
151.152 - os << '(';
151.153 - for (it = value.begin(); it != value.end(); ++it) {
151.154 - item_writer.write(os, *it);
151.155 - os << ' ';
151.156 - }
151.157 - os << ')';
151.158 - }
151.159 -
151.160 - };
151.161 -
151.162 - /// \ingroup item_io
151.163 - ///
151.164 - /// \brief The default item writer template class.
151.165 - ///
151.166 - /// The default item writer template class. If some section writer
151.167 - /// needs to write a value to the stream it will give the default way for it.
151.168 - ///
151.169 - /// \author Balazs Dezso
151.170 - template <typename _Value>
151.171 - class DefaultWriter {
151.172 - public:
151.173 - /// The value type.
151.174 - typedef _Value Value;
151.175 - /// \brief Writes the value to the given stream.
151.176 - ///
151.177 - /// Writes the value to the given stream.
151.178 - void write(std::ostream& os, const Value& value) const {
151.179 - os << value;
151.180 - }
151.181 - };
151.182 -
151.183 - template <>
151.184 - class DefaultWriter<std::string>
151.185 - : public QuotedStringWriter {};
151.186 -
151.187 - template <typename Item>
151.188 - class DefaultWriter<std::vector<Item> >
151.189 - : public IterableWriter<std::vector<Item> > {};
151.190 -
151.191 - template <typename Item>
151.192 - class DefaultWriter<std::deque<Item> >
151.193 - : public IterableWriter<std::deque<Item> > {};
151.194 -
151.195 - template <typename Item>
151.196 - class DefaultWriter<std::list<Item> >
151.197 - : public IterableWriter<std::list<Item> > {};
151.198 -
151.199 - template <typename Item>
151.200 - class DefaultWriter<std::set<Item> >
151.201 - : public IterableWriter<std::set<Item> > {};
151.202 -
151.203 - template <typename Item>
151.204 - class DefaultWriter<std::multiset<Item> >
151.205 - : public IterableWriter<std::multiset<Item> > {};
151.206 -
151.207 - /// \ingroup item_io
151.208 - /// \brief Standard WriterTraits for the section writers.
151.209 - ///
151.210 - /// Standard WriterTraits for the section writers.
151.211 - /// It defines standard writing method for all type of value.
151.212 - /// \author Balazs Dezso
151.213 - struct DefaultWriterTraits {
151.214 -
151.215 - template <typename _Value>
151.216 - struct Writer : DefaultWriter<_Value> {};
151.217 -
151.218 - };
151.219 -
151.220 -}
151.221 -
151.222 -#endif
152.1 --- a/src/lemon/bits/iterable_graph_extender.h Sat May 21 21:04:57 2005 +0000
152.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
152.3 @@ -1,250 +0,0 @@
152.4 -// -*- c++ -*-
152.5 -#ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
152.6 -#define LEMON_ITERABLE_GRAPH_EXTENDER_H
152.7 -
152.8 -#include <lemon/invalid.h>
152.9 -
152.10 -namespace lemon {
152.11 -
152.12 - template <typename _Base>
152.13 - class IterableGraphExtender : public _Base {
152.14 - public:
152.15 -
152.16 - typedef _Base Parent;
152.17 - typedef IterableGraphExtender<_Base> Graph;
152.18 -
152.19 - typedef typename Parent::Node Node;
152.20 - typedef typename Parent::Edge Edge;
152.21 -
152.22 -
152.23 - class NodeIt : public Node {
152.24 - const Graph* graph;
152.25 - public:
152.26 -
152.27 - NodeIt() {}
152.28 -
152.29 - NodeIt(Invalid i) : Node(i) { }
152.30 -
152.31 - explicit NodeIt(const Graph& _graph) : graph(&_graph) {
152.32 - _graph.first(*static_cast<Node*>(this));
152.33 - }
152.34 -
152.35 - NodeIt(const Graph& _graph, const Node& node)
152.36 - : Node(node), graph(&_graph) {}
152.37 -
152.38 - NodeIt& operator++() {
152.39 - graph->next(*this);
152.40 - return *this;
152.41 - }
152.42 -
152.43 - };
152.44 -
152.45 -
152.46 - class EdgeIt : public Edge {
152.47 - const Graph* graph;
152.48 - public:
152.49 -
152.50 - EdgeIt() { }
152.51 -
152.52 - EdgeIt(Invalid i) : Edge(i) { }
152.53 -
152.54 - explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
152.55 - _graph.first(*static_cast<Edge*>(this));
152.56 - }
152.57 -
152.58 - EdgeIt(const Graph& _graph, const Edge& e) :
152.59 - Edge(e), graph(&_graph) { }
152.60 -
152.61 - EdgeIt& operator++() {
152.62 - graph->next(*this);
152.63 - return *this;
152.64 - }
152.65 -
152.66 - };
152.67 -
152.68 -
152.69 - class OutEdgeIt : public Edge {
152.70 - const Graph* graph;
152.71 - public:
152.72 -
152.73 - OutEdgeIt() { }
152.74 -
152.75 - OutEdgeIt(Invalid i) : Edge(i) { }
152.76 -
152.77 - OutEdgeIt(const Graph& _graph, const Node& node)
152.78 - : graph(&_graph) {
152.79 - _graph.firstOut(*this, node);
152.80 - }
152.81 -
152.82 - OutEdgeIt(const Graph& _graph, const Edge& edge)
152.83 - : Edge(edge), graph(&_graph) {}
152.84 -
152.85 - OutEdgeIt& operator++() {
152.86 - graph->nextOut(*this);
152.87 - return *this;
152.88 - }
152.89 -
152.90 - };
152.91 -
152.92 -
152.93 - class InEdgeIt : public Edge {
152.94 - const Graph* graph;
152.95 - public:
152.96 -
152.97 - InEdgeIt() { }
152.98 -
152.99 - InEdgeIt(Invalid i) : Edge(i) { }
152.100 -
152.101 - InEdgeIt(const Graph& _graph, const Node& node)
152.102 - : graph(&_graph) {
152.103 - _graph.firstIn(*this, node);
152.104 - }
152.105 -
152.106 - InEdgeIt(const Graph& _graph, const Edge& edge) :
152.107 - Edge(edge), graph(&_graph) {}
152.108 -
152.109 - InEdgeIt& operator++() {
152.110 - graph->nextIn(*this);
152.111 - return *this;
152.112 - }
152.113 -
152.114 - };
152.115 -
152.116 - /// Base node of the iterator
152.117 - ///
152.118 - /// Returns the base node (ie. the source in this case) of the iterator
152.119 - ///
152.120 - /// \todo Document in the concept!
152.121 - Node baseNode(const OutEdgeIt &e) const {
152.122 - return source(e);
152.123 - }
152.124 - /// Running node of the iterator
152.125 - ///
152.126 - /// Returns the running node (ie. the target in this case) of the
152.127 - /// iterator
152.128 - ///
152.129 - /// \todo Document in the concept!
152.130 - Node runningNode(const OutEdgeIt &e) const {
152.131 - return target(e);
152.132 - }
152.133 -
152.134 - /// Base node of the iterator
152.135 - ///
152.136 - /// Returns the base node (ie. the target in this case) of the iterator
152.137 - ///
152.138 - /// \todo Document in the concept!
152.139 - Node baseNode(const InEdgeIt &e) const {
152.140 - return target(e);
152.141 - }
152.142 - /// Running node of the iterator
152.143 - ///
152.144 - /// Returns the running node (ie. the source in this case) of the
152.145 - /// iterator
152.146 - ///
152.147 - /// \todo Document in the concept!
152.148 - Node runningNode(const InEdgeIt &e) const {
152.149 - return source(e);
152.150 - }
152.151 -
152.152 - using Parent::first;
152.153 -
152.154 - private:
152.155 -
152.156 - // /// \todo When (and if) we change the iterators concept to use operator*,
152.157 - // /// then the following shadowed methods will become superfluous.
152.158 - // /// But for now these are important safety measures.
152.159 -
152.160 - // void first(NodeIt &) const;
152.161 - // void first(EdgeIt &) const;
152.162 - // void first(OutEdgeIt &) const;
152.163 - // void first(InEdgeIt &) const;
152.164 -
152.165 - };
152.166 -
152.167 -
152.168 -
152.169 -
152.170 -
152.171 -
152.172 - template <typename _Base>
152.173 - class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
152.174 - public:
152.175 -
152.176 - typedef IterableGraphExtender<_Base> Parent;
152.177 - typedef IterableUndirGraphExtender<_Base> Graph;
152.178 - typedef typename Parent::Node Node;
152.179 -
152.180 - typedef typename Parent::UndirEdge UndirEdge;
152.181 -
152.182 - class UndirEdgeIt : public Parent::UndirEdge {
152.183 - const Graph* graph;
152.184 - public:
152.185 -
152.186 - UndirEdgeIt() { }
152.187 -
152.188 - UndirEdgeIt(Invalid i) : UndirEdge(i) { }
152.189 -
152.190 - explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
152.191 - _graph.first(*static_cast<UndirEdge*>(this));
152.192 - }
152.193 -
152.194 - UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
152.195 - UndirEdge(e), graph(&_graph) { }
152.196 -
152.197 - UndirEdgeIt& operator++() {
152.198 - graph->next(*this);
152.199 - return *this;
152.200 - }
152.201 -
152.202 - };
152.203 -
152.204 - class IncEdgeIt : public Parent::UndirEdge {
152.205 - const Graph* graph;
152.206 - bool forward;
152.207 - friend class IterableUndirGraphExtender;
152.208 - template <typename G>
152.209 - friend class UndirGraphExtender;
152.210 - public:
152.211 -
152.212 - IncEdgeIt() { }
152.213 -
152.214 - IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
152.215 -
152.216 - IncEdgeIt(const Graph& _graph, const Node &n)
152.217 - : graph(&_graph)
152.218 - {
152.219 - _graph._dirFirstOut(*this, n);
152.220 - }
152.221 -
152.222 - IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
152.223 - : graph(&_graph), UndirEdge(ue)
152.224 - {
152.225 - forward = (_graph.source(ue) == n);
152.226 - }
152.227 -
152.228 - IncEdgeIt& operator++() {
152.229 - graph->_dirNextOut(*this);
152.230 - return *this;
152.231 - }
152.232 - };
152.233 -
152.234 - using Parent::baseNode;
152.235 - using Parent::runningNode;
152.236 -
152.237 - /// Base node of the iterator
152.238 - ///
152.239 - /// Returns the base node of the iterator
152.240 - Node baseNode(const IncEdgeIt &e) const {
152.241 - return _dirSource(e);
152.242 - }
152.243 - /// Running node of the iterator
152.244 - ///
152.245 - /// Returns the running node of the iterator
152.246 - Node runningNode(const IncEdgeIt &e) const {
152.247 - return _dirTarget(e);
152.248 - }
152.249 -
152.250 - };
152.251 -}
152.252 -
152.253 -#endif // LEMON_GRAPH_EXTENDER_H
153.1 --- a/src/lemon/bits/map_iterator.h Sat May 21 21:04:57 2005 +0000
153.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
153.3 @@ -1,855 +0,0 @@
153.4 -/* -*- C++ -*-
153.5 - * src/lemon/map_iterator.h - Part of LEMON, a generic C++ optimization library
153.6 - *
153.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
153.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
153.9 - *
153.10 - * Permission to use, modify and distribute this software is granted
153.11 - * provided that this copyright notice appears in all copies. For
153.12 - * precise terms see the accompanying LICENSE file.
153.13 - *
153.14 - * This software is provided "AS IS" with no warranty of any kind,
153.15 - * express or implied, and with no claim as to its suitability for any
153.16 - * purpose.
153.17 - *
153.18 - */
153.19 -
153.20 -#ifndef LEMON_MAP_ITERATOR_H
153.21 -#define LEMON_MAP_ITERATOR_H
153.22 -
153.23 -#include <iterator>
153.24 -
153.25 -#include <lemon/bits/extended_pair.h>
153.26 -#include <lemon/graph_utils.h>
153.27 -
153.28 -///\ingroup graphmaps
153.29 -///\file
153.30 -///\brief Iterators on the maps.
153.31 -
153.32 -namespace lemon {
153.33 -
153.34 - /// \addtogroup graphmaps
153.35 - /// @{
153.36 -
153.37 - /** The base class all of the map iterators.
153.38 - * The class defines the typedefs of the iterators,
153.39 - * simple step functions and equality operators.
153.40 - */
153.41 -
153.42 - template <
153.43 - typename _Graph,
153.44 - typename _Item>
153.45 - class MapIteratorBase {
153.46 -
153.47 - protected:
153.48 -
153.49 - /// The key type of the iterator.
153.50 - typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
153.51 -
153.52 - ItemIt it;
153.53 -
153.54 - /// Default constructor.
153.55 - MapIteratorBase() {}
153.56 -
153.57 - /// ItemIt initialized MapIteratorBase constructor.
153.58 - MapIteratorBase(const ItemIt _it) : it(_it) {}
153.59 -
153.60 - public:
153.61 -
153.62 - /// Stepping forward in the map.
153.63 - void increment() {
153.64 - ++it;
153.65 - }
153.66 -
153.67 - /// The equality operator of the map.
153.68 - bool operator==(const MapIteratorBase& _it) const {
153.69 - return _it.it == it;
153.70 - }
153.71 -
153.72 - /// The not-equality operator of the map.
153.73 - bool operator!=(const MapIteratorBase& _it) const {
153.74 - return !(*this == _it);
153.75 - }
153.76 - };
153.77 -
153.78 -
153.79 - template <
153.80 - typename _Graph,
153.81 - typename _Item,
153.82 - typename _Map>
153.83 - class MapConstIterator;
153.84 -
153.85 - /** Compatible iterator with the stl maps' iterators.
153.86 - * It iterates on pairs of a key and a value.
153.87 - */
153.88 - template <
153.89 - typename _Graph,
153.90 - typename _Item,
153.91 - typename _Map>
153.92 - class MapIterator : public MapIteratorBase<_Graph, _Item> {
153.93 -
153.94 - friend class MapConstIterator<_Graph, _Item, _Map>;
153.95 -
153.96 -
153.97 - public:
153.98 -
153.99 - /// The iterator base class.
153.100 - typedef MapIteratorBase<_Graph, _Item> Parent;
153.101 -
153.102 - typedef _Item Item;
153.103 - typedef _Map Map;
153.104 - typedef _Graph Graph;
153.105 -
153.106 - protected:
153.107 -
153.108 - typedef typename Parent::ItemIt ItemIt;
153.109 -
153.110 - typedef typename ReferenceMapTraits<_Map>::Value MapValue;
153.111 - typedef typename ReferenceMapTraits<_Map>::Reference MapReference;
153.112 -
153.113 - public:
153.114 -
153.115 - /// The value type of the iterator.
153.116 - typedef extended_pair<Item, const Item&,
153.117 - MapValue, const MapValue&> Value;
153.118 -
153.119 - /// The reference type of the iterator.
153.120 - typedef extended_pair<const Item&, const Item&,
153.121 - MapReference, MapReference> Reference;
153.122 -
153.123 - /// Default constructor.
153.124 - MapIterator() {}
153.125 -
153.126 - /// Constructor to initalize the iterators returned
153.127 - /// by the begin() and end().
153.128 - MapIterator(Map& _map, const ItemIt& _it)
153.129 - : Parent(_it), map(&_map) {}
153.130 -
153.131 - /// Dereference operator for the iterator.
153.132 - Reference operator*() {
153.133 - return Reference(Parent::it, (*map)[Parent::it]);
153.134 - }
153.135 -
153.136 - /// The pointer type of the iterator.
153.137 - class Pointer {
153.138 - friend class MapIterator;
153.139 - protected:
153.140 - Reference data;
153.141 - Pointer(const Item& item, MapReference val)
153.142 - : data(item, val) {}
153.143 - public:
153.144 - Reference* operator->() {return &data;}
153.145 - };
153.146 -
153.147 - /// Arrow operator for the iterator.
153.148 - Pointer operator->() {
153.149 - return Pointer(Parent::it, (*map)[Parent::it]);
153.150 - }
153.151 -
153.152 - /// The pre increment operator of the iterator.
153.153 - MapIterator& operator++() {
153.154 - Parent::increment();
153.155 - return *this;
153.156 - }
153.157 -
153.158 - /// The post increment operator of the iterator.
153.159 - MapIterator operator++(int) {
153.160 - MapIterator tmp(*this);
153.161 - Parent::increment();
153.162 - return tmp;
153.163 - }
153.164 -
153.165 - protected:
153.166 -
153.167 - Map* map;
153.168 -
153.169 - public:
153.170 - // STL compatibility typedefs.
153.171 - typedef std::forward_iterator_tag iterator_category;
153.172 - typedef int difference_type;
153.173 - typedef Value value_type;
153.174 - typedef Reference reference;
153.175 - typedef Pointer pointer;
153.176 - };
153.177 -
153.178 - /** Compatible iterator with the stl maps' iterators.
153.179 - * It iterates on pairs of a key and a value.
153.180 - */
153.181 - template <
153.182 - typename _Graph,
153.183 - typename _Item,
153.184 - typename _Map>
153.185 - class MapConstIterator : public MapIteratorBase<_Graph, _Item> {
153.186 -
153.187 - public:
153.188 -
153.189 - /// The iterator base class.
153.190 - typedef MapIteratorBase<_Graph, _Item> Parent;
153.191 -
153.192 - typedef _Graph Graph;
153.193 - typedef _Item Item;
153.194 - typedef _Map Map;
153.195 -
153.196 - protected:
153.197 -
153.198 - typedef typename Parent::ItemIt ItemIt;
153.199 -
153.200 - typedef typename ReferenceMapTraits<_Map>::Value MapValue;
153.201 - typedef typename ReferenceMapTraits<_Map>::ConstReference
153.202 - MapReference;
153.203 -
153.204 - public:
153.205 -
153.206 - /// The value type of the iterator.
153.207 - typedef extended_pair<Item, const Item&,
153.208 - MapValue, const MapValue&> Value;
153.209 -
153.210 - /// The reference type of the iterator.
153.211 - typedef extended_pair<const Item&, const Item&,
153.212 - MapReference, MapReference> Reference;
153.213 -
153.214 - /// Default constructor.
153.215 - MapConstIterator() {}
153.216 -
153.217 - /// Constructor to initalize the iterators returned
153.218 - /// by the begin() and end().
153.219 - MapConstIterator(const Map& _map, const ItemIt& _it)
153.220 - : Parent(_it), map(&_map) {}
153.221 -
153.222 - /// Dereference operator for the iterator.
153.223 - Reference operator*() {
153.224 - return Reference(Parent::it, (*map)[Parent::it]);
153.225 - }
153.226 -
153.227 - /// The pointer type of the iterator.
153.228 - class Pointer {
153.229 - friend class MapConstIterator;
153.230 - protected:
153.231 - Reference data;
153.232 - Pointer(const Item& item, MapReference val)
153.233 - : data(item, val) {}
153.234 - public:
153.235 - Reference* operator->() {return &data;}
153.236 - };
153.237 -
153.238 - /// Arrow operator for the iterator.
153.239 - Pointer operator->() {
153.240 - return Pointer(Parent::it, ((*map)[Parent::it]));
153.241 - }
153.242 -
153.243 - /// The pre increment operator of the iterator.
153.244 - MapConstIterator& operator++() {
153.245 - Parent::increment();
153.246 - return *this;
153.247 - }
153.248 -
153.249 - /// The post increment operator of the iterator.
153.250 - MapConstIterator operator++(int) {
153.251 - MapConstIterator tmp(*this);
153.252 - Parent::increment();
153.253 - return tmp;
153.254 - }
153.255 -
153.256 - protected:
153.257 - const Map* map;
153.258 -
153.259 - public:
153.260 - // STL compatibility typedefs.
153.261 - typedef std::forward_iterator_tag iterator_category;
153.262 - typedef int difference_type;
153.263 - typedef Value value_type;
153.264 - typedef Reference reference;
153.265 - typedef Pointer pointer;
153.266 - };
153.267 -
153.268 - /** The class makes the ItemIt to an stl compatible iterator
153.269 - * with dereferencing operator.
153.270 - */
153.271 - template <
153.272 - typename _Graph,
153.273 - typename _Item>
153.274 - class MapConstKeyIterator : public MapIteratorBase<_Graph, _Item> {
153.275 -
153.276 - public:
153.277 -
153.278 - /// The iterator base class.
153.279 - typedef MapIteratorBase<_Graph, _Item> Parent;
153.280 -
153.281 - typedef _Graph Graph;
153.282 - typedef _Item Item;
153.283 -
153.284 - protected:
153.285 - /// The iterator to iterate on the keys.
153.286 - typedef typename Parent::ItemIt ItemIt;
153.287 -
153.288 - public:
153.289 -
153.290 - typedef Item Value;
153.291 - typedef const Item& Reference;
153.292 - typedef const Item* Pointer;
153.293 -
153.294 - /// Default constructor.
153.295 - MapConstKeyIterator() {}
153.296 -
153.297 - /// ItemIt initialized iterator.
153.298 - MapConstKeyIterator(const ItemIt& pit) : Parent(pit) {}
153.299 -
153.300 - /// The pre increment operator of the iterator.
153.301 - MapConstKeyIterator& operator++() {
153.302 - Parent::increment();
153.303 - return *this;
153.304 - }
153.305 -
153.306 - /// The post increment operator of the iterator.
153.307 - MapConstKeyIterator operator++(int) {
153.308 - MapConstKeyIterator tmp(*this);
153.309 - Parent::increment();
153.310 - return tmp;
153.311 - }
153.312 -
153.313 - /// The dereferencing operator of the iterator.
153.314 - Item operator*() const {
153.315 - return static_cast<Item>(Parent::it);
153.316 - }
153.317 -
153.318 - public:
153.319 - // STL compatibility typedefs.
153.320 - typedef std::input_iterator_tag iterator_category;
153.321 - typedef int difference_type;
153.322 - typedef Value value_type;
153.323 - typedef Reference reference;
153.324 - typedef Pointer pointer;
153.325 - };
153.326 -
153.327 - template <
153.328 - typename _Graph,
153.329 - typename _Item,
153.330 - typename _Map>
153.331 - class MapConstValueIterator;
153.332 -
153.333 - /** MapValueIterator creates an stl compatible iterator
153.334 - * for the values.
153.335 - */
153.336 - template <
153.337 - typename _Graph,
153.338 - typename _Item,
153.339 - typename _Map>
153.340 - class MapValueIterator : public MapIteratorBase<_Graph, _Item> {
153.341 -
153.342 - friend class MapConstValueIterator<_Graph, _Item, _Map>;
153.343 -
153.344 - public:
153.345 -
153.346 - /// The iterator base class.
153.347 - typedef MapIteratorBase<_Graph, _Item> Parent;
153.348 -
153.349 - typedef _Graph Graph;
153.350 - typedef _Item Item;
153.351 - typedef _Map Map;
153.352 -
153.353 - protected:
153.354 -
153.355 - /// The iterator to iterate on the keys.
153.356 - typedef typename Parent::ItemIt ItemIt;
153.357 -
153.358 - /// The value type of the iterator.
153.359 - typedef typename ReferenceMapTraits<Map>::Value MapValue;
153.360 - /// The reference type of the iterator.
153.361 - typedef typename ReferenceMapTraits<Map>::Reference MapReference;
153.362 - /// The pointer type of the iterator.
153.363 - typedef typename ReferenceMapTraits<Map>::Pointer MapPointer;
153.364 -
153.365 - public:
153.366 -
153.367 - typedef MapValue Value;
153.368 - typedef MapReference Reference;
153.369 - typedef MapPointer Pointer;
153.370 -
153.371 - /// Default constructor.
153.372 - MapValueIterator() {}
153.373 -
153.374 - /// Map and ItemIt initialized iterator.
153.375 - MapValueIterator(Map& _map, const ItemIt& _it)
153.376 - : Parent(_it), map(&_map) {}
153.377 -
153.378 -
153.379 - /// The pre increment operator of the iterator.
153.380 - MapValueIterator& operator++() {
153.381 - Parent::increment();
153.382 - return *this;
153.383 - }
153.384 -
153.385 - /// The post increment operator of the iterator.
153.386 - MapValueIterator operator++(int) {
153.387 - MapValueIterator tmp(*this);
153.388 - Parent::increment();
153.389 - return tmp;
153.390 - }
153.391 -
153.392 - /// The dereferencing operator of the iterator.
153.393 - Reference operator*() const {
153.394 - return (*map)[Parent::it];
153.395 - }
153.396 -
153.397 - /// The arrow operator of the iterator.
153.398 - Pointer operator->() const {
153.399 - return &(operator*());
153.400 - }
153.401 -
153.402 - protected:
153.403 -
153.404 - Map* map;
153.405 -
153.406 - public:
153.407 - // STL compatibility typedefs.
153.408 - typedef std::forward_iterator_tag iterator_category;
153.409 - typedef int difference_type;
153.410 - typedef Value value_type;
153.411 - typedef Reference reference;
153.412 - typedef Pointer pointer;
153.413 - };
153.414 -
153.415 - /** MapValueIterator creates an stl compatible iterator
153.416 - * for the values.
153.417 - */
153.418 - template <
153.419 - typename _Graph,
153.420 - typename _Item,
153.421 - typename _Map>
153.422 - class MapConstValueIterator : public MapIteratorBase<_Graph, _Item> {
153.423 -
153.424 - public:
153.425 -
153.426 - /// The iterator base class.
153.427 - typedef MapIteratorBase<_Graph, _Item> Parent;
153.428 -
153.429 - typedef _Graph Graph;
153.430 - typedef _Item Item;
153.431 - typedef _Map Map;
153.432 -
153.433 - protected:
153.434 -
153.435 - /// The iterator to iterate on the keys.
153.436 - typedef typename Parent::ItemIt ItemIt;
153.437 -
153.438 - /// The value type of the iterator.
153.439 - typedef typename ReferenceMapTraits<Map>::Value MapValue;
153.440 - /// The reference type of the iterator.
153.441 - typedef typename ReferenceMapTraits<Map>::ConstReference MapReference;
153.442 - /// The pointer type of the iterator.
153.443 - typedef typename ReferenceMapTraits<Map>::ConstPointer MapPointer;
153.444 -
153.445 - public:
153.446 -
153.447 - typedef MapValue Value;
153.448 - typedef MapReference Reference;
153.449 - typedef MapPointer Pointer;
153.450 -
153.451 - /// Default constructor.
153.452 - MapConstValueIterator() {}
153.453 -
153.454 - /// Map and ItemIt initialized iterator.
153.455 - MapConstValueIterator(const Map& _map, const ItemIt& _it)
153.456 - : Parent(_it), map(&_map) {}
153.457 -
153.458 -
153.459 - /// The pre increment operator of the iterator.
153.460 - MapConstValueIterator& operator++() {
153.461 - Parent::increment();
153.462 - return *this;
153.463 - }
153.464 -
153.465 - /// The post increment operator of the iterator.
153.466 - MapConstValueIterator operator++(int) {
153.467 - MapConstValueIterator tmp(*this);
153.468 - Parent::increment();
153.469 - return tmp;
153.470 - }
153.471 -
153.472 - /// The dereferencing operator of the iterator.
153.473 - Reference operator*() const {
153.474 - return (*map)[Parent::it];
153.475 - }
153.476 -
153.477 - /// The arrow operator of the iterator.
153.478 - Pointer operator->() const {
153.479 - return &(operator*());
153.480 - }
153.481 -
153.482 - protected:
153.483 -
153.484 - const Map* map;
153.485 -
153.486 - public:
153.487 - // STL compatibility typedefs.
153.488 - typedef std::forward_iterator_tag iterator_category;
153.489 - typedef int difference_type;
153.490 - typedef Value value_type;
153.491 - typedef Reference reference;
153.492 - typedef Pointer pointer;
153.493 - };
153.494 -
153.495 -
153.496 - /** This class makes from a map an iteratable set
153.497 - * which contains all the keys of the map.
153.498 - */
153.499 - template <typename _Graph, typename _Item>
153.500 - class MapConstKeySet {
153.501 -
153.502 - public:
153.503 -
153.504 - typedef _Graph Graph;
153.505 - /// The key type of the iterator.
153.506 - typedef _Item Item;
153.507 - /// The iterator to iterate on the keys.
153.508 -
153.509 - protected:
153.510 -
153.511 - typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
153.512 -
153.513 - public:
153.514 -
153.515 - /// The map initialized const key set.
153.516 - MapConstKeySet(const Graph& _graph) : graph(&_graph) {}
153.517 -
153.518 - /// The const iterator of the set.
153.519 - typedef MapConstKeyIterator<_Graph, _Item> ConstIterator;
153.520 -
153.521 - typedef typename ConstIterator::Value Value;
153.522 - /// The reference type of the iterator.
153.523 - typedef typename ConstIterator::Reference ConstReference;
153.524 - /// The pointer type of the iterator.
153.525 - typedef typename ConstIterator::Pointer ConstPointer;
153.526 -
153.527 - /// It gives back the const iterator pointed to the first element.
153.528 - ConstIterator begin() const {
153.529 - return ConstIterator(ItemIt(*graph));
153.530 - }
153.531 -
153.532 - /// It gives back the const iterator pointed to the first ivalid element.
153.533 - ConstIterator end() const {
153.534 - return ConstIterator(ItemIt(INVALID));
153.535 - }
153.536 -
153.537 - protected:
153.538 -
153.539 - const Graph* graph;
153.540 -
153.541 - public:
153.542 - // STL compatibility typedefs.
153.543 - typedef Value value_type;
153.544 - typedef ConstIterator const_iterator;
153.545 - typedef ConstReference const_reference;
153.546 - typedef ConstPointer const_pointer;
153.547 - typedef int difference_type;
153.548 - };
153.549 -
153.550 - /** This class makes from a map an iteratable set
153.551 - * which contains all the values of the map.
153.552 - * The values cannot be modified.
153.553 - */
153.554 - template <typename _Graph, typename _Item, typename _Map>
153.555 - class MapConstValueSet {
153.556 -
153.557 - public:
153.558 -
153.559 - typedef _Graph Graph;
153.560 - typedef _Item Item;
153.561 - typedef _Map Map;
153.562 -
153.563 - protected:
153.564 -
153.565 - /// The iterator to iterate on the keys.
153.566 - typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
153.567 -
153.568 - public:
153.569 -
153.570 - /// The map initialized const value set.
153.571 - MapConstValueSet(const Graph& _graph, const Map& _map)
153.572 - : graph(&_graph), map(&_map) {}
153.573 -
153.574 - /// The const iterator of the set.
153.575 - typedef MapConstValueIterator<_Graph, _Item, _Map> ConstIterator;
153.576 -
153.577 - typedef typename ConstIterator::Value Value;
153.578 - typedef typename ConstIterator::Reference ConstReference;
153.579 - typedef typename ConstIterator::Pointer ConstPointer;
153.580 -
153.581 - /// It gives back the const iterator pointed to the first element.
153.582 - ConstIterator begin() const {
153.583 - return ConstIterator(*map, ItemIt(*graph));
153.584 - }
153.585 -
153.586 - /// It gives back the const iterator pointed to the first invalid element.
153.587 - ConstIterator end() const {
153.588 - return ConstIterator(*map, ItemIt(INVALID));
153.589 - }
153.590 -
153.591 - protected:
153.592 -
153.593 - const Map* map;
153.594 - const Graph * graph;
153.595 -
153.596 - public:
153.597 - // STL compatibility typedefs.
153.598 - typedef Value value_type;
153.599 - typedef ConstIterator const_iterator;
153.600 - typedef ConstReference const_reference;
153.601 - typedef ConstPointer const_pointer;
153.602 - typedef int difference_type;
153.603 - };
153.604 -
153.605 -
153.606 - /** This class makes from a map an iteratable set
153.607 - * which contains all the values of the map.
153.608 - * The values can be modified.
153.609 - */
153.610 - template <typename _Graph, typename _Item, typename _Map>
153.611 - class MapValueSet {
153.612 -
153.613 - public:
153.614 -
153.615 - typedef _Graph Graph;
153.616 - typedef _Item Item;
153.617 - typedef _Map Map;
153.618 -
153.619 - protected:
153.620 -
153.621 - /// The iterator to iterate on the keys.
153.622 - typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
153.623 -
153.624 - public:
153.625 -
153.626 - /// The map initialized const value set.
153.627 - MapValueSet(const Graph& _graph, Map& _map)
153.628 - : map(&_map), graph(&_graph) {}
153.629 -
153.630 - /// The const iterator of the set.
153.631 - typedef MapValueIterator<_Graph, _Item, _Map> Iterator;
153.632 - /// The const iterator of the set.
153.633 - typedef MapConstValueIterator<_Graph, _Item, _Map> ConstIterator;
153.634 -
153.635 - typedef typename ConstIterator::Value Value;
153.636 - typedef typename Iterator::Reference Reference;
153.637 - typedef typename Iterator::Pointer Pointer;
153.638 - typedef typename ConstIterator::Reference ConstReference;
153.639 - typedef typename ConstIterator::Pointer ConstPointer;
153.640 -
153.641 - /// It gives back the const iterator pointed to the first element.
153.642 - ConstIterator begin() const {
153.643 - return ConstIterator(*map, ItemIt(*graph));
153.644 - }
153.645 -
153.646 - /// It gives back the const iterator pointed to the first invalid element.
153.647 - ConstIterator end() const {
153.648 - return ConstIterator(*map, ItemIt(INVALID));
153.649 - }
153.650 -
153.651 - /// It gives back the iterator pointed to the first element.
153.652 - Iterator begin() {
153.653 - return Iterator(*map, ItemIt(*graph));
153.654 - }
153.655 -
153.656 - /// It gives back the iterator pointed to the first invalid element.
153.657 - Iterator end() {
153.658 - return Iterator(*map, ItemIt(INVALID));
153.659 - }
153.660 -
153.661 - protected:
153.662 -
153.663 - Map* map;
153.664 - const Graph * graph;
153.665 -
153.666 - public:
153.667 - // STL compatibility typedefs.
153.668 - typedef Value value_type;
153.669 - typedef Iterator iterator;
153.670 - typedef ConstIterator const_iterator;
153.671 - typedef Reference reference;
153.672 - typedef ConstReference const_reference;
153.673 - typedef Pointer pointer;
153.674 - typedef ConstPointer const_pointer;
153.675 - typedef int difference_type;
153.676 -
153.677 - };
153.678 -
153.679 - /** This class makes from a map an iteratable set
153.680 - * which contains all the values of the map.
153.681 - * The values can be modified.
153.682 - */
153.683 - template <
153.684 - typename _Graph,
153.685 - typename _Item,
153.686 - typename _Map
153.687 - >
153.688 - class MapSet {
153.689 - public:
153.690 -
153.691 - typedef _Graph Graph;
153.692 - typedef _Item Item;
153.693 - typedef _Map Map;
153.694 -
153.695 - protected:
153.696 -
153.697 - typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
153.698 -
153.699 - public:
153.700 -
153.701 - /// The map initialized value set.
153.702 - MapSet(const Graph& _graph, Map& _map) : graph(&_graph), map(&_map) {}
153.703 -
153.704 - /// The const iterator of the set.
153.705 - typedef MapIterator<_Graph, _Item, _Map> Iterator;
153.706 - typedef MapConstIterator<_Graph, _Item, _Map> ConstIterator;
153.707 -
153.708 - typedef typename ConstIterator::Value Value;
153.709 - typedef typename Iterator::Reference Reference;
153.710 - typedef typename Iterator::Pointer Pointer;
153.711 - typedef typename ConstIterator::Reference ConstReference;
153.712 - typedef typename ConstIterator::Pointer ConstPointer;
153.713 -
153.714 -
153.715 - /// It gives back the const iterator pointed to the first element.
153.716 - ConstIterator begin() const {
153.717 - return ConstIterator(*map, ItemIt(*graph));
153.718 - }
153.719 -
153.720 - /// It gives back the const iterator pointed to the first invalid element.
153.721 - ConstIterator end() const {
153.722 - return ConstIterator(*map, ItemIt(INVALID));
153.723 - }
153.724 -
153.725 - /// The iterator of the set.
153.726 -
153.727 - /// It gives back the iterator pointed to the first element.
153.728 - Iterator begin() {
153.729 - return Iterator(*map, ItemIt(*graph));
153.730 - }
153.731 -
153.732 - /// It gives back the iterator pointed to the first invalid element.
153.733 - Iterator end() {
153.734 - return Iterator(*map, ItemIt(INVALID));
153.735 - }
153.736 -
153.737 - protected:
153.738 -
153.739 - const Graph* graph;
153.740 - Map* map;
153.741 -
153.742 - public:
153.743 - // STL compatibility typedefs.
153.744 - typedef Value value_type;
153.745 - typedef Iterator iterator;
153.746 - typedef ConstIterator const_iterator;
153.747 - typedef Reference reference;
153.748 - typedef ConstReference const_reference;
153.749 - typedef Pointer pointer;
153.750 - typedef ConstPointer const_pointer;
153.751 - typedef int difference_type;
153.752 -
153.753 - };
153.754 -
153.755 - template <
153.756 - typename _Graph,
153.757 - typename _Item,
153.758 - typename _Map
153.759 - >
153.760 - class ConstMapSet {
153.761 -
153.762 - typedef _Graph Graph;
153.763 - typedef _Map Map;
153.764 -
153.765 - const Graph* graph;
153.766 - const Map* map;
153.767 -
153.768 - public:
153.769 -
153.770 - typedef typename ItemSetTraits<_Graph, _Item>::ItemIt ItemIt;
153.771 -
153.772 -
153.773 - /// The map initialized value set.
153.774 - ConstMapSet(const Graph& _graph, const Map& _map)
153.775 - : graph(&_graph), map(&_map) {}
153.776 -
153.777 - /// The const iterator of the set.
153.778 - typedef MapConstIterator<_Graph, _Item, _Map> ConstIterator;
153.779 -
153.780 - typedef typename ConstIterator::Value Value;
153.781 - typedef typename ConstIterator::Reference ConstReference;
153.782 - typedef typename ConstIterator::Pointer ConstPointer;
153.783 -
153.784 -
153.785 - /// It gives back the const iterator pointed to the first element.
153.786 - ConstIterator begin() const {
153.787 - return ConstIterator(*map, ItemIt(*graph));
153.788 - }
153.789 -
153.790 - /// It gives back the const iterator pointed to the first invalid element.
153.791 - ConstIterator end() const {
153.792 - return ConstIterator(*map, ItemIt(INVALID));
153.793 - }
153.794 -
153.795 - public:
153.796 - // STL compatibility typedefs.
153.797 - typedef Value value_type;
153.798 - typedef ConstIterator const_iterator;
153.799 - typedef ConstReference const_reference;
153.800 - typedef ConstPointer const_pointer;
153.801 - typedef int difference_type;
153.802 -
153.803 - };
153.804 -
153.805 - template <typename _Map>
153.806 - class IterableMapExtender : public _Map {
153.807 - public:
153.808 -
153.809 - typedef _Map Parent;
153.810 - typedef Parent Map;
153.811 - typedef typename Map::Graph Graph;
153.812 - typedef typename Map::Key Item;
153.813 - typedef typename Map::Value Value;
153.814 -
153.815 - typedef MapSet<Graph, Item, Map> MapSet;
153.816 -
153.817 - IterableMapExtender() : Parent() {}
153.818 -
153.819 - IterableMapExtender(const Graph& graph) : Parent(graph) {}
153.820 -
153.821 - IterableMapExtender(const Graph& graph, const Value& value)
153.822 - : Parent(graph, value) {}
153.823 -
153.824 - MapSet mapSet() {
153.825 - return MapSet(*Parent::getGraph(), *this);
153.826 - }
153.827 -
153.828 - typedef ConstMapSet<Graph, Item, Map> ConstMapSet;
153.829 -
153.830 - ConstMapSet mapSet() const {
153.831 - return ConstMapSet(*Parent::getGraph(), *this);
153.832 - }
153.833 -
153.834 - typedef MapConstKeySet<Graph, Item> ConstKeySet;
153.835 -
153.836 - ConstKeySet keySet() const {
153.837 - return ConstKeySet(*Parent::getGraph());
153.838 - }
153.839 -
153.840 - typedef MapValueSet<Graph, Item, Map> ValueSet;
153.841 -
153.842 - ValueSet valueSet() {
153.843 - return ValueSet(*Parent::getGraph(), *this);
153.844 - }
153.845 -
153.846 - typedef MapConstValueSet<Graph, Item, Map> ConstValueSet;
153.847 -
153.848 - ConstValueSet valueSet() const {
153.849 - return ConstValueSet(*Parent::getGraph(), *this);
153.850 - }
153.851 -
153.852 - };
153.853 -
153.854 - /// @}
153.855 -
153.856 -}
153.857 -
153.858 -#endif
154.1 --- a/src/lemon/bits/undir_graph_extender.h Sat May 21 21:04:57 2005 +0000
154.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
154.3 @@ -1,278 +0,0 @@
154.4 -/* -*- C++ -*-
154.5 - *
154.6 - * src/lemon/undir_graph_extender.h - Part of LEMON, a generic C++
154.7 - * optimization library
154.8 - *
154.9 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
154.10 - * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
154.11 - * EGRES).
154.12 - *
154.13 - * Permission to use, modify and distribute this software is granted
154.14 - * provided that this copyright notice appears in all copies. For
154.15 - * precise terms see the accompanying LICENSE file.
154.16 - *
154.17 - * This software is provided "AS IS" with no warranty of any kind,
154.18 - * express or implied, and with no claim as to its suitability for any
154.19 - * purpose.
154.20 - *
154.21 - */
154.22 -
154.23 -#ifndef LEMON_UNDIR_GRAPH_EXTENDER_H
154.24 -#define LEMON_UNDIR_GRAPH_EXTENDER_H
154.25 -
154.26 -#include <lemon/invalid.h>
154.27 -
154.28 -namespace lemon {
154.29 -
154.30 - template <typename _Base>
154.31 - class UndirGraphExtender : public _Base {
154.32 - typedef _Base Parent;
154.33 - typedef UndirGraphExtender Graph;
154.34 -
154.35 - public:
154.36 -
154.37 - typedef typename Parent::Edge UndirEdge;
154.38 - typedef typename Parent::Node Node;
154.39 -
154.40 - class Edge : public UndirEdge {
154.41 - friend class UndirGraphExtender;
154.42 -
154.43 - protected:
154.44 - // FIXME: Marci use opposite logic in his graph adaptors. It would
154.45 - // be reasonable to syncronize...
154.46 - bool forward;
154.47 -
154.48 - public:
154.49 - Edge() {}
154.50 -
154.51 - /// \brief Directed edge from undirected edge and a direction.
154.52 - ///
154.53 - /// This constructor is not a part of the concept interface of
154.54 - /// undirected graph, so please avoid using it if possible!
154.55 - Edge(const UndirEdge &ue, bool _forward) :
154.56 - UndirEdge(ue), forward(_forward) {}
154.57 -
154.58 - /// \brief Directed edge from undirected edge and a source node.
154.59 - ///
154.60 - /// Constructs a directed edge from undirected edge and a source node.
154.61 - ///
154.62 - /// \note You have to specify the graph for this constructor.
154.63 - Edge(const Graph &g, const UndirEdge &ue, const Node &n) :
154.64 - UndirEdge(ue) { forward = (g.source(ue) == n); }
154.65 -
154.66 - /// Invalid edge constructor
154.67 - Edge(Invalid i) : UndirEdge(i), forward(true) {}
154.68 -
154.69 - bool operator==(const Edge &that) const {
154.70 - return forward==that.forward && UndirEdge(*this)==UndirEdge(that);
154.71 - }
154.72 - bool operator!=(const Edge &that) const {
154.73 - return forward!=that.forward || UndirEdge(*this)!=UndirEdge(that);
154.74 - }
154.75 - bool operator<(const Edge &that) const {
154.76 - return forward<that.forward ||
154.77 - (!(that.forward<forward) && UndirEdge(*this)<UndirEdge(that));
154.78 - }
154.79 - };
154.80 -
154.81 -
154.82 - /// \brief Edge of opposite direction.
154.83 - ///
154.84 - /// Returns the Edge of opposite direction.
154.85 - Edge opposite(const Edge &e) const {
154.86 - return Edge(e,!e.forward);
154.87 - }
154.88 -
154.89 - protected:
154.90 -
154.91 - template <typename E>
154.92 - Node _dirSource(const E &e) const {
154.93 - return e.forward ? Parent::source(e) : Parent::target(e);
154.94 - }
154.95 -
154.96 - template <typename E>
154.97 - Node _dirTarget(const E &e) const {
154.98 - return e.forward ? Parent::target(e) : Parent::source(e);
154.99 - }
154.100 -
154.101 - public:
154.102 - /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
154.103 - /// or something???
154.104 - using Parent::source;
154.105 -
154.106 - /// Source of the given Edge.
154.107 - Node source(const Edge &e) const {
154.108 - return _dirSource(e);
154.109 - }
154.110 -
154.111 - /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
154.112 - /// or something???
154.113 - using Parent::target;
154.114 -
154.115 - /// Target of the given Edge.
154.116 - Node target(const Edge &e) const {
154.117 - return _dirTarget(e);
154.118 - }
154.119 -
154.120 - /// Returns whether the given directed edge is same orientation as the
154.121 - /// corresponding undirected edge.
154.122 - ///
154.123 - /// \todo reference to the corresponding point of the undirected graph
154.124 - /// concept. "What does the direction of an undirected edge mean?"
154.125 - bool forward(const Edge &e) const { return e.forward; }
154.126 -
154.127 - Node oppositeNode(const Node &n, const UndirEdge &e) const {
154.128 - if( n == Parent::source(e))
154.129 - return Parent::target(e);
154.130 - else if( n == Parent::target(e))
154.131 - return Parent::source(e);
154.132 - else
154.133 - return INVALID;
154.134 - }
154.135 -
154.136 - /// Directed edge from an undirected edge and a source node.
154.137 - ///
154.138 - /// Returns a (directed) Edge corresponding to the specified UndirEdge
154.139 - /// and source Node.
154.140 - ///
154.141 - ///\todo Do we need this?
154.142 - ///
154.143 - ///\todo Better name...
154.144 - Edge edgeWithSource(const UndirEdge &ue, const Node &s) const {
154.145 - return Edge(*this, ue, s);
154.146 - }
154.147 -
154.148 - using Parent::first;
154.149 - void first(Edge &e) const {
154.150 - Parent::first(e);
154.151 - e.forward=true;
154.152 - }
154.153 -
154.154 - using Parent::next;
154.155 - void next(Edge &e) const {
154.156 - if( e.forward ) {
154.157 - e.forward = false;
154.158 - }
154.159 - else {
154.160 - Parent::next(e);
154.161 - e.forward = true;
154.162 - }
154.163 - }
154.164 -
154.165 -
154.166 - protected:
154.167 -
154.168 - template <typename E>
154.169 - void _dirFirstOut(E &e, const Node &n) const {
154.170 - Parent::firstIn(e,n);
154.171 - if( UndirEdge(e) != INVALID ) {
154.172 - e.forward = false;
154.173 - }
154.174 - else {
154.175 - Parent::firstOut(e,n);
154.176 - e.forward = true;
154.177 - }
154.178 - }
154.179 - template <typename E>
154.180 - void _dirFirstIn(E &e, const Node &n) const {
154.181 - Parent::firstOut(e,n);
154.182 - if( UndirEdge(e) != INVALID ) {
154.183 - e.forward = false;
154.184 - }
154.185 - else {
154.186 - Parent::firstIn(e,n);
154.187 - e.forward = true;
154.188 - }
154.189 - }
154.190 -
154.191 - template <typename E>
154.192 - void _dirNextOut(E &e) const {
154.193 - if( ! e.forward ) {
154.194 - Node n = Parent::target(e);
154.195 - Parent::nextIn(e);
154.196 - if( UndirEdge(e) == INVALID ) {
154.197 - Parent::firstOut(e, n);
154.198 - e.forward = true;
154.199 - }
154.200 - }
154.201 - else {
154.202 - Parent::nextOut(e);
154.203 - }
154.204 - }
154.205 - template <typename E>
154.206 - void _dirNextIn(E &e) const {
154.207 - if( ! e.forward ) {
154.208 - Node n = Parent::source(e);
154.209 - Parent::nextOut(e);
154.210 - if( UndirEdge(e) == INVALID ) {
154.211 - Parent::firstIn(e, n);
154.212 - e.forward = true;
154.213 - }
154.214 - }
154.215 - else {
154.216 - Parent::nextIn(e);
154.217 - }
154.218 - }
154.219 -
154.220 - public:
154.221 -
154.222 - void firstOut(Edge &e, const Node &n) const {
154.223 - _dirFirstOut(e, n);
154.224 - }
154.225 - void firstIn(Edge &e, const Node &n) const {
154.226 - _dirFirstIn(e, n);
154.227 - }
154.228 -
154.229 - void nextOut(Edge &e) const {
154.230 - _dirNextOut(e);
154.231 - }
154.232 - void nextIn(Edge &e) const {
154.233 - _dirNextIn(e);
154.234 - }
154.235 -
154.236 - // Miscellaneous stuff:
154.237 -
154.238 - /// \todo these methods (id, maxEdgeId) should be moved into separate
154.239 - /// Extender
154.240 -
154.241 - // using Parent::id;
154.242 - // Using "using" is not a good idea, cause it could be that there is
154.243 - // no "id" in Parent...
154.244 -
154.245 - int id(const Node &n) const {
154.246 - return Parent::id(n);
154.247 - }
154.248 -
154.249 - int id(const UndirEdge &e) const {
154.250 - return Parent::id(e);
154.251 - }
154.252 -
154.253 - int id(const Edge &e) const {
154.254 - return 2 * Parent::id(e) + int(e.forward);
154.255 - }
154.256 -
154.257 -
154.258 - int maxId(Node) const {
154.259 - return Parent::maxId(Node());
154.260 - }
154.261 -
154.262 - int maxId(Edge) const {
154.263 - return 2 * Parent::maxId(typename Parent::Edge()) + 1;
154.264 - }
154.265 - int maxId(UndirEdge) const {
154.266 - return Parent::maxId(typename Parent::Edge());
154.267 - }
154.268 -
154.269 -
154.270 - int edgeNum() const {
154.271 - return 2 * Parent::edgeNum();
154.272 - }
154.273 - int undirEdgeNum() const {
154.274 - return Parent::edgeNum();
154.275 - }
154.276 -
154.277 - };
154.278 -
154.279 -}
154.280 -
154.281 -#endif // LEMON_UNDIR_GRAPH_EXTENDER_H
155.1 --- a/src/lemon/bits/vector_map.h Sat May 21 21:04:57 2005 +0000
155.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
155.3 @@ -1,288 +0,0 @@
155.4 -/* -*- C++ -*-
155.5 - * src/lemon/vector_map.h - Part of LEMON, a generic C++ optimization library
155.6 - *
155.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
155.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
155.9 - *
155.10 - * Permission to use, modify and distribute this software is granted
155.11 - * provided that this copyright notice appears in all copies. For
155.12 - * precise terms see the accompanying LICENSE file.
155.13 - *
155.14 - * This software is provided "AS IS" with no warranty of any kind,
155.15 - * express or implied, and with no claim as to its suitability for any
155.16 - * purpose.
155.17 - *
155.18 - */
155.19 -
155.20 -#ifndef LEMON_VECTOR_MAP_H
155.21 -#define LEMON_VECTOR_MAP_H
155.22 -
155.23 -#include <vector>
155.24 -#include <algorithm>
155.25 -
155.26 -#include <lemon/utility.h>
155.27 -#include <lemon/bits/map_iterator.h>
155.28 -#include <lemon/bits/alteration_notifier.h>
155.29 -
155.30 -///\ingroup graphmaps
155.31 -///\file
155.32 -///\brief Vector based graph maps.
155.33 -
155.34 -namespace lemon {
155.35 -
155.36 - /// \addtogroup graphmaps
155.37 - /// @{
155.38 -
155.39 - /// The VectorMap template class is graph map structure what
155.40 - /// automatically updates the map when a key is added to or erased from
155.41 - /// the map. This map factory uses the allocators to implement
155.42 - /// the container functionality. This map factory
155.43 - /// uses the std::vector to implement the container function.
155.44 - ///
155.45 - /// \param Registry The AlterationNotifier that will notify this map.
155.46 - /// \param IdMap The IdMap type of the graph items.
155.47 - /// \param Value The value type of the map.
155.48 - ///
155.49 - /// \author Balazs Dezso
155.50 -
155.51 -
155.52 - template <
155.53 - typename _Graph,
155.54 - typename _Item,
155.55 - typename _Value
155.56 - >
155.57 - class VectorMap : public AlterationNotifier<_Item>::ObserverBase {
155.58 - public:
155.59 -
155.60 - /// The graph type of the map.
155.61 - typedef _Graph Graph;
155.62 - /// The key type of the map.
155.63 - typedef _Item Key;
155.64 - /// The id map type of the map.
155.65 - typedef AlterationNotifier<_Item> Registry;
155.66 - /// The value type of the map.
155.67 - typedef _Value Value;
155.68 -
155.69 - /// The map type.
155.70 - typedef VectorMap Map;
155.71 - /// The base class of the map.
155.72 - typedef typename Registry::ObserverBase Parent;
155.73 -
155.74 - private:
155.75 -
155.76 - /// The container type of the map.
155.77 - typedef std::vector<Value> Container;
155.78 -
155.79 - public:
155.80 -
155.81 - /// The reference type of the map;
155.82 - typedef typename Container::reference Reference;
155.83 - /// The pointer type of the map;
155.84 - typedef typename Container::pointer Pointer;
155.85 -
155.86 - /// The const value type of the map.
155.87 - typedef const Value ConstValue;
155.88 - /// The const reference type of the map;
155.89 - typedef typename Container::const_reference ConstReference;
155.90 - /// The pointer type of the map;
155.91 - typedef typename Container::const_pointer ConstPointer;
155.92 -
155.93 - typedef True FullTypeTag;
155.94 -
155.95 - /// Constructor to attach the new map into the registry.
155.96 -
155.97 - /// It construates a map and attachs it into the registry.
155.98 - /// It adds all the items of the graph to the map.
155.99 -
155.100 - VectorMap(const Graph& _g) : graph(&_g) {
155.101 - attach(_g.getNotifier(_Item()));
155.102 - build();
155.103 - }
155.104 -
155.105 - /// Constructor uses given value to initialize the map.
155.106 -
155.107 - /// It construates a map uses a given value to initialize the map.
155.108 - /// It adds all the items of the graph to the map.
155.109 -
155.110 - VectorMap(const Graph& _g, const Value& _v) : graph(&_g) {
155.111 - attach(_g.getNotifier(_Item()));
155.112 - container.resize(graph->maxId(_Item()) + 1, _v);
155.113 - }
155.114 -
155.115 - VectorMap(const VectorMap& _copy)
155.116 - : Parent(), graph(_copy.getGraph()) {
155.117 - if (_copy.attached()) {
155.118 - attach(*_copy.getRegistry());
155.119 - container = _copy.container;
155.120 - }
155.121 - }
155.122 -
155.123 - using Parent::attach;
155.124 - using Parent::detach;
155.125 - using Parent::attached;
155.126 -
155.127 - /** Assign operator to copy a map of the same map type.
155.128 - */
155.129 - VectorMap& operator=(const VectorMap& copy) {
155.130 - if (© == this) return *this;
155.131 -
155.132 - if (graph != copy.graph) {
155.133 - if (attached()) {
155.134 - detach();
155.135 - }
155.136 - if (copy.attached()) {
155.137 - attach(*copy.getRegistry());
155.138 - }
155.139 - }
155.140 - container = copy.container;
155.141 -
155.142 - return *this;
155.143 - }
155.144 -
155.145 -
155.146 - virtual ~VectorMap() {
155.147 - if (attached()) {
155.148 - detach();
155.149 - }
155.150 - }
155.151 -
155.152 - const Graph* getGraph() const {
155.153 - return graph;
155.154 - }
155.155 -
155.156 - /// The subcript operator.
155.157 -
155.158 - /// The subscript operator. The map can be subscripted by the
155.159 - /// actual items of the graph.
155.160 -
155.161 - Reference operator[](const Key& key) {
155.162 - return container[graph->id(key)];
155.163 - }
155.164 -
155.165 - /// The const subcript operator.
155.166 -
155.167 - /// The const subscript operator. The map can be subscripted by the
155.168 - /// actual items of the graph.
155.169 -
155.170 - ConstReference operator[](const Key& key) const {
155.171 - return container[graph->id(key)];
155.172 - }
155.173 -
155.174 -
155.175 - /// The setter function of the map.
155.176 -
155.177 - /// It the same as operator[](key) = value expression.
155.178 - ///
155.179 -
155.180 - void set(const Key& key, const Value& value) {
155.181 - (*this)[key] = value;
155.182 - }
155.183 -
155.184 - /// Adds a new key to the map.
155.185 -
155.186 - /// It adds a new key to the map. It called by the observer registry
155.187 - /// and it overrides the add() member function of the observer base.
155.188 -
155.189 - void add(const Key& key) {
155.190 - int id = graph->id(key);
155.191 - if (id >= (int)container.size()) {
155.192 - container.resize(id + 1);
155.193 - }
155.194 - }
155.195 -
155.196 - /// Erases a key from the map.
155.197 -
155.198 - /// Erase a key from the map. It called by the observer registry
155.199 - /// and it overrides the erase() member function of the observer base.
155.200 - void erase(const Key&) {}
155.201 -
155.202 - /// Buildes the map.
155.203 -
155.204 - /// It buildes the map. It called by the observer registry
155.205 - /// and it overrides the build() member function of the observer base.
155.206 -
155.207 - void build() {
155.208 - container.resize(graph->maxId(_Item()) + 1);
155.209 - }
155.210 -
155.211 - /// Clear the map.
155.212 -
155.213 - /// It erase all items from the map. It called by the observer registry
155.214 - /// and it overrides the clear() member function of the observer base.
155.215 - void clear() {
155.216 - container.clear();
155.217 - }
155.218 -
155.219 - private:
155.220 -
155.221 - Container container;
155.222 - const Graph *graph;
155.223 -
155.224 - };
155.225 -
155.226 -
155.227 - template <typename _Base>
155.228 - class VectorMappableGraphExtender : public _Base {
155.229 - public:
155.230 -
155.231 - typedef VectorMappableGraphExtender<_Base> Graph;
155.232 - typedef _Base Parent;
155.233 -
155.234 - typedef typename Parent::Node Node;
155.235 - typedef typename Parent::NodeIt NodeIt;
155.236 - typedef typename Parent::NodeIdMap NodeIdMap;
155.237 - typedef typename Parent::NodeNotifier NodeObserverRegistry;
155.238 -
155.239 - typedef typename Parent::Edge Edge;
155.240 - typedef typename Parent::EdgeIt EdgeIt;
155.241 - typedef typename Parent::EdgeIdMap EdgeIdMap;
155.242 - typedef typename Parent::EdgeNotifier EdgeObserverRegistry;
155.243 -
155.244 -
155.245 - template <typename _Value>
155.246 - class NodeMap :
155.247 - public IterableMapExtender<VectorMap<Graph, Node, _Value> > {
155.248 - public:
155.249 - typedef VectorMappableGraphExtender<_Base> Graph;
155.250 -
155.251 - typedef typename Graph::Node Node;
155.252 -
155.253 - typedef IterableMapExtender<VectorMap<Graph, Node, _Value> > Parent;
155.254 -
155.255 - //typedef typename Parent::Graph Graph;
155.256 - typedef typename Parent::Value Value;
155.257 -
155.258 - NodeMap(const Graph& g)
155.259 - : Parent(g) {}
155.260 - NodeMap(const Graph& g, const Value& v)
155.261 - : Parent(g, v) {}
155.262 -
155.263 - };
155.264 -
155.265 - template <typename _Value>
155.266 - class EdgeMap
155.267 - : public IterableMapExtender<VectorMap<Graph, Edge, _Value> > {
155.268 - public:
155.269 - typedef VectorMappableGraphExtender<_Base> Graph;
155.270 -
155.271 - typedef typename Graph::Edge Edge;
155.272 -
155.273 - typedef IterableMapExtender<VectorMap<Graph, Edge, _Value> > Parent;
155.274 -
155.275 - //typedef typename Parent::Graph Graph;
155.276 - typedef typename Parent::Value Value;
155.277 -
155.278 - EdgeMap(const Graph& g)
155.279 - : Parent(g) {}
155.280 - EdgeMap(const Graph& g, const Value& v)
155.281 - : Parent(g, v) {}
155.282 -
155.283 - };
155.284 -
155.285 - };
155.286 -
155.287 - /// @}
155.288 -
155.289 -}
155.290 -
155.291 -#endif
156.1 --- a/src/lemon/concept/graph.h Sat May 21 21:04:57 2005 +0000
156.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
156.3 @@ -1,578 +0,0 @@
156.4 -/* -*- C++ -*-
156.5 - * src/lemon/concept/graph.h - Part of LEMON, a generic C++ optimization library
156.6 - *
156.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
156.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
156.9 - *
156.10 - * Permission to use, modify and distribute this software is granted
156.11 - * provided that this copyright notice appears in all copies. For
156.12 - * precise terms see the accompanying LICENSE file.
156.13 - *
156.14 - * This software is provided "AS IS" with no warranty of any kind,
156.15 - * express or implied, and with no claim as to its suitability for any
156.16 - * purpose.
156.17 - *
156.18 - */
156.19 -
156.20 -#ifndef LEMON_CONCEPT_GRAPH_H
156.21 -#define LEMON_CONCEPT_GRAPH_H
156.22 -
156.23 -///\ingroup graph_concepts
156.24 -///\file
156.25 -///\brief Declaration of Graph.
156.26 -
156.27 -#include <lemon/invalid.h>
156.28 -#include <lemon/concept/maps.h>
156.29 -#include <lemon/concept_check.h>
156.30 -#include <lemon/concept/graph_component.h>
156.31 -
156.32 -namespace lemon {
156.33 - namespace concept {
156.34 -
156.35 -
156.36 - /// \addtogroup graph_concepts
156.37 - /// @{
156.38 -
156.39 - /**************** The full-featured graph concepts ****************/
156.40 -
156.41 -
156.42 - /// \brief Modular static graph class.
156.43 - ///
156.44 - /// It should be the same as the \c StaticGraph class.
156.45 - class _StaticGraph
156.46 - : virtual public BaseGraphComponent,
156.47 - public IterableGraphComponent, public MappableGraphComponent {
156.48 - public:
156.49 - typedef BaseGraphComponent::Node Node;
156.50 - typedef BaseGraphComponent::Edge Edge;
156.51 -
156.52 - template <typename _Graph>
156.53 - struct Constraints {
156.54 - void constraints() {
156.55 - checkConcept<IterableGraphComponent, _Graph>();
156.56 - checkConcept<MappableGraphComponent, _Graph>();
156.57 - }
156.58 - };
156.59 - };
156.60 -
156.61 - /// \brief Modular extendable graph class.
156.62 - ///
156.63 - /// It should be the same as the \c ExtendableGraph class.
156.64 - class _ExtendableGraph
156.65 - : virtual public BaseGraphComponent, public _StaticGraph,
156.66 - public ExtendableGraphComponent, public ClearableGraphComponent {
156.67 - public:
156.68 - typedef BaseGraphComponent::Node Node;
156.69 - typedef BaseGraphComponent::Edge Edge;
156.70 -
156.71 - template <typename _Graph>
156.72 - struct Constraints {
156.73 - void constraints() {
156.74 - checkConcept<_StaticGraph, _Graph >();
156.75 - checkConcept<ExtendableGraphComponent, _Graph >();
156.76 - checkConcept<ClearableGraphComponent, _Graph >();
156.77 - }
156.78 - };
156.79 - };
156.80 -
156.81 - /// \brief Modular erasable graph class.
156.82 - ///
156.83 - /// It should be the same as the \c ErasableGraph class.
156.84 - class _ErasableGraph
156.85 - : virtual public BaseGraphComponent, public _ExtendableGraph,
156.86 - public ErasableGraphComponent {
156.87 - public:
156.88 - typedef BaseGraphComponent::Node Node;
156.89 - typedef BaseGraphComponent::Edge Edge;
156.90 -
156.91 - template <typename _Graph>
156.92 - struct Constraints {
156.93 - void constraints() {
156.94 - checkConcept<_ExtendableGraph, _Graph >();
156.95 - checkConcept<ErasableGraphComponent, _Graph >();
156.96 - }
156.97 - };
156.98 - };
156.99 -
156.100 - /// An empty static graph class.
156.101 -
156.102 - /// This class provides all the common features of a graph structure,
156.103 - /// however completely without implementations and real data structures
156.104 - /// behind the interface.
156.105 - /// All graph algorithms should compile with this class, but it will not
156.106 - /// run properly, of course.
156.107 - ///
156.108 - /// It can be used for checking the interface compatibility,
156.109 - /// or it can serve as a skeleton of a new graph structure.
156.110 - ///
156.111 - /// Also, you will find here the full documentation of a certain graph
156.112 - /// feature, the documentation of a real graph imlementation
156.113 - /// like @ref ListGraph or
156.114 - /// @ref SmartGraph will just refer to this structure.
156.115 - ///
156.116 - /// \todo A pages describing the concept of concept description would
156.117 - /// be nice.
156.118 - class StaticGraph
156.119 - {
156.120 - public:
156.121 - /// Defalult constructor.
156.122 -
156.123 - /// Defalult constructor.
156.124 - ///
156.125 - StaticGraph() { }
156.126 - ///Copy consructor.
156.127 -
156.128 -// ///\todo It is not clear, what we expect from a copy constructor.
156.129 -// ///E.g. How to assign the nodes/edges to each other? What about maps?
156.130 -// StaticGraph(const StaticGraph& g) { }
156.131 -
156.132 - /// The base type of node iterators,
156.133 - /// or in other words, the trivial node iterator.
156.134 -
156.135 - /// This is the base type of each node iterator,
156.136 - /// thus each kind of node iterator converts to this.
156.137 - /// More precisely each kind of node iterator should be inherited
156.138 - /// from the trivial node iterator.
156.139 - class Node {
156.140 - public:
156.141 - /// Default constructor
156.142 -
156.143 - /// @warning The default constructor sets the iterator
156.144 - /// to an undefined value.
156.145 - Node() { }
156.146 - /// Copy constructor.
156.147 -
156.148 - /// Copy constructor.
156.149 - ///
156.150 - Node(const Node&) { }
156.151 -
156.152 - /// Invalid constructor \& conversion.
156.153 -
156.154 - /// This constructor initializes the iterator to be invalid.
156.155 - /// \sa Invalid for more details.
156.156 - Node(Invalid) { }
156.157 - /// Equality operator
156.158 -
156.159 - /// Two iterators are equal if and only if they point to the
156.160 - /// same object or both are invalid.
156.161 - bool operator==(Node) const { return true; }
156.162 -
156.163 - /// Inequality operator
156.164 -
156.165 - /// \sa operator==(Node n)
156.166 - ///
156.167 - bool operator!=(Node) const { return true; }
156.168 -
156.169 - };
156.170 -
156.171 - /// This iterator goes through each node.
156.172 -
156.173 - /// This iterator goes through each node.
156.174 - /// Its usage is quite simple, for example you can count the number
156.175 - /// of nodes in graph \c g of type \c Graph like this:
156.176 - /// \code
156.177 - /// int count=0;
156.178 - /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
156.179 - /// \endcode
156.180 - class NodeIt : public Node {
156.181 - public:
156.182 - /// Default constructor
156.183 -
156.184 - /// @warning The default constructor sets the iterator
156.185 - /// to an undefined value.
156.186 - NodeIt() { }
156.187 - /// Copy constructor.
156.188 -
156.189 - /// Copy constructor.
156.190 - ///
156.191 - NodeIt(const NodeIt& n) : Node(n) { }
156.192 - /// Invalid constructor \& conversion.
156.193 -
156.194 - /// Initialize the iterator to be invalid.
156.195 - /// \sa Invalid for more details.
156.196 - NodeIt(Invalid) { }
156.197 - /// Sets the iterator to the first node.
156.198 -
156.199 - /// Sets the iterator to the first node of \c g.
156.200 - ///
156.201 - NodeIt(const StaticGraph&) { }
156.202 - /// Node -> NodeIt conversion.
156.203 -
156.204 - /// Sets the iterator to the node of \c g pointed by the trivial
156.205 - /// iterator n.
156.206 - /// This feature necessitates that each time we
156.207 - /// iterate the edge-set, the iteration order is the same.
156.208 - NodeIt(const StaticGraph& g, const Node& n) { }
156.209 - /// Next node.
156.210 -
156.211 - /// Assign the iterator to the next node.
156.212 - ///
156.213 - NodeIt& operator++() { return *this; }
156.214 - };
156.215 -
156.216 -
156.217 - /// The base type of the edge iterators.
156.218 -
156.219 - /// The base type of the edge iterators.
156.220 - ///
156.221 - class Edge {
156.222 - public:
156.223 - /// Default constructor
156.224 -
156.225 - /// @warning The default constructor sets the iterator
156.226 - /// to an undefined value.
156.227 - Edge() { }
156.228 - /// Copy constructor.
156.229 -
156.230 - /// Copy constructor.
156.231 - ///
156.232 - Edge(const Edge&) { }
156.233 - /// Initialize the iterator to be invalid.
156.234 -
156.235 - /// Initialize the iterator to be invalid.
156.236 - ///
156.237 - Edge(Invalid) { }
156.238 - /// Equality operator
156.239 -
156.240 - /// Two iterators are equal if and only if they point to the
156.241 - /// same object or both are invalid.
156.242 - bool operator==(Edge) const { return true; }
156.243 - /// Inequality operator
156.244 -
156.245 - /// \sa operator==(Node n)
156.246 - ///
156.247 - bool operator!=(Edge) const { return true; }
156.248 - };
156.249 -
156.250 - /// This iterator goes trough the outgoing edges of a node.
156.251 -
156.252 - /// This iterator goes trough the \e outgoing edges of a certain node
156.253 - /// of a graph.
156.254 - /// Its usage is quite simple, for example you can count the number
156.255 - /// of outgoing edges of a node \c n
156.256 - /// in graph \c g of type \c Graph as follows.
156.257 - /// \code
156.258 - /// int count=0;
156.259 - /// for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) ++count;
156.260 - /// \endcode
156.261 -
156.262 - class OutEdgeIt : public Edge {
156.263 - public:
156.264 - /// Default constructor
156.265 -
156.266 - /// @warning The default constructor sets the iterator
156.267 - /// to an undefined value.
156.268 - OutEdgeIt() { }
156.269 - /// Copy constructor.
156.270 -
156.271 - /// Copy constructor.
156.272 - ///
156.273 - OutEdgeIt(const OutEdgeIt& e) : Edge(e) { }
156.274 - /// Initialize the iterator to be invalid.
156.275 -
156.276 - /// Initialize the iterator to be invalid.
156.277 - ///
156.278 - OutEdgeIt(Invalid) { }
156.279 - /// This constructor sets the iterator to the first outgoing edge.
156.280 -
156.281 - /// This constructor sets the iterator to the first outgoing edge of
156.282 - /// the node.
156.283 - ///@param n the node
156.284 - ///@param g the graph
156.285 - OutEdgeIt(const StaticGraph&, const Node&) { }
156.286 - /// Edge -> OutEdgeIt conversion
156.287 -
156.288 - /// Sets the iterator to the value of the trivial iterator \c e.
156.289 - /// This feature necessitates that each time we
156.290 - /// iterate the edge-set, the iteration order is the same.
156.291 - OutEdgeIt(const StaticGraph& g, const Edge& e) { }
156.292 - ///Next outgoing edge
156.293 -
156.294 - /// Assign the iterator to the next
156.295 - /// outgoing edge of the corresponding node.
156.296 - OutEdgeIt& operator++() { return *this; }
156.297 - };
156.298 -
156.299 - /// This iterator goes trough the incoming edges of a node.
156.300 -
156.301 - /// This iterator goes trough the \e incoming edges of a certain node
156.302 - /// of a graph.
156.303 - /// Its usage is quite simple, for example you can count the number
156.304 - /// of outgoing edges of a node \c n
156.305 - /// in graph \c g of type \c Graph as follows.
156.306 - /// \code
156.307 - /// int count=0;
156.308 - /// for(Graph::InEdgeIt e(g, n); e!=INVALID; ++e) ++count;
156.309 - /// \endcode
156.310 -
156.311 - class InEdgeIt : public Edge {
156.312 - public:
156.313 - /// Default constructor
156.314 -
156.315 - /// @warning The default constructor sets the iterator
156.316 - /// to an undefined value.
156.317 - InEdgeIt() { }
156.318 - /// Copy constructor.
156.319 -
156.320 - /// Copy constructor.
156.321 - ///
156.322 - InEdgeIt(const InEdgeIt& e) : Edge(e) { }
156.323 - /// Initialize the iterator to be invalid.
156.324 -
156.325 - /// Initialize the iterator to be invalid.
156.326 - ///
156.327 - InEdgeIt(Invalid) { }
156.328 - /// This constructor sets the iterator to first incoming edge.
156.329 -
156.330 - /// This constructor set the iterator to the first incoming edge of
156.331 - /// the node.
156.332 - ///@param n the node
156.333 - ///@param g the graph
156.334 - InEdgeIt(const StaticGraph&, const Node&) { }
156.335 - /// Edge -> InEdgeIt conversion
156.336 -
156.337 - /// Sets the iterator to the value of the trivial iterator \c e.
156.338 - /// This feature necessitates that each time we
156.339 - /// iterate the edge-set, the iteration order is the same.
156.340 - InEdgeIt(const StaticGraph&, const Edge&) { }
156.341 - /// Next incoming edge
156.342 -
156.343 - /// Assign the iterator to the next inedge of the corresponding node.
156.344 - ///
156.345 - InEdgeIt& operator++() { return *this; }
156.346 - };
156.347 - /// This iterator goes through each edge.
156.348 -
156.349 - /// This iterator goes through each edge of a graph.
156.350 - /// Its usage is quite simple, for example you can count the number
156.351 - /// of edges in a graph \c g of type \c Graph as follows:
156.352 - /// \code
156.353 - /// int count=0;
156.354 - /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
156.355 - /// \endcode
156.356 - class EdgeIt : public Edge {
156.357 - public:
156.358 - /// Default constructor
156.359 -
156.360 - /// @warning The default constructor sets the iterator
156.361 - /// to an undefined value.
156.362 - EdgeIt() { }
156.363 - /// Copy constructor.
156.364 -
156.365 - /// Copy constructor.
156.366 - ///
156.367 - EdgeIt(const EdgeIt& e) : Edge(e) { }
156.368 - /// Initialize the iterator to be invalid.
156.369 -
156.370 - /// Initialize the iterator to be invalid.
156.371 - ///
156.372 - EdgeIt(Invalid) { }
156.373 - /// This constructor sets the iterator to the first edge.
156.374 -
156.375 - /// This constructor sets the iterator to the first edge of \c g.
156.376 - ///@param g the graph
156.377 - EdgeIt(const StaticGraph&) { }
156.378 - /// Edge -> EdgeIt conversion
156.379 -
156.380 - /// Sets the iterator to the value of the trivial iterator \c e.
156.381 - /// This feature necessitates that each time we
156.382 - /// iterate the edge-set, the iteration order is the same.
156.383 - EdgeIt(const StaticGraph&, const Edge&) { }
156.384 - ///Next edge
156.385 -
156.386 - /// Assign the iterator to the next edge.
156.387 - EdgeIt& operator++() { return *this; }
156.388 - };
156.389 - ///Gives back the target node of an edge.
156.390 -
156.391 - ///Gives back the target node of an edge.
156.392 - ///
156.393 - Node target(Edge) const { return INVALID; }
156.394 - ///Gives back the source node of an edge.
156.395 -
156.396 - ///Gives back the source node of an edge.
156.397 - ///
156.398 - Node source(Edge) const { return INVALID; }
156.399 - /// Read write map of the nodes to type \c T.
156.400 -
156.401 - /// \ingroup concept
156.402 - /// ReadWrite map of the nodes to type \c T.
156.403 - /// \sa Reference
156.404 - /// \warning Making maps that can handle bool type (NodeMap<bool>)
156.405 - /// needs some extra attention!
156.406 - template<class T>
156.407 - class NodeMap : public ReadWriteMap< Node, T >
156.408 - {
156.409 - public:
156.410 -
156.411 - ///\e
156.412 - NodeMap(const StaticGraph&) { }
156.413 - ///\e
156.414 - NodeMap(const StaticGraph&, T) { }
156.415 -
156.416 - ///Copy constructor
156.417 - NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
156.418 - ///Assignment operator
156.419 - NodeMap& operator=(const NodeMap&) { return *this; }
156.420 - // \todo fix this concept
156.421 - };
156.422 -
156.423 - /// Read write map of the edges to type \c T.
156.424 -
156.425 - /// \ingroup concept
156.426 - ///Reference map of the edges to type \c T.
156.427 - /// \sa Reference
156.428 - /// \warning Making maps that can handle bool type (EdgeMap<bool>)
156.429 - /// needs some extra attention!
156.430 - template<class T>
156.431 - class EdgeMap : public ReadWriteMap<Edge,T>
156.432 - {
156.433 - public:
156.434 -
156.435 - ///\e
156.436 - EdgeMap(const StaticGraph&) { }
156.437 - ///\e
156.438 - EdgeMap(const StaticGraph&, T) { }
156.439 - ///Copy constructor
156.440 - EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) { }
156.441 - ///Assignment operator
156.442 - EdgeMap& operator=(const EdgeMap&) { return *this; }
156.443 - // \todo fix this concept
156.444 - };
156.445 -
156.446 - template <typename _Graph>
156.447 - struct Constraints : public _StaticGraph::Constraints<_Graph> {};
156.448 -
156.449 - };
156.450 -
156.451 - /// An empty non-static graph class.
156.452 -
156.453 - /// This class provides everything that \ref StaticGraph does.
156.454 - /// Additionally it enables building graphs from scratch.
156.455 - class ExtendableGraph : public StaticGraph
156.456 - {
156.457 - public:
156.458 - /// Defalult constructor.
156.459 -
156.460 - /// Defalult constructor.
156.461 - ///
156.462 - ExtendableGraph() { }
156.463 - ///Add a new node to the graph.
156.464 -
156.465 - /// \return the new node.
156.466 - ///
156.467 - Node addNode() { return INVALID; }
156.468 - ///Add a new edge to the graph.
156.469 -
156.470 - ///Add a new edge to the graph with source node \c s
156.471 - ///and target node \c t.
156.472 - ///\return the new edge.
156.473 - Edge addEdge(Node, Node) { return INVALID; }
156.474 -
156.475 - /// Resets the graph.
156.476 -
156.477 - /// This function deletes all edges and nodes of the graph.
156.478 - /// It also frees the memory allocated to store them.
156.479 - /// \todo It might belong to \ref ErasableGraph.
156.480 - void clear() { }
156.481 -
156.482 - template <typename _Graph>
156.483 - struct Constraints : public _ExtendableGraph::Constraints<_Graph> {};
156.484 -
156.485 - };
156.486 -
156.487 - /// An empty erasable graph class.
156.488 -
156.489 - /// This class is an extension of \ref ExtendableGraph. It makes it
156.490 - /// possible to erase edges or nodes.
156.491 - class ErasableGraph : public ExtendableGraph
156.492 - {
156.493 - public:
156.494 - /// Defalult constructor.
156.495 -
156.496 - /// Defalult constructor.
156.497 - ///
156.498 - ErasableGraph() { }
156.499 - /// Deletes a node.
156.500 -
156.501 - /// Deletes node \c n node.
156.502 - ///
156.503 - void erase(Node) { }
156.504 - /// Deletes an edge.
156.505 -
156.506 - /// Deletes edge \c e edge.
156.507 - ///
156.508 - void erase(Edge) { }
156.509 -
156.510 - template <typename _Graph>
156.511 - struct Constraints : public _ErasableGraph::Constraints<_Graph> {};
156.512 -
156.513 - };
156.514 -
156.515 -
156.516 - /************* New GraphBase stuff **************/
156.517 -
156.518 -
156.519 -// /// A minimal GraphBase concept
156.520 -
156.521 -// /// This class describes a minimal concept which can be extended to a
156.522 -// /// full-featured graph with \ref GraphFactory.
156.523 -// class GraphBase {
156.524 -// public:
156.525 -
156.526 -// GraphBase() {}
156.527 -
156.528 -// /// \bug Should we demand that Node and Edge be subclasses of the
156.529 -// /// Graph class???
156.530 -
156.531 -// typedef GraphItem<'n'> Node;
156.532 -// typedef GraphItem<'e'> Edge;
156.533 -
156.534 -// // class Node : public BaseGraphItem<'n'> {};
156.535 -// // class Edge : public BaseGraphItem<'e'> {};
156.536 -
156.537 -// // Graph operation
156.538 -// void firstNode(Node &n) const { }
156.539 -// void firstEdge(Edge &e) const { }
156.540 -
156.541 -// void firstOutEdge(Edge &e, Node) const { }
156.542 -// void firstInEdge(Edge &e, Node) const { }
156.543 -
156.544 -// void nextNode(Node &n) const { }
156.545 -// void nextEdge(Edge &e) const { }
156.546 -
156.547 -
156.548 -// // Question: isn't it reasonable if this methods have a Node
156.549 -// // parameter? Like this:
156.550 -// // Edge& nextOut(Edge &e, Node) const { return e; }
156.551 -// void nextOutEdge(Edge &e) const { }
156.552 -// void nextInEdge(Edge &e) const { }
156.553 -
156.554 -// Node target(Edge) const { return Node(); }
156.555 -// Node source(Edge) const { return Node(); }
156.556 -
156.557 -
156.558 -// // Do we need id, nodeNum, edgeNum and co. in this basic graphbase
156.559 -// // concept?
156.560 -
156.561 -
156.562 -// // Maps.
156.563 -// //
156.564 -// // We need a special slimer concept which does not provide maps (it
156.565 -// // wouldn't be strictly slimer, cause for map-factory id() & friends
156.566 -// // a required...)
156.567 -
156.568 -// template<typename T>
156.569 -// class NodeMap : public GraphMap<GraphBase, Node, T> {};
156.570 -
156.571 -// template<typename T>
156.572 -// class EdgeMap : public GraphMap<GraphBase, Node, T> {};
156.573 -// };
156.574 -
156.575 - // @}
156.576 - } //namespace concept
156.577 -} //namespace lemon
156.578 -
156.579 -
156.580 -
156.581 -#endif // LEMON_CONCEPT_GRAPH_H
157.1 --- a/src/lemon/concept/graph_component.h Sat May 21 21:04:57 2005 +0000
157.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
157.3 @@ -1,982 +0,0 @@
157.4 -/* -*- C++ -*-
157.5 - * src/lemon/concept/graph_component.h - Part of LEMON, a generic C++ optimization library
157.6 - *
157.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
157.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
157.9 - *
157.10 - * Permission to use, modify and distribute this software is granted
157.11 - * provided that this copyright notice appears in all copies. For
157.12 - * precise terms see the accompanying LICENSE file.
157.13 - *
157.14 - * This software is provided "AS IS" with no warranty of any kind,
157.15 - * express or implied, and with no claim as to its suitability for any
157.16 - * purpose.
157.17 - *
157.18 - */
157.19 -
157.20 -///\ingroup graph_concepts
157.21 -///\file
157.22 -///\brief The graph components.
157.23 -
157.24 -
157.25 -#ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H
157.26 -#define LEMON_CONCEPT_GRAPH_COMPONENT_H
157.27 -
157.28 -#include <lemon/invalid.h>
157.29 -#include <lemon/concept/maps.h>
157.30 -
157.31 -#include <lemon/bits/alteration_notifier.h>
157.32 -
157.33 -namespace lemon {
157.34 - namespace concept {
157.35 -
157.36 - /// \addtogroup graph_concepts
157.37 - /// @{
157.38 -
157.39 - /**************** Graph iterator concepts ****************/
157.40 -
157.41 - /// Skeleton class for graph Node and Edge types
157.42 -
157.43 - /// This class describes the interface of Node and Edge (and UndirEdge
157.44 - /// in undirected graphs) subtypes of graph types.
157.45 - ///
157.46 - /// \note This class is a template class so that we can use it to
157.47 - /// create graph skeleton classes. The reason for this is than Node
157.48 - /// and Edge types should \em not derive from the same base class.
157.49 - /// For Node you should instantiate it with character 'n' and for Edge
157.50 - /// with 'e'.
157.51 -
157.52 -#ifndef DOXYGEN
157.53 - template <char _selector = '0'>
157.54 -#endif
157.55 - class GraphItem {
157.56 - public:
157.57 - /// Default constructor.
157.58 -
157.59 - /// \warning The default constructor is not required to set
157.60 - /// the item to some well-defined value. So you should consider it
157.61 - /// as uninitialized.
157.62 - GraphItem() {}
157.63 - /// Copy constructor.
157.64 -
157.65 - /// Copy constructor.
157.66 - ///
157.67 - GraphItem(GraphItem const&) {}
157.68 - /// Invalid constructor \& conversion.
157.69 -
157.70 - /// This constructor initializes the item to be invalid.
157.71 - /// \sa Invalid for more details.
157.72 - GraphItem(Invalid) {}
157.73 - /// Assign operator for nodes.
157.74 -
157.75 - /// The nodes are assignable.
157.76 - ///
157.77 - GraphItem& operator=(GraphItem const&) { return *this; }
157.78 - /// Equality operator.
157.79 -
157.80 - /// Two iterators are equal if and only if they represents the
157.81 - /// same node in the graph or both are invalid.
157.82 - bool operator==(GraphItem) const { return false; }
157.83 - /// Inequality operator.
157.84 -
157.85 - /// \sa operator==(const Node& n)
157.86 - ///
157.87 - bool operator!=(GraphItem) const { return false; }
157.88 -
157.89 - /// Artificial ordering operator.
157.90 -
157.91 - /// To allow the use of graph descriptors as key type in std::map or
157.92 - /// similar associative container we require this.
157.93 - ///
157.94 - /// \note This operator only have to define some strict ordering of
157.95 - /// the items; this order has nothing to do with the iteration
157.96 - /// ordering of the items.
157.97 - ///
157.98 - /// \bug This is a technical requirement. Do we really need this?
157.99 - bool operator<(GraphItem) const { return false; }
157.100 -
157.101 - template<typename _GraphItem>
157.102 - struct Constraints {
157.103 - void constraints() {
157.104 - _GraphItem i1;
157.105 - _GraphItem i2 = i1;
157.106 - _GraphItem i3 = INVALID;
157.107 -
157.108 - i1 = i2 = i3;
157.109 -
157.110 - bool b;
157.111 - // b = (ia == ib) && (ia != ib) && (ia < ib);
157.112 - b = (ia == ib) && (ia != ib);
157.113 - b = (ia == INVALID) && (ib != INVALID);
157.114 - // b = (ia < ib);
157.115 - }
157.116 -
157.117 - const _GraphItem &ia;
157.118 - const _GraphItem &ib;
157.119 - };
157.120 - };
157.121 -
157.122 - /// A type describing the concept of graph node
157.123 -
157.124 - /// This is an instantiation of \ref GraphItem which can be used as a
157.125 - /// Node subtype in graph skeleton definitions
157.126 - typedef GraphItem<'n'> GraphNode;
157.127 -
157.128 - /// A type describing the concept of graph edge
157.129 -
157.130 - /// This is an instantiation of \ref GraphItem which can be used as a
157.131 - /// Edge subtype in graph skeleton definitions
157.132 - typedef GraphItem<'e'> GraphEdge;
157.133 -
157.134 -
157.135 - /**************** Basic features of graphs ****************/
157.136 -
157.137 - /// An empty base graph class.
157.138 -
157.139 - /// This class provides the minimal set of features needed for a graph
157.140 - /// structure. All graph concepts have to be conform to this base
157.141 - /// graph.
157.142 - ///
157.143 - /// \bug This is not true. The minimal graph concept is the
157.144 - /// BaseIterableGraphComponent.
157.145 -
157.146 - class BaseGraphComponent {
157.147 - public:
157.148 -
157.149 - typedef BaseGraphComponent Graph;
157.150 -
157.151 - /// Node class of the graph.
157.152 -
157.153 - /// This class represents the Nodes of the graph.
157.154 - ///
157.155 - typedef GraphItem<'n'> Node;
157.156 -
157.157 - /// Edge class of the graph.
157.158 -
157.159 - /// This class represents the Edges of the graph.
157.160 - ///
157.161 - typedef GraphItem<'e'> Edge;
157.162 -
157.163 - ///Gives back the target node of an edge.
157.164 -
157.165 - ///Gives back the target node of an edge.
157.166 - ///
157.167 - Node target(const Edge&) const { return INVALID;}
157.168 -
157.169 - ///Gives back the source node of an edge.
157.170 -
157.171 - ///Gives back the source node of an edge.
157.172 - ///
157.173 - Node source(const Edge&) const { return INVALID;}
157.174 -
157.175 -
157.176 - template <typename _Graph>
157.177 - struct Constraints {
157.178 - typedef typename _Graph::Node Node;
157.179 - typedef typename _Graph::Edge Edge;
157.180 -
157.181 - void constraints() {
157.182 - checkConcept<GraphItem<'n'>, Node>();
157.183 - checkConcept<GraphItem<'e'>, Edge>();
157.184 - {
157.185 - Node n;
157.186 - Edge e;
157.187 - n = graph.source(e);
157.188 - n = graph.target(e);
157.189 - }
157.190 - }
157.191 -
157.192 - const _Graph& graph;
157.193 - };
157.194 - };
157.195 -
157.196 - /// An empty iterable base graph class.
157.197 -
157.198 - /// This class provides beside the core graph features
157.199 - /// core iterable interface for the graph structure.
157.200 - /// Most of the base graphs should be conform to this concept.
157.201 -
157.202 - class BaseIterableGraphComponent : virtual public BaseGraphComponent {
157.203 - public:
157.204 -
157.205 - typedef BaseGraphComponent::Node Node;
157.206 - typedef BaseGraphComponent::Edge Edge;
157.207 -
157.208 - /// Gives back the first Node in the iterating order.
157.209 -
157.210 - /// Gives back the first Node in the iterating order.
157.211 - ///
157.212 - void first(Node&) const {}
157.213 -
157.214 - /// Gives back the next Node in the iterating order.
157.215 -
157.216 - /// Gives back the next Node in the iterating order.
157.217 - ///
157.218 - void next(Node&) const {}
157.219 -
157.220 - /// Gives back the first Edge in the iterating order.
157.221 -
157.222 - /// Gives back the first Edge in the iterating order.
157.223 - ///
157.224 - void first(Edge&) const {}
157.225 - /// Gives back the next Edge in the iterating order.
157.226 -
157.227 - /// Gives back the next Edge in the iterating order.
157.228 - ///
157.229 - void next(Edge&) const {}
157.230 -
157.231 -
157.232 - /// Gives back the first of the Edges point to the given Node.
157.233 -
157.234 - /// Gives back the first of the Edges point to the given Node.
157.235 - ///
157.236 - void firstIn(Edge&, const Node&) const {}
157.237 -
157.238 - /// Gives back the next of the Edges points to the given Node.
157.239 -
157.240 -
157.241 - /// Gives back the next of the Edges points to the given Node.
157.242 - ///
157.243 - void nextIn(Edge&) const {}
157.244 -
157.245 - /// Gives back the first of the Edges start from the given Node.
157.246 -
157.247 - /// Gives back the first of the Edges start from the given Node.
157.248 - ///
157.249 - void firstOut(Edge&, const Node&) const {}
157.250 -
157.251 - /// Gives back the next of the Edges start from the given Node.
157.252 -
157.253 - /// Gives back the next of the Edges start from the given Node.
157.254 - ///
157.255 - void nextOut(Edge&) const {}
157.256 -
157.257 -
157.258 - template <typename _Graph>
157.259 - struct Constraints {
157.260 -
157.261 - void constraints() {
157.262 - checkConcept< BaseGraphComponent, _Graph >();
157.263 - typename _Graph::Node node;
157.264 - typename _Graph::Edge edge;
157.265 - {
157.266 - graph.first(node);
157.267 - graph.next(node);
157.268 - }
157.269 - {
157.270 - graph.first(edge);
157.271 - graph.next(edge);
157.272 - }
157.273 - {
157.274 - graph.firstIn(edge, node);
157.275 - graph.nextIn(edge);
157.276 - }
157.277 - {
157.278 - graph.firstOut(edge, node);
157.279 - graph.nextOut(edge);
157.280 - }
157.281 - }
157.282 -
157.283 - const _Graph& graph;
157.284 - };
157.285 - };
157.286 -
157.287 - /// An empty idable base graph class.
157.288 -
157.289 - /// This class provides beside the core graph features
157.290 - /// core id functions for the graph structure.
157.291 - /// The most of the base graphs should be conform to this concept.
157.292 - /// The id's are unique and immutable.
157.293 - class IDableGraphComponent : virtual public BaseGraphComponent {
157.294 - public:
157.295 -
157.296 - typedef BaseGraphComponent::Node Node;
157.297 - typedef BaseGraphComponent::Edge Edge;
157.298 -
157.299 - /// Gives back an unique integer id for the Node.
157.300 -
157.301 - /// Gives back an unique integer id for the Node.
157.302 - ///
157.303 - int id(const Node&) const { return -1;}
157.304 -
157.305 - /// \brief Gives back the node by the unique id.
157.306 - ///
157.307 - /// Gives back the node by the unique id.
157.308 - /// If the graph does not contain node with the given id
157.309 - /// then the result of the function is undetermined.
157.310 - Node fromId(int , Node) const { return INVALID;}
157.311 -
157.312 - /// \brief Gives back an unique integer id for the Edge.
157.313 - ///
157.314 - /// Gives back an unique integer id for the Edge.
157.315 - ///
157.316 - int id(const Edge&) const { return -1;}
157.317 -
157.318 - /// \brief Gives back the edge by the unique id.
157.319 - ///
157.320 - /// Gives back the edge by the unique id.
157.321 - /// If the graph does not contain edge with the given id
157.322 - /// then the result of the function is undetermined.
157.323 - Edge fromId(int, Edge) const { return INVALID;}
157.324 -
157.325 - template <typename _Graph>
157.326 - struct Constraints {
157.327 -
157.328 - void constraints() {
157.329 - checkConcept< BaseGraphComponent, _Graph >();
157.330 - typename _Graph::Node node;
157.331 - int nid = graph.id(node);
157.332 - nid = graph.id(node);
157.333 - node = graph.fromId(nid, Node());
157.334 - typename _Graph::Edge edge;
157.335 - int eid = graph.id(edge);
157.336 - eid = graph.id(edge);
157.337 - edge = graph.fromId(eid, Edge());
157.338 - }
157.339 -
157.340 - const _Graph& graph;
157.341 - };
157.342 - };
157.343 -
157.344 -
157.345 - /// An empty max-idable base graph class.
157.346 -
157.347 - /// This class provides beside the core graph features
157.348 - /// core max id functions for the graph structure.
157.349 - /// The most of the base graphs should be conform to this concept.
157.350 - /// The id's are unique and immutable.
157.351 - class MaxIDableGraphComponent : virtual public BaseGraphComponent {
157.352 - public:
157.353 -
157.354 - /// Gives back an integer greater or equal to the maximum Node id.
157.355 -
157.356 - /// Gives back an integer greater or equal to the maximum Node id.
157.357 - ///
157.358 - int maxId(Node = INVALID) const { return -1;}
157.359 -
157.360 - /// Gives back an integer greater or equal to the maximum Edge id.
157.361 -
157.362 - /// Gives back an integer greater or equal to the maximum Edge id.
157.363 - ///
157.364 - int maxId(Edge = INVALID) const { return -1;}
157.365 -
157.366 - template <typename _Graph>
157.367 - struct Constraints {
157.368 -
157.369 - void constraints() {
157.370 - checkConcept<BaseGraphComponent, _Graph>();
157.371 - int nid = graph.maxId(typename _Graph::Node());
157.372 - ignore_unused_variable_warning(nid);
157.373 - int eid = graph.maxId(typename _Graph::Edge());
157.374 - ignore_unused_variable_warning(eid);
157.375 - }
157.376 -
157.377 - const _Graph& graph;
157.378 - };
157.379 - };
157.380 -
157.381 - /// An empty extendable base graph class.
157.382 -
157.383 - /// This class provides beside the core graph features
157.384 - /// core graph extend interface for the graph structure.
157.385 - /// The most of the base graphs should be conform to this concept.
157.386 - class BaseExtendableGraphComponent : virtual public BaseGraphComponent {
157.387 - public:
157.388 -
157.389 - typedef BaseGraphComponent::Node Node;
157.390 - typedef BaseGraphComponent::Edge Edge;
157.391 -
157.392 - /// Adds a new Node to the graph.
157.393 -
157.394 - /// Adds a new Node to the graph.
157.395 - ///
157.396 - Node addNode() {
157.397 - return INVALID;
157.398 - }
157.399 -
157.400 - /// Adds a new Edge connects the two Nodes to the graph.
157.401 -
157.402 - /// Adds a new Edge connects the two Nodes to the graph.
157.403 - ///
157.404 - Edge addEdge(const Node&, const Node&) {
157.405 - return INVALID;
157.406 - }
157.407 -
157.408 - template <typename _Graph>
157.409 - struct Constraints {
157.410 - void constraints() {
157.411 - checkConcept<BaseGraphComponent, _Graph >();
157.412 - typename _Graph::Node node_a, node_b;
157.413 - node_a = graph.addNode();
157.414 - typename _Graph::Edge edge;
157.415 - edge = graph.addEdge(node_a, node_b);
157.416 - }
157.417 -
157.418 - _Graph& graph;
157.419 - };
157.420 - };
157.421 -
157.422 - /// An empty erasable base graph class.
157.423 -
157.424 - /// This class provides beside the core graph features
157.425 - /// core erase functions for the graph structure.
157.426 - /// The most of the base graphs should be conform to this concept.
157.427 - class BaseErasableGraphComponent : virtual public BaseGraphComponent {
157.428 - public:
157.429 -
157.430 - typedef BaseGraphComponent::Node Node;
157.431 - typedef BaseGraphComponent::Edge Edge;
157.432 -
157.433 - /// Erase a Node from the graph.
157.434 -
157.435 - /// Erase a Node from the graph. This function should not
157.436 - /// erase edges connecting to the Node.
157.437 - void erase(const Node&) {}
157.438 -
157.439 - /// Erase an Edge from the graph.
157.440 -
157.441 - /// Erase an Edge from the graph.
157.442 - ///
157.443 - void erase(const Edge&) {}
157.444 -
157.445 - template <typename _Graph>
157.446 - struct Constraints {
157.447 - void constraints() {
157.448 - checkConcept<BaseGraphComponent, _Graph>();
157.449 - typename _Graph::Node node;
157.450 - graph.erase(node);
157.451 - typename _Graph::Edge edge;
157.452 - graph.erase(edge);
157.453 - }
157.454 -
157.455 - _Graph& graph;
157.456 - };
157.457 - };
157.458 -
157.459 - /// An empty clearable base graph class.
157.460 -
157.461 - /// This class provides beside the core graph features
157.462 - /// core clear functions for the graph structure.
157.463 - /// The most of the base graphs should be conform to this concept.
157.464 - class ClearableGraphComponent : virtual public BaseGraphComponent {
157.465 - public:
157.466 -
157.467 - /// Erase all the Nodes and Edges from the graph.
157.468 -
157.469 - /// Erase all the Nodes and Edges from the graph.
157.470 - ///
157.471 - void clear() {}
157.472 -
157.473 - template <typename _Graph>
157.474 - struct Constraints {
157.475 - void constraints() {
157.476 - checkConcept<BaseGraphComponent, _Graph>();
157.477 - graph.clear();
157.478 - }
157.479 -
157.480 - _Graph graph;
157.481 - };
157.482 - };
157.483 -
157.484 -
157.485 - /// Skeleton class for graph NodeIt and EdgeIt
157.486 -
157.487 - /// Skeleton class for graph NodeIt and EdgeIt.
157.488 - ///
157.489 - template <typename _Graph, typename _Item>
157.490 - class GraphIterator : public _Item {
157.491 - public:
157.492 - /// \todo Don't we need the Item type as typedef?
157.493 -
157.494 - /// Default constructor.
157.495 -
157.496 - /// @warning The default constructor sets the iterator
157.497 - /// to an undefined value.
157.498 - GraphIterator() {}
157.499 - /// Copy constructor.
157.500 -
157.501 - /// Copy constructor.
157.502 - ///
157.503 - GraphIterator(GraphIterator const&) {}
157.504 - /// Sets the iterator to the first item.
157.505 -
157.506 - /// Sets the iterator to the first item of \c the graph.
157.507 - ///
157.508 - explicit GraphIterator(const _Graph&) {}
157.509 - /// Invalid constructor \& conversion.
157.510 -
157.511 - /// This constructor initializes the item to be invalid.
157.512 - /// \sa Invalid for more details.
157.513 - GraphIterator(Invalid) {}
157.514 - /// Assign operator for items.
157.515 -
157.516 - /// The items are assignable.
157.517 - ///
157.518 - GraphIterator& operator=(GraphIterator const&) { return *this; }
157.519 - /// Next item.
157.520 -
157.521 - /// Assign the iterator to the next item.
157.522 - ///
157.523 - GraphIterator& operator++() { return *this; }
157.524 - // Node operator*() const { return INVALID; }
157.525 - /// Equality operator
157.526 -
157.527 - /// Two iterators are equal if and only if they point to the
157.528 - /// same object or both are invalid.
157.529 - bool operator==(const GraphIterator&) const { return true;}
157.530 - /// Inequality operator
157.531 -
157.532 - /// \sa operator==(Node n)
157.533 - ///
157.534 - bool operator!=(const GraphIterator&) const { return true;}
157.535 -
157.536 - template<typename _GraphIterator>
157.537 - struct Constraints {
157.538 - void constraints() {
157.539 - // checkConcept< Item, _GraphIterator >();
157.540 - _GraphIterator it1(g);
157.541 -
157.542 - /// \todo Do we need NodeIt(Node) kind of constructor?
157.543 - // _GraphIterator it2(bj);
157.544 - _GraphIterator it2;
157.545 -
157.546 - it2 = ++it1;
157.547 - ++it2 = it1;
157.548 - ++(++it1);
157.549 - /// \bug This should be: is_base_and_derived<BaseItem, _GraphIterator>
157.550 - _Item bi = it1;
157.551 - bi = it2;
157.552 - }
157.553 - _Graph& g;
157.554 - };
157.555 - };
157.556 -
157.557 - /// Skeleton class for graph InEdgeIt and OutEdgeIt
157.558 -
157.559 - /// \note Because InEdgeIt and OutEdgeIt may not inherit from the same
157.560 - /// base class, the _selector is a additional template parameter. For
157.561 - /// InEdgeIt you should instantiate it with character 'i' and for
157.562 - /// OutEdgeIt with 'o'.
157.563 - /// \todo Is this a good name for this concept?
157.564 - template <typename Graph,
157.565 - typename Edge = typename Graph::Edge,
157.566 - char _selector = '0'>
157.567 - class GraphIncIterator : public Edge {
157.568 - public:
157.569 - /// Default constructor.
157.570 -
157.571 - /// @warning The default constructor sets the iterator
157.572 - /// to an undefined value.
157.573 - GraphIncIterator() {}
157.574 - /// Copy constructor.
157.575 -
157.576 - /// Copy constructor.
157.577 - ///
157.578 - GraphIncIterator(GraphIncIterator const& gi) :Edge(gi) {}
157.579 - /// Sets the iterator to the first edge incoming into or outgoing
157.580 - /// from the node.
157.581 -
157.582 - /// Sets the iterator to the first edge incoming into or outgoing
157.583 - /// from the node.
157.584 - ///
157.585 - explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {}
157.586 - /// Invalid constructor \& conversion.
157.587 -
157.588 - /// This constructor initializes the item to be invalid.
157.589 - /// \sa Invalid for more details.
157.590 - GraphIncIterator(Invalid) {}
157.591 - /// Assign operator for nodes.
157.592 -
157.593 - /// The nodes are assignable.
157.594 - ///
157.595 - GraphIncIterator& operator=(GraphIncIterator const&) { return *this; }
157.596 - /// Next edge.
157.597 -
157.598 - /// Assign the iterator to the next node.
157.599 - ///
157.600 - GraphIncIterator& operator++() { return *this; }
157.601 -
157.602 - // Node operator*() const { return INVALID; }
157.603 -
157.604 - /// Equality operator
157.605 -
157.606 - /// Two iterators are equal if and only if they point to the
157.607 - /// same object or both are invalid.
157.608 - bool operator==(const GraphIncIterator&) const { return true;}
157.609 -
157.610 - /// Inequality operator
157.611 -
157.612 - /// \sa operator==(Node n)
157.613 - ///
157.614 - bool operator!=(const GraphIncIterator&) const { return true;}
157.615 -
157.616 - template <typename _GraphIncIterator>
157.617 - struct Constraints {
157.618 - typedef typename Graph::Node Node;
157.619 - void constraints() {
157.620 - checkConcept<GraphItem<'e'>, _GraphIncIterator>();
157.621 - _GraphIncIterator it1(graph, node);
157.622 - /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
157.623 - // _GraphIncIterator it2(edge);
157.624 - _GraphIncIterator it2;
157.625 -
157.626 - it2 = ++it1;
157.627 - ++it2 = it1;
157.628 - ++(++it1);
157.629 - Edge e = it1;
157.630 - e = it2;
157.631 -
157.632 - const_constraits();
157.633 - }
157.634 -
157.635 - void const_constraits() {
157.636 - Node n = graph.baseNode(it);
157.637 - n = graph.runningNode(it);
157.638 - }
157.639 -
157.640 - Edge edge;
157.641 - Node node;
157.642 - Graph graph;
157.643 - _GraphIncIterator it;
157.644 - };
157.645 - };
157.646 -
157.647 -
157.648 - /// An empty iterable base graph class.
157.649 -
157.650 - /// This class provides beside the core graph features
157.651 - /// iterator based iterable interface for the graph structure.
157.652 - /// This concept is part of the StaticGraphConcept.
157.653 - class IterableGraphComponent : virtual public BaseGraphComponent {
157.654 -
157.655 - public:
157.656 -
157.657 - typedef IterableGraphComponent Graph;
157.658 -
157.659 - typedef BaseGraphComponent::Node Node;
157.660 - typedef BaseGraphComponent::Edge Edge;
157.661 -
157.662 - /// This iterator goes through each node.
157.663 -
157.664 - /// This iterator goes through each node.
157.665 - ///
157.666 - typedef GraphIterator<Graph, Node> NodeIt;
157.667 - /// This iterator goes through each node.
157.668 -
157.669 - /// This iterator goes through each node.
157.670 - ///
157.671 - typedef GraphIterator<Graph, Edge> EdgeIt;
157.672 - /// This iterator goes trough the incoming edges of a node.
157.673 -
157.674 - /// This iterator goes trough the \e inccoming edges of a certain node
157.675 - /// of a graph.
157.676 - typedef GraphIncIterator<Graph, Edge, 'i'> InEdgeIt;
157.677 - /// This iterator goes trough the outgoing edges of a node.
157.678 -
157.679 - /// This iterator goes trough the \e outgoing edges of a certain node
157.680 - /// of a graph.
157.681 - typedef GraphIncIterator<Graph, Edge, 'o'> OutEdgeIt;
157.682 - };
157.683 -
157.684 - template <typename _Graph>
157.685 - struct Constraints {
157.686 - void constraints() {
157.687 - checkConcept< BaseGraphComponent, _Graph>();
157.688 -
157.689 - checkConcept<GraphIterator<_Graph, typename _Graph::Edge>,
157.690 - typename _Graph::EdgeIt >();
157.691 - checkConcept<GraphIterator<_Graph, typename _Graph::Node>,
157.692 - typename _Graph::NodeIt >();
157.693 - checkConcept<GraphIncIterator<_Graph>, typename _Graph::InEdgeIt >();
157.694 - checkConcept<GraphIncIterator<_Graph>, typename _Graph::OutEdgeIt >();
157.695 - }
157.696 - };
157.697 -
157.698 - /// An empty alteration notifier base graph class.
157.699 -
157.700 - /// This class provides beside the core graph features
157.701 - /// alteration notifier interface for the graph structure.
157.702 - /// This is an observer-notifier pattern. More Obsevers can
157.703 - /// be registered into the notifier and whenever an alteration
157.704 - /// occured in the graph all the observers will notified about it.
157.705 - class AlterableGraphComponent : virtual public BaseGraphComponent {
157.706 - public:
157.707 -
157.708 - /// The edge observer registry.
157.709 - typedef AlterationNotifier<Edge> EdgeNotifier;
157.710 - /// The node observer registry.
157.711 - typedef AlterationNotifier<Node> NodeNotifier;
157.712 -
157.713 - /// \brief Gives back the edge alteration notifier.
157.714 - ///
157.715 - /// Gives back the edge alteration notifier.
157.716 - EdgeNotifier getNotifier(Edge) const {
157.717 - return EdgeNotifier();
157.718 - }
157.719 -
157.720 - /// \brief Gives back the node alteration notifier.
157.721 - ///
157.722 - /// Gives back the node alteration notifier.
157.723 - NodeNotifier getNotifier(Node) const {
157.724 - return NodeNotifier();
157.725 - }
157.726 -
157.727 - };
157.728 -
157.729 -
157.730 - /// Class describing the concept of graph maps
157.731 -
157.732 - /// This class describes the common interface of the graph maps
157.733 - /// (NodeMap, EdgeMap), that is \ref maps-pages "maps" which can be used to
157.734 - /// associate data to graph descriptors (nodes or edges).
157.735 - template <typename Graph, typename Item, typename _Value>
157.736 - class GraphMap : public ReadWriteMap<Item, _Value> {
157.737 - protected:
157.738 - GraphMap() {}
157.739 - public:
157.740 - /// \brief Construct a new map.
157.741 - ///
157.742 - /// Construct a new map for the graph.
157.743 - explicit GraphMap(const Graph&) {}
157.744 - /// \brief Construct a new map with default value.
157.745 - ///
157.746 - /// Construct a new map for the graph and initalise the values.
157.747 - GraphMap(const Graph&, const _Value&) {}
157.748 - /// \brief Copy constructor.
157.749 - ///
157.750 - /// Copy Constructor.
157.751 - GraphMap(const GraphMap& gm) :ReadWriteMap<Item, _Value>(gm) {}
157.752 -
157.753 - /// \brief Assign operator.
157.754 - ///
157.755 - /// Assign operator.
157.756 - GraphMap& operator=(const GraphMap&) { return *this;}
157.757 -
157.758 - template<typename _Map>
157.759 - struct Constraints {
157.760 - void constraints() {
157.761 - checkConcept<ReadWriteMap<Item, _Value>, _Map >();
157.762 - // Construction with a graph parameter
157.763 - _Map a(g);
157.764 - // Constructor with a graph and a default value parameter
157.765 - _Map a2(g,t);
157.766 - // Copy constructor. Do we need it?
157.767 - _Map b=c;
157.768 - // Copy operator. Do we need it?
157.769 - a=b;
157.770 -
157.771 - ignore_unused_variable_warning(a2);
157.772 - }
157.773 -
157.774 - const _Map &c;
157.775 - const Graph &g;
157.776 - const typename GraphMap::Value &t;
157.777 - };
157.778 -
157.779 - };
157.780 -
157.781 - /// An empty mappable base graph class.
157.782 -
157.783 - /// This class provides beside the core graph features
157.784 - /// map interface for the graph structure.
157.785 - /// This concept is part of the StaticGraphConcept.
157.786 - class MappableGraphComponent : virtual public BaseGraphComponent {
157.787 - public:
157.788 -
157.789 - typedef MappableGraphComponent Graph;
157.790 -
157.791 - typedef BaseGraphComponent::Node Node;
157.792 - typedef BaseGraphComponent::Edge Edge;
157.793 -
157.794 - /// ReadWrite map of the nodes.
157.795 -
157.796 - /// ReadWrite map of the nodes.
157.797 - ///
157.798 - template <typename _Value>
157.799 - class NodeMap : public GraphMap<Graph, Node, _Value> {
157.800 - private:
157.801 - NodeMap();
157.802 - public:
157.803 - /// \brief Construct a new map.
157.804 - ///
157.805 - /// Construct a new map for the graph.
157.806 - /// \todo call the right parent class constructor
157.807 - explicit NodeMap(const Graph&) {}
157.808 - /// \brief Construct a new map with default value.
157.809 - ///
157.810 - /// Construct a new map for the graph and initalise the values.
157.811 - NodeMap(const Graph&, const _Value&) {}
157.812 - /// \brief Copy constructor.
157.813 - ///
157.814 - /// Copy Constructor.
157.815 - NodeMap(const NodeMap& nm) : GraphMap<Graph, Node, _Value>(nm) {}
157.816 -
157.817 - /// \brief Assign operator.
157.818 - ///
157.819 - /// Assign operator.
157.820 - NodeMap& operator=(const NodeMap&) { return *this;}
157.821 -
157.822 - };
157.823 -
157.824 - /// ReadWrite map of the edges.
157.825 -
157.826 - /// ReadWrite map of the edges.
157.827 - ///
157.828 - template <typename _Value>
157.829 - class EdgeMap : public GraphMap<Graph, Edge, _Value> {
157.830 - private:
157.831 - EdgeMap();
157.832 - public:
157.833 - /// \brief Construct a new map.
157.834 - ///
157.835 - /// Construct a new map for the graph.
157.836 - /// \todo call the right parent class constructor
157.837 - explicit EdgeMap(const Graph&) {}
157.838 - /// \brief Construct a new map with default value.
157.839 - ///
157.840 - /// Construct a new map for the graph and initalise the values.
157.841 - EdgeMap(const Graph&, const _Value&) {}
157.842 - /// \brief Copy constructor.
157.843 - ///
157.844 - /// Copy Constructor.
157.845 - EdgeMap(const EdgeMap& em) :GraphMap<Graph, Edge, _Value>(em) {}
157.846 -
157.847 - /// \brief Assign operator.
157.848 - ///
157.849 - /// Assign operator.
157.850 - EdgeMap& operator=(const EdgeMap&) { return *this;}
157.851 -
157.852 - };
157.853 -
157.854 - template <typename _Graph>
157.855 - struct Constraints {
157.856 -
157.857 - struct Type {
157.858 - int value;
157.859 - Type() : value(0) {}
157.860 - Type(int _v) : value(_v) {}
157.861 - };
157.862 -
157.863 - void constraints() {
157.864 - checkConcept<BaseGraphComponent, _Graph>();
157.865 - { // int map test
157.866 - typedef typename _Graph::template NodeMap<int> IntNodeMap;
157.867 - checkConcept<GraphMap<_Graph, typename _Graph::Node, int>,
157.868 - IntNodeMap >();
157.869 - } { // bool map test
157.870 - typedef typename _Graph::template NodeMap<bool> BoolNodeMap;
157.871 - checkConcept<GraphMap<_Graph, typename _Graph::Node, bool>,
157.872 - BoolNodeMap >();
157.873 - } { // Type map test
157.874 - typedef typename _Graph::template NodeMap<Type> TypeNodeMap;
157.875 - checkConcept<GraphMap<_Graph, typename _Graph::Node, Type>,
157.876 - TypeNodeMap >();
157.877 - }
157.878 -
157.879 - { // int map test
157.880 - typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
157.881 - checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
157.882 - IntEdgeMap >();
157.883 - } { // bool map test
157.884 - typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
157.885 - checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
157.886 - BoolEdgeMap >();
157.887 - } { // Type map test
157.888 - typedef typename _Graph::template EdgeMap<Type> TypeEdgeMap;
157.889 - checkConcept<GraphMap<_Graph, typename _Graph::Edge, Type>,
157.890 - TypeEdgeMap >();
157.891 - }
157.892 - }
157.893 -
157.894 - _Graph& graph;
157.895 - };
157.896 - };
157.897 -
157.898 - /// \brief An empty extendable extended graph class.
157.899 - ///
157.900 - /// This class provides beside the core graph features
157.901 - /// item addition interface for the graph structure.
157.902 - /// The difference between this class and the
157.903 - /// \c BaseExtendableGraphComponent is that it should
157.904 - /// notify the item alteration observers.
157.905 - class ExtendableGraphComponent : virtual public BaseGraphComponent {
157.906 - public:
157.907 -
157.908 - typedef ExtendableGraphComponent Graph;
157.909 -
157.910 - typedef BaseGraphComponent::Node Node;
157.911 - typedef BaseGraphComponent::Edge Edge;
157.912 -
157.913 - /// \brief Add a node to the graph.
157.914 - ///
157.915 - /// Add a node to the graph and notify the observers.
157.916 - Node addNode() {
157.917 - return INVALID;
157.918 - }
157.919 -
157.920 - /// \brief Add an edge to the graph.
157.921 - ///
157.922 - /// Add an edge to the graph and notify the observers.
157.923 - Edge addEdge(const Node&, const Node&) {
157.924 - return INVALID;
157.925 - }
157.926 -
157.927 - template <typename _Graph>
157.928 - struct Constraints {
157.929 - void constraints() {
157.930 - checkConcept<BaseGraphComponent, _Graph >();
157.931 - typename _Graph::Node node_a, node_b;
157.932 - node_a = graph.addNode();
157.933 - typename _Graph::Edge edge;
157.934 - edge = graph.addEdge(node_a, node_b);
157.935 - }
157.936 - _Graph& graph;
157.937 - };
157.938 - };
157.939 -
157.940 - /// \brief An empty erasable extended graph class.
157.941 - ///
157.942 - /// This class provides beside the core graph features
157.943 - /// item erase interface for the graph structure.
157.944 - /// The difference between this class and the
157.945 - /// \c BaseErasableGraphComponent is that it should
157.946 - /// notify the item alteration observers.
157.947 - class ErasableGraphComponent : virtual public BaseGraphComponent {
157.948 - public:
157.949 -
157.950 - typedef ErasableGraphComponent Graph;
157.951 -
157.952 - typedef BaseGraphComponent::Node Node;
157.953 - typedef BaseGraphComponent::Edge Edge;
157.954 -
157.955 - /// \brief Erase the Node and notify the node alteration observers.
157.956 - ///
157.957 - /// Erase the Node and notify the node alteration observers.
157.958 - void erase(const Node&) {}
157.959 -
157.960 - /// \brief Erase the Edge and notify the edge alteration observers.
157.961 - ///
157.962 - /// Erase the Edge and notify the edge alteration observers.
157.963 - void erase(const Edge&) {}
157.964 -
157.965 - template <typename _Graph>
157.966 - struct Constraints {
157.967 - void constraints() {
157.968 - checkConcept<BaseGraphComponent, _Graph >();
157.969 - typename _Graph::Node node;
157.970 - graph.erase(node);
157.971 - typename _Graph::Edge edge;
157.972 - graph.erase(edge);
157.973 - }
157.974 -
157.975 - _Graph& graph;
157.976 - };
157.977 - };
157.978 -
157.979 - /// @}
157.980 -
157.981 - }
157.982 -
157.983 -}
157.984 -
157.985 -#endif
158.1 --- a/src/lemon/concept/heap.h Sat May 21 21:04:57 2005 +0000
158.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
158.3 @@ -1,201 +0,0 @@
158.4 -/* -*- C++ -*-
158.5 - * src/lemon/concept/heap.h - Part of LEMON, a generic C++ optimization library
158.6 - *
158.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
158.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
158.9 - *
158.10 - * Permission to use, modify and distribute this software is granted
158.11 - * provided that this copyright notice appears in all copies. For
158.12 - * precise terms see the accompanying LICENSE file.
158.13 - *
158.14 - * This software is provided "AS IS" with no warranty of any kind,
158.15 - * express or implied, and with no claim as to its suitability for any
158.16 - * purpose.
158.17 - *
158.18 - */
158.19 -
158.20 -///\ingroup concept
158.21 -///\file
158.22 -///\brief Classes for representing heaps.
158.23 -///
158.24 -
158.25 -#ifndef LEMON_CONCEPT_HEAP_H
158.26 -#define LEMON_CONCEPT_HEAP_H
158.27 -
158.28 -#include <lemon/invalid.h>
158.29 -
158.30 -namespace lemon {
158.31 - namespace concept {
158.32 - /// \addtogroup concept
158.33 - /// @{
158.34 -
158.35 -
158.36 - /// \brief A concept structure describes the main interface of heaps.
158.37 - ///
158.38 - /// A concept structure describes the main interface of heaps.
158.39 - ///
158.40 - template <typename Item, typename Prio, typename ItemIntMap>
158.41 - class Heap {
158.42 - public:
158.43 -
158.44 -
158.45 - /// \brief Type to represent the items states.
158.46 - ///
158.47 - /// Each Item element have a state associated to it. It may be "in heap",
158.48 - /// "pre heap" or "post heap". The later two are indifferent from the
158.49 - /// heap's point of view, but may be useful to the user.
158.50 - ///
158.51 - /// The ItemIntMap _should_ be initialized in such way, that it maps
158.52 - /// PRE_HEAP (-1) to any element to be put in the heap...
158.53 - enum state_enum {
158.54 - IN_HEAP = 0,
158.55 - PRE_HEAP = -1,
158.56 - POST_HEAP = -2
158.57 - };
158.58 -
158.59 - /// \brief The constructor.
158.60 - ///
158.61 - /// The constructor.
158.62 - /// \param _iim should be given to the constructor, since it is used
158.63 - /// internally to handle the cross references. The value of the map
158.64 - /// should be PRE_HEAP (-1) for each element.
158.65 - explicit Heap(ItemIntMap &_iim) {}
158.66 -
158.67 - /// The number of items stored in the heap.
158.68 - ///
158.69 - /// \brief Returns the number of items stored in the heap.
158.70 - int size() const { return 0; }
158.71 - /// \brief Checks if the heap stores no items.
158.72 - ///
158.73 - /// Returns \c true if and only if the heap stores no items.
158.74 - bool empty() const { return false; }
158.75 -
158.76 - /// \brief Insert an item into the heap with the given heap.
158.77 - ///
158.78 - /// Adds \c i to the heap with priority \c p.
158.79 - /// \param i The item to insert.
158.80 - /// \param p The priority of the item.
158.81 - void push(const Item &i, const Prio &p) {}
158.82 -
158.83 - /// \brief Returns the item with minimum priority.
158.84 - ///
158.85 - /// This method returns the item with minimum priority.
158.86 - /// \pre The heap must be nonempty.
158.87 - Item top() const {}
158.88 -
158.89 - /// \brief Returns the minimum priority.
158.90 - ///
158.91 - /// It returns the minimum priority.
158.92 - /// \pre The heap must be nonempty.
158.93 - Prio prio() const {}
158.94 -
158.95 - /// \brief Deletes the item with minimum priority.
158.96 - ///
158.97 - /// This method deletes the item with minimum priority.
158.98 - /// \pre The heap must be non-empty.
158.99 - void pop() {}
158.100 -
158.101 - /// \brief Deletes \c i from the heap.
158.102 - ///
158.103 - /// This method deletes item \c i from the heap, if \c i was
158.104 - /// already stored in the heap.
158.105 - /// \param i The item to erase.
158.106 - void erase(const Item &i) {}
158.107 -
158.108 - /// \brief Returns the priority of \c i.
158.109 - ///
158.110 - /// This function returns the priority of item \c i.
158.111 - /// \pre \c i must be in the heap.
158.112 - /// \param i The item.
158.113 - Prio operator[](const Item &i) const {}
158.114 -
158.115 - /// \brief \c i gets to the heap with priority \c p independently
158.116 - /// if \c i was already there.
158.117 - ///
158.118 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
158.119 - /// in the heap and sets the priority of \c i to \c p otherwise.
158.120 - /// It may throw an \e UnderFlowPriorityException.
158.121 - /// \param i The item.
158.122 - /// \param p The priority.
158.123 - void set(const Item &i, const Prio &p) {}
158.124 -
158.125 - /// \brief Decreases the priority of \c i to \c p.
158.126 - ///
158.127 - /// This method decreases the priority of item \c i to \c p.
158.128 - /// \pre \c i must be stored in the heap with priority at least \c p.
158.129 - /// \param i The item.
158.130 - /// \param p The priority.
158.131 - void decrease(const Item &i, const Prio &p) {}
158.132 -
158.133 - /// \brief Increases the priority of \c i to \c p.
158.134 - ///
158.135 - /// This method sets the priority of item \c i to \c p.
158.136 - /// \pre \c i must be stored in the heap with priority at most \c
158.137 - /// p relative to \c Compare.
158.138 - /// \param i The item.
158.139 - /// \param p The priority.
158.140 - void increase(const Item &i, const Prio &p) {}
158.141 -
158.142 - /// \brief Returns if \c item is in, has already been in, or has
158.143 - /// never been in the heap.
158.144 - ///
158.145 - /// This method returns PRE_HEAP if \c item has never been in the
158.146 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
158.147 - /// otherwise. In the latter case it is possible that \c item will
158.148 - /// get back to the heap again.
158.149 - /// \param i The item.
158.150 - state_enum state(const Item &i) const {}
158.151 -
158.152 -
158.153 - template <typename _Heap>
158.154 - struct Constraints {
158.155 - public:
158.156 -
158.157 - void constraints() {
158.158 - Item item;
158.159 - Prio prio;
158.160 -
158.161 - ignore_unused_variable_warning(item);
158.162 - ignore_unused_variable_warning(prio);
158.163 -
158.164 - typedef typename _Heap::state_enum state_enum;
158.165 - state_enum state;
158.166 -
158.167 - ignore_unused_variable_warning(state);
158.168 -
158.169 - _Heap heap1 = _Heap(map);
158.170 -
158.171 - ignore_unused_variable_warning(heap1);
158.172 -
158.173 - heap.push(item, prio);
158.174 -
158.175 - prio = heap.prio();
158.176 - item = heap.top();
158.177 -
158.178 - heap.pop();
158.179 -
158.180 - heap.set(item, prio);
158.181 - heap.decrease(item, prio);
158.182 - heap.increase(item, prio);
158.183 - prio = heap[item];
158.184 -
158.185 - heap.erase(item);
158.186 -
158.187 - state = heap.state(item);
158.188 -
158.189 - state = _Heap::PRE_HEAP;
158.190 - state = _Heap::IN_HEAP;
158.191 - state = _Heap::POST_HEAP;
158.192 - }
158.193 -
158.194 - _Heap& heap;
158.195 - ItemIntMap& map;
158.196 -
158.197 - Constraints() : heap(0), map(0) {}
158.198 - };
158.199 - };
158.200 -
158.201 - /// @}
158.202 - } // namespace lemon
158.203 -}
158.204 -#endif // LEMON_CONCEPT_PATH_H
159.1 --- a/src/lemon/concept/maps.h Sat May 21 21:04:57 2005 +0000
159.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
159.3 @@ -1,187 +0,0 @@
159.4 -/* -*- C++ -*-
159.5 - * src/lemon/concept/maps.h - Part of LEMON, a generic C++ optimization library
159.6 - *
159.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
159.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
159.9 - *
159.10 - * Permission to use, modify and distribute this software is granted
159.11 - * provided that this copyright notice appears in all copies. For
159.12 - * precise terms see the accompanying LICENSE file.
159.13 - *
159.14 - * This software is provided "AS IS" with no warranty of any kind,
159.15 - * express or implied, and with no claim as to its suitability for any
159.16 - * purpose.
159.17 - *
159.18 - */
159.19 -
159.20 -#ifndef LEMON_CONCEPT_MAPS_H
159.21 -#define LEMON_CONCEPT_MAPS_H
159.22 -
159.23 -#include <lemon/concept_check.h>
159.24 -
159.25 -///\ingroup concept
159.26 -///\file
159.27 -///\brief Map concepts checking classes for testing and documenting.
159.28 -
159.29 -namespace lemon {
159.30 -
159.31 - namespace concept {
159.32 -
159.33 - /// \addtogroup concept
159.34 - /// @{
159.35 -
159.36 - /// Readable map concept
159.37 - template<typename K, typename T>
159.38 - class ReadMap
159.39 - {
159.40 - public:
159.41 - /// Map's key type.
159.42 - typedef K Key;
159.43 - /// Map's value type. (The type of objects associated with the keys).
159.44 - typedef T Value;
159.45 -
159.46 - // \bug Value don't need to be default constructible.
159.47 - /// Returns the value associated with a key.
159.48 - Value operator[](const Key &) const {return Value();}
159.49 -
159.50 - template<typename _ReadMap>
159.51 - struct Constraints {
159.52 -
159.53 - void constraints() {
159.54 - Value val = m[key];
159.55 - val = m[key];
159.56 - typename _ReadMap::Value own_val = m[own_key];
159.57 - own_val = m[own_key];
159.58 -
159.59 - ignore_unused_variable_warning(val);
159.60 - ignore_unused_variable_warning(own_val);
159.61 - ignore_unused_variable_warning(key);
159.62 - }
159.63 - Key& key;
159.64 - typename _ReadMap::Key& own_key;
159.65 - _ReadMap& m;
159.66 - };
159.67 -
159.68 - };
159.69 -
159.70 -
159.71 - /// Writable map concept
159.72 - template<typename K, typename T>
159.73 - class WriteMap
159.74 - {
159.75 - public:
159.76 - /// Map's key type.
159.77 - typedef K Key;
159.78 - /// Map's value type. (The type of objects associated with the keys).
159.79 - typedef T Value;
159.80 -
159.81 - /// Sets the value associated with a key.
159.82 - void set(const Key &,const Value &) {}
159.83 -
159.84 - ///Default constructor
159.85 - WriteMap() {}
159.86 -
159.87 - template <typename _WriteMap>
159.88 - struct Constraints {
159.89 - void constraints() {
159.90 - // No constraints for constructor.
159.91 - m.set(key, val);
159.92 - m.set(own_key, own_val);
159.93 - ignore_unused_variable_warning(key);
159.94 - ignore_unused_variable_warning(val);
159.95 - ignore_unused_variable_warning(own_key);
159.96 - ignore_unused_variable_warning(own_val);
159.97 - }
159.98 -
159.99 - Value& val;
159.100 - typename _WriteMap::Value own_val;
159.101 - Key& key;
159.102 - typename _WriteMap::Key& own_key;
159.103 - WriteMap& m;
159.104 -
159.105 - };
159.106 - };
159.107 -
159.108 - ///Read/Writable map concept
159.109 - template<typename K, typename T>
159.110 - class ReadWriteMap : public ReadMap<K,T>,
159.111 - public WriteMap<K,T>
159.112 - {
159.113 - public:
159.114 - /// Map's key type.
159.115 - typedef K Key;
159.116 - /// Map's value type. (The type of objects associated with the keys).
159.117 - typedef T Value;
159.118 -
159.119 - /// Returns the value associated with a key.
159.120 - Value operator[](const Key &) const {return Value();}
159.121 - /// Sets the value associated with a key.
159.122 - void set(const Key & ,const Value &) {}
159.123 -
159.124 - template<typename _ReadWriteMap>
159.125 - struct Constraints {
159.126 - void constraints() {
159.127 - checkConcept<ReadMap<K, T>, _ReadWriteMap >();
159.128 - checkConcept<ReadMap<K, T>, _ReadWriteMap >();
159.129 - }
159.130 - };
159.131 - };
159.132 -
159.133 -
159.134 - ///Dereferable map concept
159.135 - template<typename K, typename T, typename R, typename CR>
159.136 - class ReferenceMap : public ReadWriteMap<K,T>
159.137 - {
159.138 - public:
159.139 - /// Map's key type.
159.140 - typedef K Key;
159.141 - /// Map's value type. (The type of objects associated with the keys).
159.142 - typedef T Value;
159.143 - /// Map's reference type.
159.144 - typedef R Reference;
159.145 - /// Map's const reference type.
159.146 - typedef CR ConstReference;
159.147 -
159.148 - protected:
159.149 - Value tmp;
159.150 - public:
159.151 -
159.152 - ///Returns a reference to the value associated to a key.
159.153 - Reference operator[](const Key &) { return tmp; }
159.154 - ///Returns a const reference to the value associated to a key.
159.155 - ConstReference operator[](const Key &) const
159.156 - { return tmp; }
159.157 - /// Sets the value associated with a key.
159.158 - void set(const Key &k,const Value &t) { operator[](k)=t; }
159.159 -
159.160 - // \todo rethink this concept
159.161 - template<typename _ReferenceMap>
159.162 - struct ReferenceMapConcept {
159.163 -
159.164 - void constraints() {
159.165 - checkConcept<ReadWriteMap, _ReferenceMap >();
159.166 - m[key] = val;
159.167 - val = m[key];
159.168 - m[key] = ref;
159.169 - ref = m[key];
159.170 - m[own_key] = own_val;
159.171 - own_val = m[own_key];
159.172 - m[own_key] = own_ref;
159.173 - own_ref = m[own_key];
159.174 - }
159.175 -
159.176 - typename _ReferenceMap::Key& own_key;
159.177 - typename _ReferenceMap::Value& own_val;
159.178 - typename _ReferenceMap::Reference& own_ref;
159.179 - Key& key;
159.180 - Value& val;
159.181 - Reference& ref;
159.182 - ReferenceMap& m;
159.183 - };
159.184 - };
159.185 -
159.186 - // @}
159.187 -
159.188 - } //namespace concept
159.189 -} //namespace lemon
159.190 -#endif // LEMON_CONCEPT_MAPS_H
160.1 --- a/src/lemon/concept/path.h Sat May 21 21:04:57 2005 +0000
160.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
160.3 @@ -1,236 +0,0 @@
160.4 -/* -*- C++ -*-
160.5 - * src/lemon/concept/path.h - Part of LEMON, a generic C++ optimization library
160.6 - *
160.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
160.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
160.9 - *
160.10 - * Permission to use, modify and distribute this software is granted
160.11 - * provided that this copyright notice appears in all copies. For
160.12 - * precise terms see the accompanying LICENSE file.
160.13 - *
160.14 - * This software is provided "AS IS" with no warranty of any kind,
160.15 - * express or implied, and with no claim as to its suitability for any
160.16 - * purpose.
160.17 - *
160.18 - */
160.19 -
160.20 -///\ingroup concept
160.21 -///\file
160.22 -///\brief Classes for representing paths in graphs.
160.23 -///
160.24 -///\todo Iterators have obsolete style
160.25 -
160.26 -#ifndef LEMON_CONCEPT_PATH_H
160.27 -#define LEMON_CONCEPT_PATH_H
160.28 -
160.29 -#include <lemon/invalid.h>
160.30 -
160.31 -namespace lemon {
160.32 - namespace concept {
160.33 - /// \addtogroup concept
160.34 - /// @{
160.35 -
160.36 -
160.37 - //! \brief A skeleton structure for representing directed paths in a graph.
160.38 - //!
160.39 - //! A skeleton structure for representing directed paths in a graph.
160.40 - //! \param GR The graph type in which the path is.
160.41 - //!
160.42 - //! In a sense, the path can be treated as a graph, for it has \c NodeIt
160.43 - //! and \c EdgeIt with the same usage. These types converts to the \c Node
160.44 - //! and \c Edge of the original graph.
160.45 - template<typename GR>
160.46 - class Path {
160.47 - public:
160.48 -
160.49 - /// Type of the underlying graph.
160.50 - typedef /*typename*/ GR Graph;
160.51 - /// Edge type of the underlying graph.
160.52 - typedef typename Graph::Edge GraphEdge;
160.53 - /// Node type of the underlying graph.
160.54 - typedef typename Graph::Node GraphNode;
160.55 - class NodeIt;
160.56 - class EdgeIt;
160.57 -
160.58 - /// \param _G The graph in which the path is.
160.59 - ///
160.60 - Path(const Graph &) {}
160.61 -
160.62 - /// Length of the path.
160.63 - int length() const {return 0;}
160.64 - /// Returns whether the path is empty.
160.65 - bool empty() const { return true;}
160.66 -
160.67 - /// Resets the path to an empty path.
160.68 - void clear() {}
160.69 -
160.70 - /// \brief Starting point of the path.
160.71 - ///
160.72 - /// Starting point of the path.
160.73 - /// Returns INVALID if the path is empty.
160.74 - GraphNode/*It*/ target() const {return INVALID;}
160.75 - /// \brief End point of the path.
160.76 - ///
160.77 - /// End point of the path.
160.78 - /// Returns INVALID if the path is empty.
160.79 - GraphNode/*It*/ source() const {return INVALID;}
160.80 -
160.81 - /// \brief First NodeIt/EdgeIt.
160.82 - ///
160.83 - /// Initializes node or edge iterator to point to the first
160.84 - /// node or edge.
160.85 - template<typename It>
160.86 - It& first(It &i) const { return i=It(*this); }
160.87 -
160.88 - /// \brief The target of an edge.
160.89 - ///
160.90 - /// Returns node iterator pointing to the target node of the
160.91 - /// given edge iterator.
160.92 - NodeIt target(const EdgeIt&) const {return INVALID;}
160.93 -
160.94 - /// \brief The source of an edge.
160.95 - ///
160.96 - /// Returns node iterator pointing to the source node of the
160.97 - /// given edge iterator.
160.98 - NodeIt source(const EdgeIt&) const {return INVALID;}
160.99 -
160.100 -
160.101 - /* Iterator classes */
160.102 -
160.103 - /**
160.104 - * \brief Iterator class to iterate on the edges of the paths
160.105 - *
160.106 - * This class is used to iterate on the edges of the paths
160.107 - *
160.108 - * Of course it converts to Graph::Edge
160.109 - *
160.110 - */
160.111 - class EdgeIt {
160.112 - public:
160.113 - /// Default constructor
160.114 - EdgeIt() {}
160.115 - /// Invalid constructor
160.116 - EdgeIt(Invalid) {}
160.117 - /// Constructor with starting point
160.118 - EdgeIt(const Path &) {}
160.119 -
160.120 - operator GraphEdge () const {}
160.121 -
160.122 - /// Next edge
160.123 - EdgeIt& operator++() {return *this;}
160.124 -
160.125 - /// Comparison operator
160.126 - bool operator==(const EdgeIt&) const {return true;}
160.127 - /// Comparison operator
160.128 - bool operator!=(const EdgeIt&) const {return true;}
160.129 -// /// Comparison operator
160.130 -// /// \todo It is not clear what is the "natural" ordering.
160.131 -// bool operator<(const EdgeIt& e) const {}
160.132 -
160.133 - };
160.134 -
160.135 - /**
160.136 - * \brief Iterator class to iterate on the nodes of the paths
160.137 - *
160.138 - * This class is used to iterate on the nodes of the paths
160.139 - *
160.140 - * Of course it converts to Graph::Node.
160.141 - *
160.142 - */
160.143 - class NodeIt {
160.144 - public:
160.145 - /// Default constructor
160.146 - NodeIt() {}
160.147 - /// Invalid constructor
160.148 - NodeIt(Invalid) {}
160.149 - /// Constructor with starting point
160.150 - NodeIt(const Path &) {}
160.151 -
160.152 - ///Conversion to Graph::Node
160.153 - operator const GraphNode& () const {}
160.154 - /// Next node
160.155 - NodeIt& operator++() {return *this;}
160.156 -
160.157 - /// Comparison operator
160.158 - bool operator==(const NodeIt&) const {return true;}
160.159 - /// Comparison operator
160.160 - bool operator!=(const NodeIt&) const {return true;}
160.161 -// /// Comparison operator
160.162 -// /// \todo It is not clear what is the "natural" ordering.
160.163 -// bool operator<(const NodeIt& e) const {}
160.164 -
160.165 - };
160.166 -
160.167 - friend class Builder;
160.168 -
160.169 - /**
160.170 - * \brief Class to build paths
160.171 - *
160.172 - * This class is used to fill a path with edges.
160.173 - *
160.174 - * You can push new edges to the front and to the back of the path in
160.175 - * arbitrary order then you should commit these changes to the graph.
160.176 - *
160.177 - * While the builder is active (after the first modifying
160.178 - * operation and until the call of \ref commit()) the
160.179 - * underlining Path is in a "transitional" state (operations on
160.180 - * it have undefined result).
160.181 - */
160.182 - class Builder {
160.183 - public:
160.184 -
160.185 - Path &P;
160.186 -
160.187 - ///\param _P the path you want to fill in.
160.188 - ///
160.189 -
160.190 - Builder(Path &_p) : P(_p) {}
160.191 -
160.192 - /// Sets the starting node of the path.
160.193 -
160.194 - /// Sets the starting node of the path. Edge added to the path
160.195 - /// afterwards have to be incident to this node.
160.196 - /// You \em must start building an empty path with these functions.
160.197 - /// (And you \em must \em not use it later).
160.198 - /// \sa pushFront()
160.199 - /// \sa pushBack()
160.200 - void setStartNode(const GraphNode &) {}
160.201 -
160.202 - ///Push a new edge to the front of the path
160.203 -
160.204 - ///Push a new edge to the front of the path.
160.205 - ///If the path is empty, you \em must call \ref setStartNode() before
160.206 - ///the first use of \ref pushFront().
160.207 - void pushFront(const GraphEdge&) {}
160.208 -
160.209 - ///Push a new edge to the back of the path
160.210 -
160.211 - ///Push a new edge to the back of the path.
160.212 - ///If the path is empty, you \em must call \ref setStartNode() before
160.213 - ///the first use of \ref pushBack().
160.214 - void pushBack(const GraphEdge&) {}
160.215 -
160.216 - ///Commit the changes to the path.
160.217 - void commit() {}
160.218 -
160.219 - ///Reserve (front) storage for the builder in advance.
160.220 -
160.221 - ///If you know a reasonable upper bound on the number of the edges
160.222 - ///to add to the front of the path,
160.223 - ///using this function you may speed up the building.
160.224 - void reserveFront(size_t) {}
160.225 - ///Reserve (back) storage for the builder in advance.
160.226 -
160.227 - ///If you know a reasonable upper bound on the number of the edges
160.228 - ///to add to the back of the path,
160.229 - ///using this function you may speed up the building.
160.230 - void reserveBack(size_t) {}
160.231 - };
160.232 - };
160.233 -
160.234 - ///@}
160.235 - }
160.236 -
160.237 -} // namespace lemon
160.238 -
160.239 -#endif // LEMON_CONCEPT_PATH_H
161.1 --- a/src/lemon/concept/sym_graph.h Sat May 21 21:04:57 2005 +0000
161.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
161.3 @@ -1,653 +0,0 @@
161.4 -/* -*- C++ -*-
161.5 - * src/lemon/concept/graph.h - Part of LEMON, a generic C++ optimization library
161.6 - *
161.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
161.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
161.9 - *
161.10 - * Permission to use, modify and distribute this software is granted
161.11 - * provided that this copyright notice appears in all copies. For
161.12 - * precise terms see the accompanying LICENSE file.
161.13 - *
161.14 - * This software is provided "AS IS" with no warranty of any kind,
161.15 - * express or implied, and with no claim as to its suitability for any
161.16 - * purpose.
161.17 - *
161.18 - */
161.19 -
161.20 -#ifndef LEMON_CONCEPT_SYM_GRAPH_H
161.21 -#define LEMON_CONCEPT_SYM_GRAPH_H
161.22 -
161.23 -///\ingroup concept
161.24 -///\file
161.25 -///\brief Declaration of SymGraph.
161.26 -
161.27 -#include <lemon/invalid.h>
161.28 -#include <lemon/concept/graph.h>
161.29 -#include <lemon/concept/maps.h>
161.30 -
161.31 -namespace lemon {
161.32 - namespace concept {
161.33 -
161.34 - /// \addtogroup concept
161.35 - /// @{
161.36 -
161.37 - /// An empty static graph class.
161.38 -
161.39 - /// This class provides all the common features of a symmetric
161.40 - /// graph structure, however completely without implementations and
161.41 - /// real data structures behind the interface.
161.42 - /// All graph algorithms should compile with this class, but it will not
161.43 - /// run properly, of course.
161.44 - ///
161.45 - /// It can be used for checking the interface compatibility,
161.46 - /// or it can serve as a skeleton of a new symmetric graph structure.
161.47 - ///
161.48 - /// Also, you will find here the full documentation of a certain graph
161.49 - /// feature, the documentation of a real symmetric graph imlementation
161.50 - /// like @ref SymListGraph or
161.51 - /// @ref lemon::SymSmartGraph will just refer to this structure.
161.52 - class StaticSymGraph
161.53 - {
161.54 - public:
161.55 - /// Defalult constructor.
161.56 -
161.57 - /// Defalult constructor.
161.58 - ///
161.59 - StaticSymGraph() { }
161.60 - ///Copy consructor.
161.61 -
161.62 -// ///\todo It is not clear, what we expect from a copy constructor.
161.63 -// ///E.g. How to assign the nodes/edges to each other? What about maps?
161.64 -// StaticGraph(const StaticGraph& g) { }
161.65 -
161.66 - /// The base type of node iterators,
161.67 - /// or in other words, the trivial node iterator.
161.68 -
161.69 - /// This is the base type of each node iterator,
161.70 - /// thus each kind of node iterator converts to this.
161.71 - /// More precisely each kind of node iterator should be inherited
161.72 - /// from the trivial node iterator.
161.73 - class Node {
161.74 - public:
161.75 - /// Default constructor
161.76 -
161.77 - /// @warning The default constructor sets the iterator
161.78 - /// to an undefined value.
161.79 - Node() { }
161.80 - /// Copy constructor.
161.81 -
161.82 - /// Copy constructor.
161.83 - ///
161.84 - Node(const Node&) { }
161.85 -
161.86 - /// Invalid constructor \& conversion.
161.87 -
161.88 - /// This constructor initializes the iterator to be invalid.
161.89 - /// \sa Invalid for more details.
161.90 - Node(Invalid) { }
161.91 - /// Equality operator
161.92 -
161.93 - /// Two iterators are equal if and only if they point to the
161.94 - /// same object or both are invalid.
161.95 - bool operator==(Node) const { return true; }
161.96 -
161.97 - /// Inequality operator
161.98 -
161.99 - /// \sa operator==(Node n)
161.100 - ///
161.101 - bool operator!=(Node) const { return true; }
161.102 -
161.103 - ///Comparison operator.
161.104 -
161.105 - ///This is a strict ordering between the nodes.
161.106 - ///
161.107 - ///This ordering can be different from the order in which NodeIt
161.108 - ///goes through the nodes.
161.109 - ///\todo Possibly we don't need it.
161.110 - bool operator<(Node) const { return true; }
161.111 - };
161.112 -
161.113 - /// This iterator goes through each node.
161.114 -
161.115 - /// This iterator goes through each node.
161.116 - /// Its usage is quite simple, for example you can count the number
161.117 - /// of nodes in graph \c g of type \c Graph like this:
161.118 - /// \code
161.119 - /// int count=0;
161.120 - /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
161.121 - /// \endcode
161.122 - class NodeIt : public Node {
161.123 - public:
161.124 - /// Default constructor
161.125 -
161.126 - /// @warning The default constructor sets the iterator
161.127 - /// to an undefined value.
161.128 - NodeIt() { }
161.129 - /// Copy constructor.
161.130 -
161.131 - /// Copy constructor.
161.132 - ///
161.133 - NodeIt(const NodeIt&) { }
161.134 - /// Invalid constructor \& conversion.
161.135 -
161.136 - /// Initialize the iterator to be invalid.
161.137 - /// \sa Invalid for more details.
161.138 - NodeIt(Invalid) { }
161.139 - /// Sets the iterator to the first node.
161.140 -
161.141 - /// Sets the iterator to the first node of \c g.
161.142 - ///
161.143 - NodeIt(const StaticSymGraph& g) { }
161.144 - /// Node -> NodeIt conversion.
161.145 -
161.146 - /// Sets the iterator to the node of \c g pointed by the trivial
161.147 - /// iterator n.
161.148 - /// This feature necessitates that each time we
161.149 - /// iterate the edge-set, the iteration order is the same.
161.150 - NodeIt(const StaticSymGraph& g, const Node& n) { }
161.151 - /// Next node.
161.152 -
161.153 - /// Assign the iterator to the next node.
161.154 - ///
161.155 - NodeIt& operator++() { return *this; }
161.156 - };
161.157 -
161.158 -
161.159 - /// The base type of the symmetric edge iterators.
161.160 -
161.161 - /// The base type of the symmetric edge iterators.
161.162 - ///
161.163 - class SymEdge {
161.164 - public:
161.165 - /// Default constructor
161.166 -
161.167 - /// @warning The default constructor sets the iterator
161.168 - /// to an undefined value.
161.169 - SymEdge() { }
161.170 - /// Copy constructor.
161.171 -
161.172 - /// Copy constructor.
161.173 - ///
161.174 - SymEdge(const SymEdge&) { }
161.175 - /// Initialize the iterator to be invalid.
161.176 -
161.177 - /// Initialize the iterator to be invalid.
161.178 - ///
161.179 - SymEdge(Invalid) { }
161.180 - /// Equality operator
161.181 -
161.182 - /// Two iterators are equal if and only if they point to the
161.183 - /// same object or both are invalid.
161.184 - bool operator==(SymEdge) const { return true; }
161.185 - /// Inequality operator
161.186 -
161.187 - /// \sa operator==(Node n)
161.188 - ///
161.189 - bool operator!=(SymEdge) const { return true; }
161.190 - ///Comparison operator.
161.191 -
161.192 - ///This is a strict ordering between the nodes.
161.193 - ///
161.194 - ///This ordering can be different from the order in which NodeIt
161.195 - ///goes through the nodes.
161.196 - ///\todo Possibly we don't need it.
161.197 - bool operator<(SymEdge) const { return true; }
161.198 - };
161.199 -
161.200 -
161.201 - /// The base type of the edge iterators.
161.202 -
161.203 - /// The base type of the edge iterators.
161.204 - ///
161.205 - class Edge : public SymEdge {
161.206 - public:
161.207 - /// Default constructor
161.208 -
161.209 - /// @warning The default constructor sets the iterator
161.210 - /// to an undefined value.
161.211 - Edge() { }
161.212 - /// Copy constructor.
161.213 -
161.214 - /// Copy constructor.
161.215 - ///
161.216 - Edge(const Edge&) { }
161.217 - /// Initialize the iterator to be invalid.
161.218 -
161.219 - /// Initialize the iterator to be invalid.
161.220 - ///
161.221 - Edge(Invalid) { }
161.222 - /// Equality operator
161.223 -
161.224 - /// Two iterators are equal if and only if they point to the
161.225 - /// same object or both are invalid.
161.226 - bool operator==(Edge) const { return true; }
161.227 - /// Inequality operator
161.228 -
161.229 - /// \sa operator==(Node n)
161.230 - ///
161.231 - bool operator!=(Edge) const { return true; }
161.232 - ///Comparison operator.
161.233 -
161.234 - ///This is a strict ordering between the nodes.
161.235 - ///
161.236 - ///This ordering can be different from the order in which NodeIt
161.237 - ///goes through the nodes.
161.238 - ///\todo Possibly we don't need it.
161.239 - bool operator<(Edge) const { return true; }
161.240 - };
161.241 -
161.242 - /// This iterator goes trough the outgoing edges of a node.
161.243 -
161.244 - /// This iterator goes trough the \e outgoing edges of a certain node
161.245 - /// of a graph.
161.246 - /// Its usage is quite simple, for example you can count the number
161.247 - /// of outgoing edges of a node \c n
161.248 - /// in graph \c g of type \c Graph as follows.
161.249 - /// \code
161.250 - /// int count=0;
161.251 - /// for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) ++count;
161.252 - /// \endcode
161.253 -
161.254 - class OutEdgeIt : public Edge {
161.255 - public:
161.256 - /// Default constructor
161.257 -
161.258 - /// @warning The default constructor sets the iterator
161.259 - /// to an undefined value.
161.260 - OutEdgeIt() { }
161.261 - /// Copy constructor.
161.262 -
161.263 - /// Copy constructor.
161.264 - ///
161.265 - OutEdgeIt(const OutEdgeIt&) { }
161.266 - /// Initialize the iterator to be invalid.
161.267 -
161.268 - /// Initialize the iterator to be invalid.
161.269 - ///
161.270 - OutEdgeIt(Invalid) { }
161.271 - /// This constructor sets the iterator to first outgoing edge.
161.272 -
161.273 - /// This constructor set the iterator to the first outgoing edge of
161.274 - /// node
161.275 - ///@param n the node
161.276 - ///@param g the graph
161.277 - OutEdgeIt(const StaticSymGraph& g, const Node& n) { }
161.278 - /// Edge -> OutEdgeIt conversion
161.279 -
161.280 - /// Sets the iterator to the value of the trivial iterator \c e.
161.281 - /// This feature necessitates that each time we
161.282 - /// iterate the edge-set, the iteration order is the same.
161.283 - OutEdgeIt(const StaticSymGraph& g, const Edge& e) { }
161.284 - ///Next outgoing edge
161.285 -
161.286 - /// Assign the iterator to the next
161.287 - /// outgoing edge of the corresponding node.
161.288 - OutEdgeIt& operator++() { return *this; }
161.289 - };
161.290 -
161.291 - /// This iterator goes trough the incoming edges of a node.
161.292 -
161.293 - /// This iterator goes trough the \e incoming edges of a certain node
161.294 - /// of a graph.
161.295 - /// Its usage is quite simple, for example you can count the number
161.296 - /// of outgoing edges of a node \c n
161.297 - /// in graph \c g of type \c Graph as follows.
161.298 - /// \code
161.299 - /// int count=0;
161.300 - /// for(Graph::InEdgeIt e(g, n); e!=INVALID; ++e) ++count;
161.301 - /// \endcode
161.302 -
161.303 - class InEdgeIt : public Edge {
161.304 - public:
161.305 - /// Default constructor
161.306 -
161.307 - /// @warning The default constructor sets the iterator
161.308 - /// to an undefined value.
161.309 - InEdgeIt() { }
161.310 - /// Copy constructor.
161.311 -
161.312 - /// Copy constructor.
161.313 - ///
161.314 - InEdgeIt(const InEdgeIt&) { }
161.315 - /// Initialize the iterator to be invalid.
161.316 -
161.317 - /// Initialize the iterator to be invalid.
161.318 - ///
161.319 - InEdgeIt(Invalid) { }
161.320 - /// This constructor sets the iterator to first incoming edge.
161.321 -
161.322 - /// This constructor set the iterator to the first incoming edge of
161.323 - /// node
161.324 - ///@param n the node
161.325 - ///@param g the graph
161.326 - InEdgeIt(const StaticSymGraph& g, const Node& n) { }
161.327 - /// Edge -> InEdgeIt conversion
161.328 -
161.329 - /// Sets the iterator to the value of the trivial iterator \c e.
161.330 - /// This feature necessitates that each time we
161.331 - /// iterate the edge-set, the iteration order is the same.
161.332 - InEdgeIt(const StaticSymGraph& g, const Edge& n) { }
161.333 - /// Next incoming edge
161.334 -
161.335 - /// Assign the iterator to the next inedge of the corresponding node.
161.336 - ///
161.337 - InEdgeIt& operator++() { return *this; }
161.338 - };
161.339 - /// This iterator goes through each symmetric edge.
161.340 -
161.341 - /// This iterator goes through each symmetric edge of a graph.
161.342 - /// Its usage is quite simple, for example you can count the number
161.343 - /// of symmetric edges in a graph \c g of type \c Graph as follows:
161.344 - /// \code
161.345 - /// int count=0;
161.346 - /// for(Graph::SymEdgeIt e(g); e!=INVALID; ++e) ++count;
161.347 - /// \endcode
161.348 - class SymEdgeIt : public SymEdge {
161.349 - public:
161.350 - /// Default constructor
161.351 -
161.352 - /// @warning The default constructor sets the iterator
161.353 - /// to an undefined value.
161.354 - SymEdgeIt() { }
161.355 - /// Copy constructor.
161.356 -
161.357 - /// Copy constructor.
161.358 - ///
161.359 - SymEdgeIt(const SymEdgeIt&) { }
161.360 - /// Initialize the iterator to be invalid.
161.361 -
161.362 - /// Initialize the iterator to be invalid.
161.363 - ///
161.364 - SymEdgeIt(Invalid) { }
161.365 - /// This constructor sets the iterator to first edge.
161.366 -
161.367 - /// This constructor set the iterator to the first edge of
161.368 - /// node
161.369 - ///@param g the graph
161.370 - SymEdgeIt(const StaticSymGraph& g) { }
161.371 - /// Edge -> EdgeIt conversion
161.372 -
161.373 - /// Sets the iterator to the value of the trivial iterator \c e.
161.374 - /// This feature necessitates that each time we
161.375 - /// iterate the edge-set, the iteration order is the same.
161.376 - SymEdgeIt(const StaticSymGraph&, const SymEdge&) { }
161.377 - ///Next edge
161.378 -
161.379 - /// Assign the iterator to the next
161.380 - /// edge of the corresponding node.
161.381 - SymEdgeIt& operator++() { return *this; }
161.382 - };
161.383 - /// This iterator goes through each edge.
161.384 -
161.385 - /// This iterator goes through each edge of a graph.
161.386 - /// Its usage is quite simple, for example you can count the number
161.387 - /// of edges in a graph \c g of type \c Graph as follows:
161.388 - /// \code
161.389 - /// int count=0;
161.390 - /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
161.391 - /// \endcode
161.392 - class EdgeIt : public Edge {
161.393 - public:
161.394 - /// Default constructor
161.395 -
161.396 - /// @warning The default constructor sets the iterator
161.397 - /// to an undefined value.
161.398 - EdgeIt() { }
161.399 - /// Copy constructor.
161.400 -
161.401 - /// Copy constructor.
161.402 - ///
161.403 - EdgeIt(const EdgeIt&) { }
161.404 - /// Initialize the iterator to be invalid.
161.405 -
161.406 - /// Initialize the iterator to be invalid.
161.407 - ///
161.408 - EdgeIt(Invalid) { }
161.409 - /// This constructor sets the iterator to first edge.
161.410 -
161.411 - /// This constructor set the iterator to the first edge of
161.412 - /// node
161.413 - ///@param g the graph
161.414 - EdgeIt(const StaticSymGraph& g) { }
161.415 - /// Edge -> EdgeIt conversion
161.416 -
161.417 - /// Sets the iterator to the value of the trivial iterator \c e.
161.418 - /// This feature necessitates that each time we
161.419 - /// iterate the edge-set, the iteration order is the same.
161.420 - EdgeIt(const StaticSymGraph&, const Edge&) { }
161.421 - ///Next edge
161.422 -
161.423 - /// Assign the iterator to the next
161.424 - /// edge of the corresponding node.
161.425 - EdgeIt& operator++() { return *this; }
161.426 - };
161.427 -
161.428 - /// First node of the graph.
161.429 -
161.430 - /// \retval i the first node.
161.431 - /// \return the first node.
161.432 - ///
161.433 - NodeIt& first(NodeIt& i) const { return i; }
161.434 -
161.435 - /// The first incoming edge.
161.436 -
161.437 - /// The first incoming edge.
161.438 - ///
161.439 - InEdgeIt& first(InEdgeIt &i, Node) const { return i; }
161.440 - /// The first outgoing edge.
161.441 -
161.442 - /// The first outgoing edge.
161.443 - ///
161.444 - OutEdgeIt& first(OutEdgeIt& i, Node) const { return i; }
161.445 - /// The first edge of the Graph.
161.446 -
161.447 - /// The first edge of the Graph.
161.448 - ///
161.449 - EdgeIt& first(EdgeIt& i) const { return i; }
161.450 - /// The first symmetric edge of the Graph.
161.451 -
161.452 - /// The first symmetric edge of the Graph.
161.453 - ///
161.454 - SymEdgeIt& first(SymEdgeIt& i) const { return i; }
161.455 -
161.456 - ///Gives back the target node of an edge.
161.457 -
161.458 - ///Gives back the target node of an edge.
161.459 - ///
161.460 - Node target(Edge) const { return INVALID; }
161.461 - ///Gives back the source node of an edge.
161.462 -
161.463 - ///Gives back the source node of an edge.
161.464 - ///
161.465 - Node source(Edge) const { return INVALID; }
161.466 -
161.467 - ///Gives back the first node of an symmetric edge.
161.468 -
161.469 - ///Gives back the first node of an symmetric edge.
161.470 - ///
161.471 - Node target(SymEdge) const { return INVALID; }
161.472 - ///Gives back the second node of an symmetric edge.
161.473 -
161.474 - ///Gives back the second node of an symmetric edge.
161.475 - ///
161.476 - Node source(SymEdge) const { return INVALID; }
161.477 - ///Gives back the \e id of a node.
161.478 -
161.479 - ///\warning Not all graph structures provide this feature.
161.480 - ///
161.481 - ///\todo Should each graph provide \c id?
161.482 - int id(const Node&) const { return 0; }
161.483 - ///Gives back the \e id of an edge.
161.484 -
161.485 - ///\warning Not all graph structures provide this feature.
161.486 - ///
161.487 - ///\todo Should each graph provide \c id?
161.488 - int id(const Edge&) const { return 0; }
161.489 -
161.490 - ///\warning Not all graph structures provide this feature.
161.491 - ///
161.492 - ///\todo Should each graph provide \c id?
161.493 - int id(const SymEdge&) const { return 0; }
161.494 -
161.495 - ///\e
161.496 -
161.497 - ///\todo Should it be in the concept?
161.498 - ///
161.499 - int nodeNum() const { return 0; }
161.500 - ///\e
161.501 -
161.502 - ///\todo Should it be in the concept?
161.503 - ///
161.504 - int edgeNum() const { return 0; }
161.505 -
161.506 - ///\todo Should it be in the concept?
161.507 - ///
161.508 - int symEdgeNum() const { return 0; }
161.509 -
161.510 -
161.511 - /// Gives back the forward directed edge of the symmetric edge.
161.512 - Edge forward(SymEdge) const {return INVALID;}
161.513 -
161.514 - /// Gives back the backward directed edge of the symmetric edge.
161.515 - Edge backward(SymEdge) const {return INVALID;};
161.516 -
161.517 - /// Gives back the opposite of the edge.
161.518 - Edge opposite(Edge) const {return INVALID;}
161.519 -
161.520 - ///Reference map of the nodes to type \c T.
161.521 - /// \ingroup concept
161.522 - ///Reference map of the nodes to type \c T.
161.523 - /// \sa Reference
161.524 - /// \warning Making maps that can handle bool type (NodeMap<bool>)
161.525 - /// needs some extra attention!
161.526 - template<class T> class NodeMap : public ReferenceMap< Node, T >
161.527 - {
161.528 - public:
161.529 -
161.530 - ///\e
161.531 - NodeMap(const StaticSymGraph&) { }
161.532 - ///\e
161.533 - NodeMap(const StaticSymGraph&, T) { }
161.534 -
161.535 - ///Copy constructor
161.536 - template<typename TT> NodeMap(const NodeMap<TT>&) { }
161.537 - ///Assignment operator
161.538 - template<typename TT> NodeMap& operator=(const NodeMap<TT>&)
161.539 - { return *this; }
161.540 - };
161.541 -
161.542 - ///Reference map of the edges to type \c T.
161.543 -
161.544 - /// \ingroup concept
161.545 - ///Reference map of the edges to type \c T.
161.546 - /// \sa Reference
161.547 - /// \warning Making maps that can handle bool type (EdgeMap<bool>)
161.548 - /// needs some extra attention!
161.549 - template<class T> class EdgeMap
161.550 - : public ReferenceMap<Edge,T>
161.551 - {
161.552 - public:
161.553 -
161.554 - ///\e
161.555 - EdgeMap(const StaticSymGraph&) { }
161.556 - ///\e
161.557 - EdgeMap(const StaticSymGraph&, T) { }
161.558 -
161.559 - ///Copy constructor
161.560 - template<typename TT> EdgeMap(const EdgeMap<TT>&) { }
161.561 - ///Assignment operator
161.562 - template<typename TT> EdgeMap &operator=(const EdgeMap<TT>&)
161.563 - { return *this; }
161.564 - };
161.565 -
161.566 - ///Reference map of the edges to type \c T.
161.567 -
161.568 - /// \ingroup concept
161.569 - ///Reference map of the symmetric edges to type \c T.
161.570 - /// \sa Reference
161.571 - /// \warning Making maps that can handle bool type (EdgeMap<bool>)
161.572 - /// needs some extra attention!
161.573 - template<class T> class SymEdgeMap
161.574 - : public ReferenceMap<SymEdge,T>
161.575 - {
161.576 - public:
161.577 -
161.578 - ///\e
161.579 - SymEdgeMap(const StaticSymGraph&) { }
161.580 - ///\e
161.581 - SymEdgeMap(const StaticSymGraph&, T) { }
161.582 -
161.583 - ///Copy constructor
161.584 - template<typename TT> SymEdgeMap(const SymEdgeMap<TT>&) { }
161.585 - ///Assignment operator
161.586 - template<typename TT> SymEdgeMap &operator=(const SymEdgeMap<TT>&)
161.587 - { return *this; }
161.588 - };
161.589 - };
161.590 -
161.591 -
161.592 -
161.593 - /// An empty non-static graph class.
161.594 -
161.595 - /// This class provides everything that \ref StaticGraph
161.596 - /// with additional functionality which enables to build a
161.597 - /// graph from scratch.
161.598 - class ExtendableSymGraph : public StaticSymGraph
161.599 - {
161.600 - public:
161.601 - /// Defalult constructor.
161.602 -
161.603 - /// Defalult constructor.
161.604 - ///
161.605 - ExtendableSymGraph() { }
161.606 - ///Add a new node to the graph.
161.607 -
161.608 - /// \return the new node.
161.609 - ///
161.610 - Node addNode() { return INVALID; }
161.611 - ///Add a new edge to the graph.
161.612 -
161.613 - ///Add a new symmetric edge to the graph with source node \c t
161.614 - ///and target node \c h.
161.615 - ///\return the new edge.
161.616 - SymEdge addEdge(Node h, Node t) { return INVALID; }
161.617 -
161.618 - /// Resets the graph.
161.619 -
161.620 - /// This function deletes all edges and nodes of the graph.
161.621 - /// It also frees the memory allocated to store them.
161.622 - /// \todo It might belong to \ref ErasableGraph.
161.623 - void clear() { }
161.624 - };
161.625 -
161.626 - /// An empty erasable graph class.
161.627 -
161.628 - /// This class is an extension of \ref ExtendableGraph. It also makes it
161.629 - /// possible to erase edges or nodes.
161.630 - class ErasableSymGraph : public ExtendableSymGraph
161.631 - {
161.632 - public:
161.633 - /// Defalult constructor.
161.634 -
161.635 - /// Defalult constructor.
161.636 - ///
161.637 - ErasableSymGraph() { }
161.638 - /// Deletes a node.
161.639 -
161.640 - /// Deletes node \c n node.
161.641 - ///
161.642 - void erase(Node n) { }
161.643 - /// Deletes an edge.
161.644 -
161.645 - /// Deletes edge \c e edge.
161.646 - ///
161.647 - void erase(SymEdge e) { }
161.648 - };
161.649 -
161.650 - // @}
161.651 - } //namespace concept
161.652 -} //namespace lemon
161.653 -
161.654 -
161.655 -
161.656 -#endif // LEMON_CONCEPT_GRAPH_H
162.1 --- a/src/lemon/concept/undir_graph.h Sat May 21 21:04:57 2005 +0000
162.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
162.3 @@ -1,531 +0,0 @@
162.4 -/* -*- C++ -*-
162.5 - *
162.6 - * src/lemon/concept/undir_graph_component.h - Part of LEMON, a generic
162.7 - * C++ optimization library
162.8 - *
162.9 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
162.10 - * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
162.11 - * EGRES).
162.12 - *
162.13 - * Permission to use, modify and distribute this software is granted
162.14 - * provided that this copyright notice appears in all copies. For
162.15 - * precise terms see the accompanying LICENSE file.
162.16 - *
162.17 - * This software is provided "AS IS" with no warranty of any kind,
162.18 - * express or implied, and with no claim as to its suitability for any
162.19 - * purpose.
162.20 - *
162.21 - */
162.22 -
162.23 -///\ingroup graph_concepts
162.24 -///\file
162.25 -///\brief Undirected graphs and components of.
162.26 -
162.27 -
162.28 -#ifndef LEMON_CONCEPT_UNDIR_GRAPH_H
162.29 -#define LEMON_CONCEPT_UNDIR_GRAPH_H
162.30 -
162.31 -#include <lemon/concept/graph_component.h>
162.32 -
162.33 -namespace lemon {
162.34 - namespace concept {
162.35 -
162.36 - /// \addtogroup graph_concepts
162.37 - /// @{
162.38 -
162.39 -
162.40 - /// Skeleton class which describes an edge with direction in \ref
162.41 - /// UndirGraph "undirected graph".
162.42 - template <typename UndirGraph>
162.43 - class UndirGraphEdge : public UndirGraph::UndirEdge {
162.44 - typedef typename UndirGraph::UndirEdge UndirEdge;
162.45 - typedef typename UndirGraph::Node Node;
162.46 - public:
162.47 -
162.48 - /// \e
162.49 - UndirGraphEdge() {}
162.50 -
162.51 - /// \e
162.52 - UndirGraphEdge(const UndirGraphEdge& e) : UndirGraph::UndirEdge(e) {}
162.53 -
162.54 - /// \e
162.55 - UndirGraphEdge(Invalid) {}
162.56 -
162.57 - /// \brief Directed edge from undirected edge and a source node.
162.58 - ///
162.59 - /// Constructs a directed edge from undirected edge and a source node.
162.60 - ///
162.61 - /// \note You have to specify the graph for this constructor.
162.62 - UndirGraphEdge(const UndirGraph &g,
162.63 - UndirEdge undir_edge, Node n) {
162.64 - ignore_unused_variable_warning(undir_edge);
162.65 - ignore_unused_variable_warning(g);
162.66 - ignore_unused_variable_warning(n);
162.67 - }
162.68 -
162.69 - /// \e
162.70 - UndirGraphEdge& operator=(UndirGraphEdge) { return *this; }
162.71 -
162.72 - /// \e
162.73 - bool operator==(UndirGraphEdge) const { return true; }
162.74 - /// \e
162.75 - bool operator!=(UndirGraphEdge) const { return false; }
162.76 -
162.77 - /// \e
162.78 - bool operator<(UndirGraphEdge) const { return false; }
162.79 -
162.80 - template <typename Edge>
162.81 - struct Constraints {
162.82 - void constraints() {
162.83 - const_constraints();
162.84 - }
162.85 - void const_constraints() const {
162.86 - /// \bug This should be is_base_and_derived ...
162.87 - UndirEdge ue = e;
162.88 - ue = e;
162.89 -
162.90 - Edge e_with_source(graph,ue,n);
162.91 - ignore_unused_variable_warning(e_with_source);
162.92 - }
162.93 - Edge e;
162.94 - UndirEdge ue;
162.95 - UndirGraph graph;
162.96 - Node n;
162.97 - };
162.98 - };
162.99 -
162.100 -
162.101 - struct BaseIterableUndirGraphConcept {
162.102 -
162.103 - template <typename Graph>
162.104 - struct Constraints {
162.105 -
162.106 - typedef typename Graph::UndirEdge UndirEdge;
162.107 - typedef typename Graph::Edge Edge;
162.108 - typedef typename Graph::Node Node;
162.109 -
162.110 - void constraints() {
162.111 - checkConcept<BaseIterableGraphComponent, Graph>();
162.112 - checkConcept<GraphItem<>, UndirEdge>();
162.113 - checkConcept<UndirGraphEdge<Graph>, Edge>();
162.114 -
162.115 - graph.first(ue);
162.116 - graph.next(ue);
162.117 -
162.118 - const_constraints();
162.119 - }
162.120 - void const_constraints() {
162.121 - Node n;
162.122 - n = graph.target(ue);
162.123 - n = graph.source(ue);
162.124 - n = graph.oppositeNode(n0, ue);
162.125 -
162.126 - bool b;
162.127 - b = graph.forward(e);
162.128 - ignore_unused_variable_warning(b);
162.129 - }
162.130 -
162.131 - Graph graph;
162.132 - Edge e;
162.133 - Node n0;
162.134 - UndirEdge ue;
162.135 - };
162.136 -
162.137 - };
162.138 -
162.139 -
162.140 - struct IterableUndirGraphConcept {
162.141 -
162.142 - template <typename Graph>
162.143 - struct Constraints {
162.144 - void constraints() {
162.145 - /// \todo we don't need the iterable component to be base iterable
162.146 - /// Don't we really???
162.147 - //checkConcept< BaseIterableUndirGraphConcept, Graph > ();
162.148 -
162.149 - checkConcept<IterableGraphComponent, Graph> ();
162.150 -
162.151 - typedef typename Graph::UndirEdge UndirEdge;
162.152 - typedef typename Graph::UndirEdgeIt UndirEdgeIt;
162.153 - typedef typename Graph::IncEdgeIt IncEdgeIt;
162.154 -
162.155 - checkConcept<GraphIterator<Graph, UndirEdge>, UndirEdgeIt>();
162.156 - checkConcept<GraphIncIterator<Graph, UndirEdge>, IncEdgeIt>();
162.157 - }
162.158 - };
162.159 -
162.160 - };
162.161 -
162.162 - struct MappableUndirGraphConcept {
162.163 -
162.164 - template <typename Graph>
162.165 - struct Constraints {
162.166 -
162.167 - struct Dummy {
162.168 - int value;
162.169 - Dummy() : value(0) {}
162.170 - Dummy(int _v) : value(_v) {}
162.171 - };
162.172 -
162.173 - void constraints() {
162.174 - checkConcept<MappableGraphComponent, Graph>();
162.175 -
162.176 - typedef typename Graph::template UndirEdgeMap<int> IntMap;
162.177 - checkConcept<GraphMap<Graph, typename Graph::UndirEdge, int>,
162.178 - IntMap >();
162.179 -
162.180 - typedef typename Graph::template UndirEdgeMap<bool> BoolMap;
162.181 - checkConcept<GraphMap<Graph, typename Graph::UndirEdge, bool>,
162.182 - BoolMap >();
162.183 -
162.184 - typedef typename Graph::template UndirEdgeMap<Dummy> DummyMap;
162.185 - checkConcept<GraphMap<Graph, typename Graph::UndirEdge, Dummy>,
162.186 - DummyMap >();
162.187 - }
162.188 - };
162.189 -
162.190 - };
162.191 -
162.192 - struct ExtendableUndirGraphConcept {
162.193 -
162.194 - template <typename Graph>
162.195 - struct Constraints {
162.196 - void constraints() {
162.197 - node_a = graph.addNode();
162.198 - uedge = graph.addEdge(node_a, node_b);
162.199 - }
162.200 - typename Graph::Node node_a, node_b;
162.201 - typename Graph::UndirEdge uedge;
162.202 - Graph graph;
162.203 - };
162.204 -
162.205 - };
162.206 -
162.207 - struct ErasableUndirGraphConcept {
162.208 -
162.209 - template <typename Graph>
162.210 - struct Constraints {
162.211 - void constraints() {
162.212 - graph.erase(n);
162.213 - graph.erase(e);
162.214 - }
162.215 - Graph graph;
162.216 - typename Graph::Node n;
162.217 - typename Graph::UndirEdge e;
162.218 - };
162.219 -
162.220 - };
162.221 -
162.222 - /// Class describing the concept of Undirected Graphs.
162.223 -
162.224 - /// This class describes the common interface of all Undirected
162.225 - /// Graphs.
162.226 - ///
162.227 - /// As all concept describing classes it provides only interface
162.228 - /// without any sensible implementation. So any algorithm for
162.229 - /// undirected graph should compile with this class, but it will not
162.230 - /// run properly, of couse.
162.231 - ///
162.232 - /// In LEMON undirected graphs also fulfill the concept of directed
162.233 - /// graphs (\ref lemon::concept::Graph "Graph Concept"). For
162.234 - /// explanation of this and more see also the page \ref undir_graphs,
162.235 - /// a tutorial about undirected graphs.
162.236 -
162.237 - class UndirGraph {
162.238 - public:
162.239 -
162.240 - /// Type describing a node in the graph
162.241 - typedef GraphNode Node;
162.242 -
162.243 - /// Type describing an undirected edge
162.244 - typedef GraphItem<'u'> UndirEdge;
162.245 -
162.246 - /// Type describing an UndirEdge with direction
162.247 -#ifndef DOXYGEN
162.248 - typedef UndirGraphEdge<UndirGraph> Edge;
162.249 -#else
162.250 - typedef UndirGraphEdge Edge;
162.251 -#endif
162.252 -
162.253 - /// Iterator type which iterates over all nodes
162.254 -#ifndef DOXYGEN
162.255 - typedef GraphIterator<UndirGraph, Node> NodeIt;
162.256 -#else
162.257 - typedef GraphIterator NodeIt;
162.258 -#endif
162.259 -
162.260 - /// Iterator type which iterates over all undirected edges
162.261 -#ifndef DOXYGEN
162.262 - typedef GraphIterator<UndirGraph, UndirEdge> UndirEdgeIt;
162.263 -#else
162.264 - typedef GraphIterator UndirEdgeIt;
162.265 -#endif
162.266 -
162.267 - /// Iterator type which iterates over all directed edges.
162.268 -
162.269 - /// Iterator type which iterates over all edges (each undirected
162.270 - /// edge occurs twice with both directions.
162.271 -#ifndef DOXYGEN
162.272 - typedef GraphIterator<UndirGraph, Edge> EdgeIt;
162.273 -#else
162.274 - typedef GraphIterator EdgeIt;
162.275 -#endif
162.276 -
162.277 -
162.278 - /// Iterator of undirected edges incident to a node
162.279 -#ifndef DOXYGEN
162.280 - typedef GraphIncIterator<UndirGraph, UndirEdge, 'u'> IncEdgeIt;
162.281 -#else
162.282 - typedef GraphIncIterator IncEdgeIt;
162.283 -#endif
162.284 -
162.285 - /// Iterator of edges incoming to a node
162.286 -#ifndef DOXYGEN
162.287 - typedef GraphIncIterator<UndirGraph, Edge, 'i'> InEdgeIt;
162.288 -#else
162.289 - typedef GraphIncIterator InEdgeIt;
162.290 -#endif
162.291 -
162.292 - /// Iterator of edges outgoing from a node
162.293 -#ifndef DOXYGEN
162.294 - typedef GraphIncIterator<UndirGraph, Edge, 'o'> OutEdgeIt;
162.295 -#else
162.296 - typedef GraphIncIterator OutEdgeIt;
162.297 -#endif
162.298 -
162.299 - /// NodeMap template
162.300 -#ifdef DOXYGEN
162.301 - typedef GraphMap NodeMap<T>;
162.302 -#endif
162.303 -
162.304 - /// UndirEdgeMap template
162.305 -#ifdef DOXYGEN
162.306 - typedef GraphMap UndirEdgeMap<T>;
162.307 -#endif
162.308 -
162.309 - /// EdgeMap template
162.310 -#ifdef DOXYGEN
162.311 - typedef GraphMap EdgeMap<T>;
162.312 -#endif
162.313 -
162.314 - template <typename T>
162.315 - class NodeMap : public GraphMap<UndirGraph, Node, T> {
162.316 - typedef GraphMap<UndirGraph, Node, T> Parent;
162.317 - public:
162.318 -
162.319 - explicit NodeMap(const UndirGraph &g) : Parent(g) {}
162.320 - NodeMap(const UndirGraph &g, T t) : Parent(g, t) {}
162.321 - };
162.322 -
162.323 - template <typename T>
162.324 - class UndirEdgeMap : public GraphMap<UndirGraph, UndirEdge, T> {
162.325 - typedef GraphMap<UndirGraph, UndirEdge, T> Parent;
162.326 - public:
162.327 -
162.328 - explicit UndirEdgeMap(const UndirGraph &g) : Parent(g) {}
162.329 - UndirEdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
162.330 - };
162.331 -
162.332 - template <typename T>
162.333 - class EdgeMap : public GraphMap<UndirGraph, Edge, T> {
162.334 - typedef GraphMap<UndirGraph, Edge, T> Parent;
162.335 - public:
162.336 -
162.337 - explicit EdgeMap(const UndirGraph &g) : Parent(g) {}
162.338 - EdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
162.339 - };
162.340 -
162.341 - /// Is the Edge oriented "forward"?
162.342 -
162.343 - /// Returns whether the given directed edge is same orientation as
162.344 - /// the corresponding undirected edge.
162.345 - ///
162.346 - /// \todo "What does the direction of an undirected edge mean?"
162.347 - bool forward(Edge) const { return true; }
162.348 -
162.349 - /// Opposite node on an edge
162.350 -
162.351 - /// \return the opposite of the given Node on the given Edge
162.352 - ///
162.353 - /// \todo What should we do if given Node and Edge are not incident?
162.354 - Node oppositeNode(Node, UndirEdge) const { return INVALID; }
162.355 -
162.356 - /// First node of the undirected edge.
162.357 -
162.358 - /// \return the first node of the given UndirEdge.
162.359 - ///
162.360 - /// Naturally undirectected edges don't have direction and thus
162.361 - /// don't have source and target node. But we use these two methods
162.362 - /// to query the two endnodes of the edge. The direction of the edge
162.363 - /// which arises this way is called the inherent direction of the
162.364 - /// undirected edge, and is used to define the "forward" direction
162.365 - /// of the directed versions of the edges.
162.366 - /// \sa forward
162.367 - Node source(UndirEdge) const { return INVALID; }
162.368 -
162.369 - /// Second node of the undirected edge.
162.370 - Node target(UndirEdge) const { return INVALID; }
162.371 -
162.372 - /// Source node of the directed edge.
162.373 - Node source(Edge) const { return INVALID; }
162.374 -
162.375 - /// Target node of the directed edge.
162.376 - Node target(Edge) const { return INVALID; }
162.377 -
162.378 - /// First node of the graph
162.379 -
162.380 - /// \note This method is part of so called \ref
162.381 - /// developpers_interface "Developpers' interface", so it shouldn't
162.382 - /// be used in an end-user program.
162.383 - void first(Node&) const {}
162.384 - /// Next node of the graph
162.385 -
162.386 - /// \note This method is part of so called \ref
162.387 - /// developpers_interface "Developpers' interface", so it shouldn't
162.388 - /// be used in an end-user program.
162.389 - void next(Node&) const {}
162.390 -
162.391 - /// First undirected edge of the graph
162.392 -
162.393 - /// \note This method is part of so called \ref
162.394 - /// developpers_interface "Developpers' interface", so it shouldn't
162.395 - /// be used in an end-user program.
162.396 - void first(UndirEdge&) const {}
162.397 - /// Next undirected edge of the graph
162.398 -
162.399 - /// \note This method is part of so called \ref
162.400 - /// developpers_interface "Developpers' interface", so it shouldn't
162.401 - /// be used in an end-user program.
162.402 - void next(UndirEdge&) const {}
162.403 -
162.404 - /// First directed edge of the graph
162.405 -
162.406 - /// \note This method is part of so called \ref
162.407 - /// developpers_interface "Developpers' interface", so it shouldn't
162.408 - /// be used in an end-user program.
162.409 - void first(Edge&) const {}
162.410 - /// Next directed edge of the graph
162.411 -
162.412 - /// \note This method is part of so called \ref
162.413 - /// developpers_interface "Developpers' interface", so it shouldn't
162.414 - /// be used in an end-user program.
162.415 - void next(Edge&) const {}
162.416 -
162.417 - /// First outgoing edge from a given node
162.418 -
162.419 - /// \note This method is part of so called \ref
162.420 - /// developpers_interface "Developpers' interface", so it shouldn't
162.421 - /// be used in an end-user program.
162.422 - void firstOut(Edge&, Node) const {}
162.423 - /// Next outgoing edge to a node
162.424 -
162.425 - /// \note This method is part of so called \ref
162.426 - /// developpers_interface "Developpers' interface", so it shouldn't
162.427 - /// be used in an end-user program.
162.428 - void nextOut(Edge&) const {}
162.429 -
162.430 - /// First incoming edge to a given node
162.431 -
162.432 - /// \note This method is part of so called \ref
162.433 - /// developpers_interface "Developpers' interface", so it shouldn't
162.434 - /// be used in an end-user program.
162.435 - void firstIn(Edge&, Node) const {}
162.436 - /// Next incoming edge to a node
162.437 -
162.438 - /// \note This method is part of so called \ref
162.439 - /// developpers_interface "Developpers' interface", so it shouldn't
162.440 - /// be used in an end-user program.
162.441 - void nextIn(Edge&) const {}
162.442 -
162.443 -
162.444 - /// Base node of the iterator
162.445 - ///
162.446 - /// Returns the base node (the source in this case) of the iterator
162.447 - Node baseNode(OutEdgeIt e) const {
162.448 - return source(e);
162.449 - }
162.450 - /// Running node of the iterator
162.451 - ///
162.452 - /// Returns the running node (the target in this case) of the
162.453 - /// iterator
162.454 - Node runningNode(OutEdgeIt e) const {
162.455 - return target(e);
162.456 - }
162.457 -
162.458 - /// Base node of the iterator
162.459 - ///
162.460 - /// Returns the base node (the target in this case) of the iterator
162.461 - Node baseNode(InEdgeIt e) const {
162.462 - return target(e);
162.463 - }
162.464 - /// Running node of the iterator
162.465 - ///
162.466 - /// Returns the running node (the source in this case) of the
162.467 - /// iterator
162.468 - Node runningNode(InEdgeIt e) const {
162.469 - return source(e);
162.470 - }
162.471 -
162.472 - /// Base node of the iterator
162.473 - ///
162.474 - /// Returns the base node of the iterator
162.475 - Node baseNode(IncEdgeIt) const {
162.476 - return INVALID;
162.477 - }
162.478 - /// Running node of the iterator
162.479 - ///
162.480 - /// Returns the running node of the iterator
162.481 - Node runningNode(IncEdgeIt) const {
162.482 - return INVALID;
162.483 - }
162.484 -
162.485 -
162.486 - template <typename Graph>
162.487 - struct Constraints {
162.488 - void constraints() {
162.489 - checkConcept<BaseIterableUndirGraphConcept, Graph>();
162.490 - checkConcept<IterableUndirGraphConcept, Graph>();
162.491 - checkConcept<MappableUndirGraphConcept, Graph>();
162.492 - }
162.493 - };
162.494 -
162.495 - };
162.496 -
162.497 - class ExtendableUndirGraph : public UndirGraph {
162.498 - public:
162.499 -
162.500 - template <typename Graph>
162.501 - struct Constraints {
162.502 - void constraints() {
162.503 - checkConcept<BaseIterableUndirGraphConcept, Graph>();
162.504 - checkConcept<IterableUndirGraphConcept, Graph>();
162.505 - checkConcept<MappableUndirGraphConcept, Graph>();
162.506 -
162.507 - checkConcept<UndirGraph, Graph>();
162.508 - checkConcept<ExtendableUndirGraphConcept, Graph>();
162.509 - checkConcept<ClearableGraphComponent, Graph>();
162.510 - }
162.511 - };
162.512 -
162.513 - };
162.514 -
162.515 - class ErasableUndirGraph : public ExtendableUndirGraph {
162.516 - public:
162.517 -
162.518 - template <typename Graph>
162.519 - struct Constraints {
162.520 - void constraints() {
162.521 - checkConcept<ExtendableUndirGraph, Graph>();
162.522 - checkConcept<ErasableUndirGraphConcept, Graph>();
162.523 - }
162.524 - };
162.525 -
162.526 - };
162.527 -
162.528 - /// @}
162.529 -
162.530 - }
162.531 -
162.532 -}
162.533 -
162.534 -#endif
163.1 --- a/src/lemon/concept_check.h Sat May 21 21:04:57 2005 +0000
163.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
163.3 @@ -1,89 +0,0 @@
163.4 -// -*- C++ -*-
163.5 -// Modified for use in LEMON.
163.6 -// We should really consider using Boost...
163.7 -
163.8 -
163.9 -//
163.10 -// (C) Copyright Jeremy Siek 2000.
163.11 -// Distributed under the Boost Software License, Version 1.0. (See
163.12 -// accompanying file LICENSE_1_0.txt or copy at
163.13 -// http://www.boost.org/LICENSE_1_0.txt)
163.14 -//
163.15 -// Revision History:
163.16 -// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
163.17 -// 02 April 2001: Removed limits header altogether. (Jeremy Siek)
163.18 -// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
163.19 -//
163.20 -
163.21 -// See http://www.boost.org/libs/concept_check for documentation.
163.22 -
163.23 -#ifndef LEMON_BOOST_CONCEPT_CHECKS_HPP
163.24 -#define LEMON_BOOST_CONCEPT_CHECKS_HPP
163.25 -
163.26 -namespace lemon {
163.27 -
163.28 - /*
163.29 - "inline" is used for ignore_unused_variable_warning()
163.30 - and function_requires() to make sure there is no
163.31 - overtarget with g++.
163.32 - */
163.33 -
163.34 - template <class T> inline void ignore_unused_variable_warning(const T&) { }
163.35 -
163.36 - template <class Concept>
163.37 - inline void function_requires()
163.38 - {
163.39 -#if !defined(NDEBUG)
163.40 - void (Concept::*x)() = & Concept::constraints;
163.41 - ignore_unused_variable_warning(x);
163.42 -#endif
163.43 - }
163.44 -
163.45 - template <typename Concept, typename Type>
163.46 - inline void checkConcept() {
163.47 -#if !defined(NDEBUG)
163.48 - typedef typename Concept::template Constraints<Type> ConceptCheck;
163.49 - void (ConceptCheck::*x)() = & ConceptCheck::constraints;
163.50 - ignore_unused_variable_warning(x);
163.51 -#endif
163.52 - }
163.53 -
163.54 -#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
163.55 - typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
163.56 - template <func##type_var##concept Tp1_> \
163.57 - struct concept_checking_##type_var##concept { }; \
163.58 - typedef concept_checking_##type_var##concept< \
163.59 - BOOST_FPTR ns::concept<type_var>::constraints> \
163.60 - concept_checking_typedef_##type_var##concept
163.61 -
163.62 -#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
163.63 - typedef void (ns::concept <type_var1,type_var2>::* \
163.64 - func##type_var1##type_var2##concept)(); \
163.65 - template <func##type_var1##type_var2##concept Tp1_> \
163.66 - struct concept_checking_##type_var1##type_var2##concept { }; \
163.67 - typedef concept_checking_##type_var1##type_var2##concept< \
163.68 - BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
163.69 - concept_checking_typedef_##type_var1##type_var2##concept
163.70 -
163.71 -#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
163.72 - typedef void (ns::concept <tv1,tv2,tv3>::* \
163.73 - func##tv1##tv2##tv3##concept)(); \
163.74 - template <func##tv1##tv2##tv3##concept Tp1_> \
163.75 - struct concept_checking_##tv1##tv2##tv3##concept { }; \
163.76 - typedef concept_checking_##tv1##tv2##tv3##concept< \
163.77 - BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
163.78 - concept_checking_typedef_##tv1##tv2##tv3##concept
163.79 -
163.80 -#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
163.81 - typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
163.82 - func##tv1##tv2##tv3##tv4##concept)(); \
163.83 - template <func##tv1##tv2##tv3##tv4##concept Tp1_> \
163.84 - struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
163.85 - typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
163.86 - BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
163.87 - concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
163.88 -
163.89 -
163.90 -} // namespace lemon
163.91 -
163.92 -#endif // LEMON_BOOST_CONCEPT_CHECKS_HPP
164.1 --- a/src/lemon/config.h.in Sat May 21 21:04:57 2005 +0000
164.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
164.3 @@ -1,5 +0,0 @@
164.4 -/* Define to 1 if you have CPLEX. */
164.5 -#undef HAVE_CPLEX
164.6 -
164.7 -/* Define to 1 if you have GLPK. */
164.8 -#undef HAVE_GLPK
165.1 --- a/src/lemon/dfs.h Sat May 21 21:04:57 2005 +0000
165.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
165.3 @@ -1,1136 +0,0 @@
165.4 -/* -*- C++ -*-
165.5 - * src/lemon/dfs.h - Part of LEMON, a generic C++ optimization library
165.6 - *
165.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
165.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
165.9 - *
165.10 - * Permission to use, modify and distribute this software is granted
165.11 - * provided that this copyright notice appears in all copies. For
165.12 - * precise terms see the accompanying LICENSE file.
165.13 - *
165.14 - * This software is provided "AS IS" with no warranty of any kind,
165.15 - * express or implied, and with no claim as to its suitability for any
165.16 - * purpose.
165.17 - *
165.18 - */
165.19 -
165.20 -#ifndef LEMON_DFS_H
165.21 -#define LEMON_DFS_H
165.22 -
165.23 -///\ingroup flowalgs
165.24 -///\file
165.25 -///\brief Dfs algorithm.
165.26 -
165.27 -#include <lemon/list_graph.h>
165.28 -#include <lemon/graph_utils.h>
165.29 -#include <lemon/invalid.h>
165.30 -#include <lemon/error.h>
165.31 -#include <lemon/maps.h>
165.32 -
165.33 -namespace lemon {
165.34 -
165.35 -
165.36 -
165.37 - ///Default traits class of Dfs class.
165.38 -
165.39 - ///Default traits class of Dfs class.
165.40 - ///\param GR Graph type.
165.41 - template<class GR>
165.42 - struct DfsDefaultTraits
165.43 - {
165.44 - ///The graph type the algorithm runs on.
165.45 - typedef GR Graph;
165.46 - ///\brief The type of the map that stores the last
165.47 - ///edges of the %DFS paths.
165.48 - ///
165.49 - ///The type of the map that stores the last
165.50 - ///edges of the %DFS paths.
165.51 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.52 - ///
165.53 - typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
165.54 - ///Instantiates a PredMap.
165.55 -
165.56 - ///This function instantiates a \ref PredMap.
165.57 - ///\param G is the graph, to which we would like to define the PredMap.
165.58 - ///\todo The graph alone may be insufficient to initialize
165.59 - static PredMap *createPredMap(const GR &G)
165.60 - {
165.61 - return new PredMap(G);
165.62 - }
165.63 -// ///\brief The type of the map that stores the last but one
165.64 -// ///nodes of the %DFS paths.
165.65 -// ///
165.66 -// ///The type of the map that stores the last but one
165.67 -// ///nodes of the %DFS paths.
165.68 -// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.69 -// ///
165.70 -// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
165.71 -// ///Instantiates a PredNodeMap.
165.72 -
165.73 -// ///This function instantiates a \ref PredNodeMap.
165.74 -// ///\param G is the graph, to which
165.75 -// ///we would like to define the \ref PredNodeMap
165.76 -// static PredNodeMap *createPredNodeMap(const GR &G)
165.77 -// {
165.78 -// return new PredNodeMap();
165.79 -// }
165.80 -
165.81 - ///The type of the map that indicates which nodes are processed.
165.82 -
165.83 - ///The type of the map that indicates which nodes are processed.
165.84 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.85 - ///\todo named parameter to set this type, function to read and write.
165.86 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
165.87 - ///Instantiates a ProcessedMap.
165.88 -
165.89 - ///This function instantiates a \ref ProcessedMap.
165.90 - ///\param G is the graph, to which
165.91 - ///we would like to define the \ref ProcessedMap
165.92 - static ProcessedMap *createProcessedMap(const GR &)
165.93 - {
165.94 - return new ProcessedMap();
165.95 - }
165.96 - ///The type of the map that indicates which nodes are reached.
165.97 -
165.98 - ///The type of the map that indicates which nodes are reached.
165.99 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.100 - ///\todo named parameter to set this type, function to read and write.
165.101 - typedef typename Graph::template NodeMap<bool> ReachedMap;
165.102 - ///Instantiates a ReachedMap.
165.103 -
165.104 - ///This function instantiates a \ref ReachedMap.
165.105 - ///\param G is the graph, to which
165.106 - ///we would like to define the \ref ReachedMap.
165.107 - static ReachedMap *createReachedMap(const GR &G)
165.108 - {
165.109 - return new ReachedMap(G);
165.110 - }
165.111 - ///The type of the map that stores the dists of the nodes.
165.112 -
165.113 - ///The type of the map that stores the dists of the nodes.
165.114 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.115 - ///
165.116 - typedef typename Graph::template NodeMap<int> DistMap;
165.117 - ///Instantiates a DistMap.
165.118 -
165.119 - ///This function instantiates a \ref DistMap.
165.120 - ///\param G is the graph, to which we would like to define the \ref DistMap
165.121 - static DistMap *createDistMap(const GR &G)
165.122 - {
165.123 - return new DistMap(G);
165.124 - }
165.125 - };
165.126 -
165.127 - ///%DFS algorithm class.
165.128 -
165.129 - ///\ingroup flowalgs
165.130 - ///This class provides an efficient implementation of the %DFS algorithm.
165.131 - ///
165.132 - ///\param GR The graph type the algorithm runs on. The default value is
165.133 - ///\ref ListGraph. The value of GR is not used directly by Dfs, it
165.134 - ///is only passed to \ref DfsDefaultTraits.
165.135 - ///\param TR Traits class to set various data types used by the algorithm.
165.136 - ///The default traits class is
165.137 - ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
165.138 - ///See \ref DfsDefaultTraits for the documentation of
165.139 - ///a Dfs traits class.
165.140 - ///
165.141 - ///\author Jacint Szabo and Alpar Juttner
165.142 - ///\todo A compare object would be nice.
165.143 -
165.144 -#ifdef DOXYGEN
165.145 - template <typename GR,
165.146 - typename TR>
165.147 -#else
165.148 - template <typename GR=ListGraph,
165.149 - typename TR=DfsDefaultTraits<GR> >
165.150 -#endif
165.151 - class Dfs {
165.152 - public:
165.153 - /**
165.154 - * \brief \ref Exception for uninitialized parameters.
165.155 - *
165.156 - * This error represents problems in the initialization
165.157 - * of the parameters of the algorithms.
165.158 - */
165.159 - class UninitializedParameter : public lemon::UninitializedParameter {
165.160 - public:
165.161 - virtual const char* exceptionName() const {
165.162 - return "lemon::Dfs::UninitializedParameter";
165.163 - }
165.164 - };
165.165 -
165.166 - typedef TR Traits;
165.167 - ///The type of the underlying graph.
165.168 - typedef typename TR::Graph Graph;
165.169 - ///\e
165.170 - typedef typename Graph::Node Node;
165.171 - ///\e
165.172 - typedef typename Graph::NodeIt NodeIt;
165.173 - ///\e
165.174 - typedef typename Graph::Edge Edge;
165.175 - ///\e
165.176 - typedef typename Graph::OutEdgeIt OutEdgeIt;
165.177 -
165.178 - ///\brief The type of the map that stores the last
165.179 - ///edges of the %DFS paths.
165.180 - typedef typename TR::PredMap PredMap;
165.181 -// ///\brief The type of the map that stores the last but one
165.182 -// ///nodes of the %DFS paths.
165.183 -// typedef typename TR::PredNodeMap PredNodeMap;
165.184 - ///The type of the map indicating which nodes are reached.
165.185 - typedef typename TR::ReachedMap ReachedMap;
165.186 - ///The type of the map indicating which nodes are processed.
165.187 - typedef typename TR::ProcessedMap ProcessedMap;
165.188 - ///The type of the map that stores the dists of the nodes.
165.189 - typedef typename TR::DistMap DistMap;
165.190 - private:
165.191 - /// Pointer to the underlying graph.
165.192 - const Graph *G;
165.193 - ///Pointer to the map of predecessors edges.
165.194 - PredMap *_pred;
165.195 - ///Indicates if \ref _pred is locally allocated (\c true) or not.
165.196 - bool local_pred;
165.197 -// ///Pointer to the map of predecessors nodes.
165.198 -// PredNodeMap *_predNode;
165.199 -// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
165.200 -// bool local_predNode;
165.201 - ///Pointer to the map of distances.
165.202 - DistMap *_dist;
165.203 - ///Indicates if \ref _dist is locally allocated (\c true) or not.
165.204 - bool local_dist;
165.205 - ///Pointer to the map of reached status of the nodes.
165.206 - ReachedMap *_reached;
165.207 - ///Indicates if \ref _reached is locally allocated (\c true) or not.
165.208 - bool local_reached;
165.209 - ///Pointer to the map of processed status of the nodes.
165.210 - ProcessedMap *_processed;
165.211 - ///Indicates if \ref _processed is locally allocated (\c true) or not.
165.212 - bool local_processed;
165.213 -
165.214 - std::vector<typename Graph::OutEdgeIt> _stack;
165.215 - int _stack_head;
165.216 -// ///The source node of the last execution.
165.217 -// Node source;
165.218 -
165.219 - ///Creates the maps if necessary.
165.220 -
165.221 - ///\todo Error if \c G are \c NULL.
165.222 - ///\todo Better memory allocation (instead of new).
165.223 - void create_maps()
165.224 - {
165.225 - if(!_pred) {
165.226 - local_pred = true;
165.227 - _pred = Traits::createPredMap(*G);
165.228 - }
165.229 -// if(!_predNode) {
165.230 -// local_predNode = true;
165.231 -// _predNode = Traits::createPredNodeMap(*G);
165.232 -// }
165.233 - if(!_dist) {
165.234 - local_dist = true;
165.235 - _dist = Traits::createDistMap(*G);
165.236 - }
165.237 - if(!_reached) {
165.238 - local_reached = true;
165.239 - _reached = Traits::createReachedMap(*G);
165.240 - }
165.241 - if(!_processed) {
165.242 - local_processed = true;
165.243 - _processed = Traits::createProcessedMap(*G);
165.244 - }
165.245 - }
165.246 -
165.247 - public :
165.248 -
165.249 - ///\name Named template parameters
165.250 -
165.251 - ///@{
165.252 -
165.253 - template <class T>
165.254 - struct DefPredMapTraits : public Traits {
165.255 - typedef T PredMap;
165.256 - static PredMap *createPredMap(const Graph &G)
165.257 - {
165.258 - throw UninitializedParameter();
165.259 - }
165.260 - };
165.261 - ///\ref named-templ-param "Named parameter" for setting PredMap type
165.262 -
165.263 - ///\ref named-templ-param "Named parameter" for setting PredMap type
165.264 - ///
165.265 - template <class T>
165.266 - class DefPredMap : public Dfs< Graph,
165.267 - DefPredMapTraits<T> > { };
165.268 -
165.269 -// template <class T>
165.270 -// struct DefPredNodeMapTraits : public Traits {
165.271 -// typedef T PredNodeMap;
165.272 -// static PredNodeMap *createPredNodeMap(const Graph &G)
165.273 -// {
165.274 -// throw UninitializedParameter();
165.275 -// }
165.276 -// };
165.277 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
165.278 -
165.279 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
165.280 -// ///
165.281 -// template <class T>
165.282 -// class DefPredNodeMap : public Dfs< Graph,
165.283 -// LengthMap,
165.284 -// DefPredNodeMapTraits<T> > { };
165.285 -
165.286 - template <class T>
165.287 - struct DefDistMapTraits : public Traits {
165.288 - typedef T DistMap;
165.289 - static DistMap *createDistMap(const Graph &G)
165.290 - {
165.291 - throw UninitializedParameter();
165.292 - }
165.293 - };
165.294 - ///\ref named-templ-param "Named parameter" for setting DistMap type
165.295 -
165.296 - ///\ref named-templ-param "Named parameter" for setting DistMap type
165.297 - ///
165.298 - template <class T>
165.299 - class DefDistMap : public Dfs< Graph,
165.300 - DefDistMapTraits<T> > { };
165.301 -
165.302 - template <class T>
165.303 - struct DefReachedMapTraits : public Traits {
165.304 - typedef T ReachedMap;
165.305 - static ReachedMap *createReachedMap(const Graph &G)
165.306 - {
165.307 - throw UninitializedParameter();
165.308 - }
165.309 - };
165.310 - ///\ref named-templ-param "Named parameter" for setting ReachedMap type
165.311 -
165.312 - ///\ref named-templ-param "Named parameter" for setting ReachedMap type
165.313 - ///
165.314 - template <class T>
165.315 - class DefReachedMap : public Dfs< Graph,
165.316 - DefReachedMapTraits<T> > { };
165.317 -
165.318 - struct DefGraphReachedMapTraits : public Traits {
165.319 - typedef typename Graph::template NodeMap<bool> ReachedMap;
165.320 - static ReachedMap *createReachedMap(const Graph &G)
165.321 - {
165.322 - return new ReachedMap(G);
165.323 - }
165.324 - };
165.325 - template <class T>
165.326 - struct DefProcessedMapTraits : public Traits {
165.327 - typedef T ProcessedMap;
165.328 - static ProcessedMap *createProcessedMap(const Graph &G)
165.329 - {
165.330 - throw UninitializedParameter();
165.331 - }
165.332 - };
165.333 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
165.334 -
165.335 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
165.336 - ///
165.337 - template <class T>
165.338 - class DefProcessedMap : public Dfs< Graph,
165.339 - DefProcessedMapTraits<T> > { };
165.340 -
165.341 - struct DefGraphProcessedMapTraits : public Traits {
165.342 - typedef typename Graph::template NodeMap<bool> ProcessedMap;
165.343 - static ProcessedMap *createProcessedMap(const Graph &G)
165.344 - {
165.345 - return new ProcessedMap(G);
165.346 - }
165.347 - };
165.348 - ///\brief \ref named-templ-param "Named parameter"
165.349 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
165.350 - ///
165.351 - ///\ref named-templ-param "Named parameter"
165.352 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
165.353 - ///If you don't set it explicitely, it will be automatically allocated.
165.354 - template <class T>
165.355 - class DefProcessedMapToBeDefaultMap :
165.356 - public Dfs< Graph,
165.357 - DefGraphProcessedMapTraits> { };
165.358 -
165.359 - ///@}
165.360 -
165.361 - public:
165.362 -
165.363 - ///Constructor.
165.364 -
165.365 - ///\param _G the graph the algorithm will run on.
165.366 - ///
165.367 - Dfs(const Graph& _G) :
165.368 - G(&_G),
165.369 - _pred(NULL), local_pred(false),
165.370 -// _predNode(NULL), local_predNode(false),
165.371 - _dist(NULL), local_dist(false),
165.372 - _reached(NULL), local_reached(false),
165.373 - _processed(NULL), local_processed(false)
165.374 - { }
165.375 -
165.376 - ///Destructor.
165.377 - ~Dfs()
165.378 - {
165.379 - if(local_pred) delete _pred;
165.380 -// if(local_predNode) delete _predNode;
165.381 - if(local_dist) delete _dist;
165.382 - if(local_reached) delete _reached;
165.383 - if(local_processed) delete _processed;
165.384 - }
165.385 -
165.386 - ///Sets the map storing the predecessor edges.
165.387 -
165.388 - ///Sets the map storing the predecessor edges.
165.389 - ///If you don't use this function before calling \ref run(),
165.390 - ///it will allocate one. The destuctor deallocates this
165.391 - ///automatically allocated map, of course.
165.392 - ///\return <tt> (*this) </tt>
165.393 - Dfs &predMap(PredMap &m)
165.394 - {
165.395 - if(local_pred) {
165.396 - delete _pred;
165.397 - local_pred=false;
165.398 - }
165.399 - _pred = &m;
165.400 - return *this;
165.401 - }
165.402 -
165.403 -// ///Sets the map storing the predecessor nodes.
165.404 -
165.405 -// ///Sets the map storing the predecessor nodes.
165.406 -// ///If you don't use this function before calling \ref run(),
165.407 -// ///it will allocate one. The destuctor deallocates this
165.408 -// ///automatically allocated map, of course.
165.409 -// ///\return <tt> (*this) </tt>
165.410 -// Dfs &predNodeMap(PredNodeMap &m)
165.411 -// {
165.412 -// if(local_predNode) {
165.413 -// delete _predNode;
165.414 -// local_predNode=false;
165.415 -// }
165.416 -// _predNode = &m;
165.417 -// return *this;
165.418 -// }
165.419 -
165.420 - ///Sets the map storing the distances calculated by the algorithm.
165.421 -
165.422 - ///Sets the map storing the distances calculated by the algorithm.
165.423 - ///If you don't use this function before calling \ref run(),
165.424 - ///it will allocate one. The destuctor deallocates this
165.425 - ///automatically allocated map, of course.
165.426 - ///\return <tt> (*this) </tt>
165.427 - Dfs &distMap(DistMap &m)
165.428 - {
165.429 - if(local_dist) {
165.430 - delete _dist;
165.431 - local_dist=false;
165.432 - }
165.433 - _dist = &m;
165.434 - return *this;
165.435 - }
165.436 -
165.437 - ///Sets the map indicating if a node is reached.
165.438 -
165.439 - ///Sets the map indicating if a node is reached.
165.440 - ///If you don't use this function before calling \ref run(),
165.441 - ///it will allocate one. The destuctor deallocates this
165.442 - ///automatically allocated map, of course.
165.443 - ///\return <tt> (*this) </tt>
165.444 - Dfs &reachedMap(ReachedMap &m)
165.445 - {
165.446 - if(local_reached) {
165.447 - delete _reached;
165.448 - local_reached=false;
165.449 - }
165.450 - _reached = &m;
165.451 - return *this;
165.452 - }
165.453 -
165.454 - ///Sets the map indicating if a node is processed.
165.455 -
165.456 - ///Sets the map indicating if a node is processed.
165.457 - ///If you don't use this function before calling \ref run(),
165.458 - ///it will allocate one. The destuctor deallocates this
165.459 - ///automatically allocated map, of course.
165.460 - ///\return <tt> (*this) </tt>
165.461 - Dfs &processedMap(ProcessedMap &m)
165.462 - {
165.463 - if(local_processed) {
165.464 - delete _processed;
165.465 - local_processed=false;
165.466 - }
165.467 - _processed = &m;
165.468 - return *this;
165.469 - }
165.470 -
165.471 - public:
165.472 - ///\name Execution control
165.473 - ///The simplest way to execute the algorithm is to use
165.474 - ///one of the member functions called \c run(...).
165.475 - ///\n
165.476 - ///If you need more control on the execution,
165.477 - ///first you must call \ref init(), then you can add several source nodes
165.478 - ///with \ref addSource().
165.479 - ///Finally \ref start() will perform the actual path
165.480 - ///computation.
165.481 -
165.482 - ///@{
165.483 -
165.484 - ///Initializes the internal data structures.
165.485 -
165.486 - ///Initializes the internal data structures.
165.487 - ///
165.488 - void init()
165.489 - {
165.490 - create_maps();
165.491 - _stack.resize(countNodes(*G));
165.492 - _stack_head=-1;
165.493 - for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
165.494 - _pred->set(u,INVALID);
165.495 - // _predNode->set(u,INVALID);
165.496 - _reached->set(u,false);
165.497 - _processed->set(u,false);
165.498 - }
165.499 - }
165.500 -
165.501 - ///Adds a new source node.
165.502 -
165.503 - ///Adds a new source node to the set of nodes to be processed.
165.504 - ///
165.505 - ///\bug dist's are wrong (or at least strange) in case of multiple sources.
165.506 - void addSource(Node s)
165.507 - {
165.508 - if(!(*_reached)[s])
165.509 - {
165.510 - _reached->set(s,true);
165.511 - _pred->set(s,INVALID);
165.512 - // _predNode->set(u,INVALID);
165.513 - _stack[++_stack_head]=OutEdgeIt(*G,s);
165.514 - _dist->set(s,_stack_head);
165.515 - }
165.516 - }
165.517 -
165.518 - ///Processes the next node.
165.519 -
165.520 - ///Processes the next node.
165.521 - ///
165.522 - ///\warning The stack must not be empty!
165.523 - void processNextEdge()
165.524 - {
165.525 - Node m;
165.526 - Edge e=_stack[_stack_head];
165.527 - if(!(*_reached)[m=G->target(e)]) {
165.528 - _pred->set(m,e);
165.529 - _reached->set(m,true);
165.530 - // _pred_node->set(m,G->source(e));
165.531 - ++_stack_head;
165.532 - _stack[_stack_head] = OutEdgeIt(*G, m);
165.533 - _dist->set(m,_stack_head);
165.534 - }
165.535 - else {
165.536 - Node n;
165.537 - while(_stack_head>=0 &&
165.538 - (n=G->source(_stack[_stack_head]),
165.539 - ++_stack[_stack_head]==INVALID))
165.540 - {
165.541 - _processed->set(n,true);
165.542 - --_stack_head;
165.543 - }
165.544 - }
165.545 - }
165.546 -
165.547 - ///\brief Returns \c false if there are nodes
165.548 - ///to be processed in the queue
165.549 - ///
165.550 - ///Returns \c false if there are nodes
165.551 - ///to be processed in the queue
165.552 - bool emptyQueue() { return _stack_head<0; }
165.553 - ///Returns the number of the nodes to be processed.
165.554 -
165.555 - ///Returns the number of the nodes to be processed in the queue.
165.556 - ///
165.557 - int queueSize() { return _stack_head+1; }
165.558 -
165.559 - ///Executes the algorithm.
165.560 -
165.561 - ///Executes the algorithm.
165.562 - ///
165.563 - ///\pre init() must be called and at least one node should be added
165.564 - ///with addSource() before using this function.
165.565 - ///
165.566 - ///This method runs the %DFS algorithm from the root node(s)
165.567 - ///in order to
165.568 - ///compute the
165.569 - ///%DFS path to each node. The algorithm computes
165.570 - ///- The %DFS tree.
165.571 - ///- The distance of each node from the root(s).
165.572 - ///
165.573 - void start()
165.574 - {
165.575 - while ( !emptyQueue() ) processNextEdge();
165.576 - }
165.577 -
165.578 - ///Executes the algorithm until \c dest is reached.
165.579 -
165.580 - ///Executes the algorithm until \c dest is reached.
165.581 - ///
165.582 - ///\pre init() must be called and at least one node should be added
165.583 - ///with addSource() before using this function.
165.584 - ///
165.585 - ///This method runs the %DFS algorithm from the root node(s)
165.586 - ///in order to
165.587 - ///compute the
165.588 - ///%DFS path to \c dest. The algorithm computes
165.589 - ///- The %DFS path to \c dest.
165.590 - ///- The distance of \c dest from the root(s).
165.591 - ///
165.592 - void start(Node dest)
165.593 - {
165.594 - while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
165.595 - processNextEdge();
165.596 - }
165.597 -
165.598 - ///Executes the algorithm until a condition is met.
165.599 -
165.600 - ///Executes the algorithm until a condition is met.
165.601 - ///
165.602 - ///\pre init() must be called and at least one node should be added
165.603 - ///with addSource() before using this function.
165.604 - ///
165.605 - ///\param nm must be a bool (or convertible) edge map. The algorithm
165.606 - ///will stop when it reaches a edge \c v with <tt>nm[v]==true</tt>.
165.607 - ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c mn is an edge map,
165.608 - ///not a node map.
165.609 - template<class NM>
165.610 - void start(const NM &nm)
165.611 - {
165.612 - while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
165.613 - }
165.614 -
165.615 - ///Runs %DFS algorithm from node \c s.
165.616 -
165.617 - ///This method runs the %DFS algorithm from a root node \c s
165.618 - ///in order to
165.619 - ///compute the
165.620 - ///%DFS path to each node. The algorithm computes
165.621 - ///- The %DFS tree.
165.622 - ///- The distance of each node from the root.
165.623 - ///
165.624 - ///\note d.run(s) is just a shortcut of the following code.
165.625 - ///\code
165.626 - /// d.init();
165.627 - /// d.addSource(s);
165.628 - /// d.start();
165.629 - ///\endcode
165.630 - void run(Node s) {
165.631 - init();
165.632 - addSource(s);
165.633 - start();
165.634 - }
165.635 -
165.636 - ///Finds the %DFS path between \c s and \c t.
165.637 -
165.638 - ///Finds the %DFS path between \c s and \c t.
165.639 - ///
165.640 - ///\return The length of the %DFS s---t path if there exists one,
165.641 - ///0 otherwise.
165.642 - ///\note Apart from the return value, d.run(s) is
165.643 - ///just a shortcut of the following code.
165.644 - ///\code
165.645 - /// d.init();
165.646 - /// d.addSource(s);
165.647 - /// d.start(t);
165.648 - ///\endcode
165.649 - int run(Node s,Node t) {
165.650 - init();
165.651 - addSource(s);
165.652 - start(t);
165.653 - return reached(t)?_stack_head+1:0;
165.654 - }
165.655 -
165.656 - ///@}
165.657 -
165.658 - ///\name Query Functions
165.659 - ///The result of the %DFS algorithm can be obtained using these
165.660 - ///functions.\n
165.661 - ///Before the use of these functions,
165.662 - ///either run() or start() must be called.
165.663 -
165.664 - ///@{
165.665 -
165.666 - ///Copies the path to \c t on the DFS tree into \c p
165.667 -
165.668 - ///This function copies the path on the DFS tree to \c t into \c p.
165.669 - ///If it \c \t is a source itself or unreachable, then it does not
165.670 - ///alter \c p.
165.671 - ///\todo Is it the right way to handle unreachable nodes?
165.672 - ///\return Returns \c true if a path to \c t was actually copied to \c p,
165.673 - ///\c false otherwise.
165.674 - ///\sa DirPath
165.675 - template<class P>
165.676 - bool getPath(P &p,Node t)
165.677 - {
165.678 - if(reached(t)) {
165.679 - p.clear();
165.680 - typename P::Builder b(p);
165.681 - for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
165.682 - b.pushFront(pred(t));
165.683 - b.commit();
165.684 - return true;
165.685 - }
165.686 - return false;
165.687 - }
165.688 -
165.689 - ///The distance of a node from the root(s).
165.690 -
165.691 - ///Returns the distance of a node from the root(s).
165.692 - ///\pre \ref run() must be called before using this function.
165.693 - ///\warning If node \c v in unreachable from the root(s) the return value
165.694 - ///of this funcion is undefined.
165.695 - int dist(Node v) const { return (*_dist)[v]; }
165.696 -
165.697 - ///Returns the 'previous edge' of the %DFS tree.
165.698 -
165.699 - ///For a node \c v it returns the 'previous edge'
165.700 - ///of the %DFS path,
165.701 - ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
165.702 - ///v. It is \ref INVALID
165.703 - ///if \c v is unreachable from the root(s) or \c v is a root. The
165.704 - ///%DFS tree used here is equal to the %DFS tree used in
165.705 - ///\ref predNode(Node v).
165.706 - ///\pre Either \ref run() or \ref start() must be called before using
165.707 - ///this function.
165.708 - ///\todo predEdge could be a better name.
165.709 - Edge pred(Node v) const { return (*_pred)[v];}
165.710 -
165.711 - ///Returns the 'previous node' of the %DFS tree.
165.712 -
165.713 - ///For a node \c v it returns the 'previous node'
165.714 - ///of the %DFS tree,
165.715 - ///i.e. it returns the last but one node from a %DFS path from the
165.716 - ///root(a) to \c /v.
165.717 - ///It is INVALID if \c v is unreachable from the root(s) or
165.718 - ///if \c v itself a root.
165.719 - ///The %DFS tree used here is equal to the %DFS
165.720 - ///tree used in \ref pred(Node v).
165.721 - ///\pre Either \ref run() or \ref start() must be called before
165.722 - ///using this function.
165.723 - Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
165.724 - G->source((*_pred)[v]); }
165.725 -
165.726 - ///Returns a reference to the NodeMap of distances.
165.727 -
165.728 - ///Returns a reference to the NodeMap of distances.
165.729 - ///\pre Either \ref run() or \ref init() must
165.730 - ///be called before using this function.
165.731 - const DistMap &distMap() const { return *_dist;}
165.732 -
165.733 - ///Returns a reference to the %DFS edge-tree map.
165.734 -
165.735 - ///Returns a reference to the NodeMap of the edges of the
165.736 - ///%DFS tree.
165.737 - ///\pre Either \ref run() or \ref init()
165.738 - ///must be called before using this function.
165.739 - const PredMap &predMap() const { return *_pred;}
165.740 -
165.741 -// ///Returns a reference to the map of nodes of %DFS paths.
165.742 -
165.743 -// ///Returns a reference to the NodeMap of the last but one nodes of the
165.744 -// ///%DFS tree.
165.745 -// ///\pre \ref run() must be called before using this function.
165.746 -// const PredNodeMap &predNodeMap() const { return *_predNode;}
165.747 -
165.748 - ///Checks if a node is reachable from the root.
165.749 -
165.750 - ///Returns \c true if \c v is reachable from the root.
165.751 - ///\warning The source nodes are inditated as unreached.
165.752 - ///\pre Either \ref run() or \ref start()
165.753 - ///must be called before using this function.
165.754 - ///
165.755 - bool reached(Node v) { return (*_reached)[v]; }
165.756 -
165.757 - ///@}
165.758 - };
165.759 -
165.760 - ///Default traits class of Dfs function.
165.761 -
165.762 - ///Default traits class of Dfs function.
165.763 - ///\param GR Graph type.
165.764 - template<class GR>
165.765 - struct DfsWizardDefaultTraits
165.766 - {
165.767 - ///The graph type the algorithm runs on.
165.768 - typedef GR Graph;
165.769 - ///\brief The type of the map that stores the last
165.770 - ///edges of the %DFS paths.
165.771 - ///
165.772 - ///The type of the map that stores the last
165.773 - ///edges of the %DFS paths.
165.774 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.775 - ///
165.776 - typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
165.777 - ///Instantiates a PredMap.
165.778 -
165.779 - ///This function instantiates a \ref PredMap.
165.780 - ///\param G is the graph, to which we would like to define the PredMap.
165.781 - ///\todo The graph alone may be insufficient to initialize
165.782 - static PredMap *createPredMap(const GR &)
165.783 - {
165.784 - return new PredMap();
165.785 - }
165.786 -// ///\brief The type of the map that stores the last but one
165.787 -// ///nodes of the %DFS paths.
165.788 -// ///
165.789 -// ///The type of the map that stores the last but one
165.790 -// ///nodes of the %DFS paths.
165.791 -// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.792 -// ///
165.793 -// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
165.794 -// ///Instantiates a PredNodeMap.
165.795 -
165.796 -// ///This function instantiates a \ref PredNodeMap.
165.797 -// ///\param G is the graph, to which
165.798 -// ///we would like to define the \ref PredNodeMap
165.799 -// static PredNodeMap *createPredNodeMap(const GR &G)
165.800 -// {
165.801 -// return new PredNodeMap();
165.802 -// }
165.803 -
165.804 - ///The type of the map that indicates which nodes are processed.
165.805 -
165.806 - ///The type of the map that indicates which nodes are processed.
165.807 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.808 - ///\todo named parameter to set this type, function to read and write.
165.809 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
165.810 - ///Instantiates a ProcessedMap.
165.811 -
165.812 - ///This function instantiates a \ref ProcessedMap.
165.813 - ///\param G is the graph, to which
165.814 - ///we would like to define the \ref ProcessedMap
165.815 - static ProcessedMap *createProcessedMap(const GR &)
165.816 - {
165.817 - return new ProcessedMap();
165.818 - }
165.819 - ///The type of the map that indicates which nodes are reached.
165.820 -
165.821 - ///The type of the map that indicates which nodes are reached.
165.822 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.823 - ///\todo named parameter to set this type, function to read and write.
165.824 - typedef typename Graph::template NodeMap<bool> ReachedMap;
165.825 - ///Instantiates a ReachedMap.
165.826 -
165.827 - ///This function instantiates a \ref ReachedMap.
165.828 - ///\param G is the graph, to which
165.829 - ///we would like to define the \ref ReachedMap.
165.830 - static ReachedMap *createReachedMap(const GR &G)
165.831 - {
165.832 - return new ReachedMap(G);
165.833 - }
165.834 - ///The type of the map that stores the dists of the nodes.
165.835 -
165.836 - ///The type of the map that stores the dists of the nodes.
165.837 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
165.838 - ///
165.839 - typedef NullMap<typename Graph::Node,int> DistMap;
165.840 - ///Instantiates a DistMap.
165.841 -
165.842 - ///This function instantiates a \ref DistMap.
165.843 - ///\param G is the graph, to which we would like to define the \ref DistMap
165.844 - static DistMap *createDistMap(const GR &)
165.845 - {
165.846 - return new DistMap();
165.847 - }
165.848 - };
165.849 -
165.850 - /// Default traits used by \ref DfsWizard
165.851 -
165.852 - /// To make it easier to use Dfs algorithm
165.853 - ///we have created a wizard class.
165.854 - /// This \ref DfsWizard class needs default traits,
165.855 - ///as well as the \ref Dfs class.
165.856 - /// The \ref DfsWizardBase is a class to be the default traits of the
165.857 - /// \ref DfsWizard class.
165.858 - template<class GR>
165.859 - class DfsWizardBase : public DfsWizardDefaultTraits<GR>
165.860 - {
165.861 -
165.862 - typedef DfsWizardDefaultTraits<GR> Base;
165.863 - protected:
165.864 - /// Type of the nodes in the graph.
165.865 - typedef typename Base::Graph::Node Node;
165.866 -
165.867 - /// Pointer to the underlying graph.
165.868 - void *_g;
165.869 - ///Pointer to the map of reached nodes.
165.870 - void *_reached;
165.871 - ///Pointer to the map of processed nodes.
165.872 - void *_processed;
165.873 - ///Pointer to the map of predecessors edges.
165.874 - void *_pred;
165.875 -// ///Pointer to the map of predecessors nodes.
165.876 -// void *_predNode;
165.877 - ///Pointer to the map of distances.
165.878 - void *_dist;
165.879 - ///Pointer to the source node.
165.880 - Node _source;
165.881 -
165.882 - public:
165.883 - /// Constructor.
165.884 -
165.885 - /// This constructor does not require parameters, therefore it initiates
165.886 - /// all of the attributes to default values (0, INVALID).
165.887 - DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
165.888 -// _predNode(0),
165.889 - _dist(0), _source(INVALID) {}
165.890 -
165.891 - /// Constructor.
165.892 -
165.893 - /// This constructor requires some parameters,
165.894 - /// listed in the parameters list.
165.895 - /// Others are initiated to 0.
165.896 - /// \param g is the initial value of \ref _g
165.897 - /// \param s is the initial value of \ref _source
165.898 - DfsWizardBase(const GR &g, Node s=INVALID) :
165.899 - _g((void *)&g), _reached(0), _processed(0), _pred(0),
165.900 -// _predNode(0),
165.901 - _dist(0), _source(s) {}
165.902 -
165.903 - };
165.904 -
165.905 - /// A class to make the usage of Dfs algorithm easier
165.906 -
165.907 - /// This class is created to make it easier to use Dfs algorithm.
165.908 - /// It uses the functions and features of the plain \ref Dfs,
165.909 - /// but it is much simpler to use it.
165.910 - ///
165.911 - /// Simplicity means that the way to change the types defined
165.912 - /// in the traits class is based on functions that returns the new class
165.913 - /// and not on templatable built-in classes.
165.914 - /// When using the plain \ref Dfs
165.915 - /// the new class with the modified type comes from
165.916 - /// the original class by using the ::
165.917 - /// operator. In the case of \ref DfsWizard only
165.918 - /// a function have to be called and it will
165.919 - /// return the needed class.
165.920 - ///
165.921 - /// It does not have own \ref run method. When its \ref run method is called
165.922 - /// it initiates a plain \ref Dfs class, and calls the \ref Dfs::run
165.923 - /// method of it.
165.924 - template<class TR>
165.925 - class DfsWizard : public TR
165.926 - {
165.927 - typedef TR Base;
165.928 -
165.929 - ///The type of the underlying graph.
165.930 - typedef typename TR::Graph Graph;
165.931 - //\e
165.932 - typedef typename Graph::Node Node;
165.933 - //\e
165.934 - typedef typename Graph::NodeIt NodeIt;
165.935 - //\e
165.936 - typedef typename Graph::Edge Edge;
165.937 - //\e
165.938 - typedef typename Graph::OutEdgeIt OutEdgeIt;
165.939 -
165.940 - ///\brief The type of the map that stores
165.941 - ///the reached nodes
165.942 - typedef typename TR::ReachedMap ReachedMap;
165.943 - ///\brief The type of the map that stores
165.944 - ///the processed nodes
165.945 - typedef typename TR::ProcessedMap ProcessedMap;
165.946 - ///\brief The type of the map that stores the last
165.947 - ///edges of the %DFS paths.
165.948 - typedef typename TR::PredMap PredMap;
165.949 -// ///\brief The type of the map that stores the last but one
165.950 -// ///nodes of the %DFS paths.
165.951 -// typedef typename TR::PredNodeMap PredNodeMap;
165.952 - ///The type of the map that stores the dists of the nodes.
165.953 - typedef typename TR::DistMap DistMap;
165.954 -
165.955 -public:
165.956 - /// Constructor.
165.957 - DfsWizard() : TR() {}
165.958 -
165.959 - /// Constructor that requires parameters.
165.960 -
165.961 - /// Constructor that requires parameters.
165.962 - /// These parameters will be the default values for the traits class.
165.963 - DfsWizard(const Graph &g, Node s=INVALID) :
165.964 - TR(g,s) {}
165.965 -
165.966 - ///Copy constructor
165.967 - DfsWizard(const TR &b) : TR(b) {}
165.968 -
165.969 - ~DfsWizard() {}
165.970 -
165.971 - ///Runs Dfs algorithm from a given node.
165.972 -
165.973 - ///Runs Dfs algorithm from a given node.
165.974 - ///The node can be given by the \ref source function.
165.975 - void run()
165.976 - {
165.977 - if(Base::_source==INVALID) throw UninitializedParameter();
165.978 - Dfs<Graph,TR> alg(*(Graph*)Base::_g);
165.979 - if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
165.980 - if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
165.981 - if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
165.982 -// if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
165.983 - if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
165.984 - alg.run(Base::_source);
165.985 - }
165.986 -
165.987 - ///Runs Dfs algorithm from the given node.
165.988 -
165.989 - ///Runs Dfs algorithm from the given node.
165.990 - ///\param s is the given source.
165.991 - void run(Node s)
165.992 - {
165.993 - Base::_source=s;
165.994 - run();
165.995 - }
165.996 -
165.997 - template<class T>
165.998 - struct DefPredMapBase : public Base {
165.999 - typedef T PredMap;
165.1000 - static PredMap *createPredMap(const Graph &) { return 0; };
165.1001 - DefPredMapBase(const TR &b) : TR(b) {}
165.1002 - };
165.1003 -
165.1004 - ///\brief \ref named-templ-param "Named parameter"
165.1005 - ///function for setting PredMap type
165.1006 - ///
165.1007 - /// \ref named-templ-param "Named parameter"
165.1008 - ///function for setting PredMap type
165.1009 - ///
165.1010 - template<class T>
165.1011 - DfsWizard<DefPredMapBase<T> > predMap(const T &t)
165.1012 - {
165.1013 - Base::_pred=(void *)&t;
165.1014 - return DfsWizard<DefPredMapBase<T> >(*this);
165.1015 - }
165.1016 -
165.1017 -
165.1018 - template<class T>
165.1019 - struct DefReachedMapBase : public Base {
165.1020 - typedef T ReachedMap;
165.1021 - static ReachedMap *createReachedMap(const Graph &) { return 0; };
165.1022 - DefReachedMapBase(const TR &b) : TR(b) {}
165.1023 - };
165.1024 -
165.1025 - ///\brief \ref named-templ-param "Named parameter"
165.1026 - ///function for setting ReachedMap
165.1027 - ///
165.1028 - /// \ref named-templ-param "Named parameter"
165.1029 - ///function for setting ReachedMap
165.1030 - ///
165.1031 - template<class T>
165.1032 - DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
165.1033 - {
165.1034 - Base::_pred=(void *)&t;
165.1035 - return DfsWizard<DefReachedMapBase<T> >(*this);
165.1036 - }
165.1037 -
165.1038 -
165.1039 - template<class T>
165.1040 - struct DefProcessedMapBase : public Base {
165.1041 - typedef T ProcessedMap;
165.1042 - static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
165.1043 - DefProcessedMapBase(const TR &b) : TR(b) {}
165.1044 - };
165.1045 -
165.1046 - ///\brief \ref named-templ-param "Named parameter"
165.1047 - ///function for setting ProcessedMap
165.1048 - ///
165.1049 - /// \ref named-templ-param "Named parameter"
165.1050 - ///function for setting ProcessedMap
165.1051 - ///
165.1052 - template<class T>
165.1053 - DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
165.1054 - {
165.1055 - Base::_pred=(void *)&t;
165.1056 - return DfsWizard<DefProcessedMapBase<T> >(*this);
165.1057 - }
165.1058 -
165.1059 -
165.1060 -// template<class T>
165.1061 -// struct DefPredNodeMapBase : public Base {
165.1062 -// typedef T PredNodeMap;
165.1063 -// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
165.1064 -// DefPredNodeMapBase(const TR &b) : TR(b) {}
165.1065 -// };
165.1066 -
165.1067 -// ///\brief \ref named-templ-param "Named parameter"
165.1068 -// ///function for setting PredNodeMap type
165.1069 -// ///
165.1070 -// /// \ref named-templ-param "Named parameter"
165.1071 -// ///function for setting PredNodeMap type
165.1072 -// ///
165.1073 -// template<class T>
165.1074 -// DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
165.1075 -// {
165.1076 -// Base::_predNode=(void *)&t;
165.1077 -// return DfsWizard<DefPredNodeMapBase<T> >(*this);
165.1078 -// }
165.1079 -
165.1080 - template<class T>
165.1081 - struct DefDistMapBase : public Base {
165.1082 - typedef T DistMap;
165.1083 - static DistMap *createDistMap(const Graph &) { return 0; };
165.1084 - DefDistMapBase(const TR &b) : TR(b) {}
165.1085 - };
165.1086 -
165.1087 - ///\brief \ref named-templ-param "Named parameter"
165.1088 - ///function for setting DistMap type
165.1089 - ///
165.1090 - /// \ref named-templ-param "Named parameter"
165.1091 - ///function for setting DistMap type
165.1092 - ///
165.1093 - template<class T>
165.1094 - DfsWizard<DefDistMapBase<T> > distMap(const T &t)
165.1095 - {
165.1096 - Base::_dist=(void *)&t;
165.1097 - return DfsWizard<DefDistMapBase<T> >(*this);
165.1098 - }
165.1099 -
165.1100 - /// Sets the source node, from which the Dfs algorithm runs.
165.1101 -
165.1102 - /// Sets the source node, from which the Dfs algorithm runs.
165.1103 - /// \param s is the source node.
165.1104 - DfsWizard<TR> &source(Node s)
165.1105 - {
165.1106 - Base::_source=s;
165.1107 - return *this;
165.1108 - }
165.1109 -
165.1110 - };
165.1111 -
165.1112 - ///Function type interface for Dfs algorithm.
165.1113 -
165.1114 - /// \ingroup flowalgs
165.1115 - ///Function type interface for Dfs algorithm.
165.1116 - ///
165.1117 - ///This function also has several
165.1118 - ///\ref named-templ-func-param "named parameters",
165.1119 - ///they are declared as the members of class \ref DfsWizard.
165.1120 - ///The following
165.1121 - ///example shows how to use these parameters.
165.1122 - ///\code
165.1123 - /// dfs(g,source).predMap(preds).run();
165.1124 - ///\endcode
165.1125 - ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
165.1126 - ///to the end of the parameter list.
165.1127 - ///\sa DfsWizard
165.1128 - ///\sa Dfs
165.1129 - template<class GR>
165.1130 - DfsWizard<DfsWizardBase<GR> >
165.1131 - dfs(const GR &g,typename GR::Node s=INVALID)
165.1132 - {
165.1133 - return DfsWizard<DfsWizardBase<GR> >(g,s);
165.1134 - }
165.1135 -
165.1136 -} //END OF NAMESPACE LEMON
165.1137 -
165.1138 -#endif
165.1139 -
166.1 --- a/src/lemon/dijkstra.h Sat May 21 21:04:57 2005 +0000
166.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
166.3 @@ -1,1074 +0,0 @@
166.4 -/* -*- C++ -*-
166.5 - * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library
166.6 - *
166.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
166.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
166.9 - *
166.10 - * Permission to use, modify and distribute this software is granted
166.11 - * provided that this copyright notice appears in all copies. For
166.12 - * precise terms see the accompanying LICENSE file.
166.13 - *
166.14 - * This software is provided "AS IS" with no warranty of any kind,
166.15 - * express or implied, and with no claim as to its suitability for any
166.16 - * purpose.
166.17 - *
166.18 - */
166.19 -
166.20 -#ifndef LEMON_DIJKSTRA_H
166.21 -#define LEMON_DIJKSTRA_H
166.22 -
166.23 -///\ingroup flowalgs
166.24 -///\file
166.25 -///\brief Dijkstra algorithm.
166.26 -///
166.27 -///\todo getPath() should be implemented! (also for BFS and DFS)
166.28 -
166.29 -#include <lemon/list_graph.h>
166.30 -#include <lemon/bin_heap.h>
166.31 -#include <lemon/invalid.h>
166.32 -#include <lemon/error.h>
166.33 -#include <lemon/maps.h>
166.34 -
166.35 -namespace lemon {
166.36 -
166.37 -
166.38 -
166.39 - ///Default traits class of Dijkstra class.
166.40 -
166.41 - ///Default traits class of Dijkstra class.
166.42 - ///\param GR Graph type.
166.43 - ///\param LM Type of length map.
166.44 - template<class GR, class LM>
166.45 - struct DijkstraDefaultTraits
166.46 - {
166.47 - ///The graph type the algorithm runs on.
166.48 - typedef GR Graph;
166.49 - ///The type of the map that stores the edge lengths.
166.50 -
166.51 - ///The type of the map that stores the edge lengths.
166.52 - ///It must meet the \ref concept::ReadMap "ReadMap" concept.
166.53 - typedef LM LengthMap;
166.54 - //The type of the length of the edges.
166.55 - typedef typename LM::Value Value;
166.56 - ///The heap type used by Dijkstra algorithm.
166.57 -
166.58 - ///The heap type used by Dijkstra algorithm.
166.59 - ///
166.60 - ///\sa BinHeap
166.61 - ///\sa Dijkstra
166.62 - typedef BinHeap<typename Graph::Node,
166.63 - typename LM::Value,
166.64 - typename GR::template NodeMap<int>,
166.65 - std::less<Value> > Heap;
166.66 -
166.67 - ///\brief The type of the map that stores the last
166.68 - ///edges of the shortest paths.
166.69 - ///
166.70 - ///The type of the map that stores the last
166.71 - ///edges of the shortest paths.
166.72 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.73 - ///
166.74 - typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
166.75 - ///Instantiates a PredMap.
166.76 -
166.77 - ///This function instantiates a \ref PredMap.
166.78 - ///\param G is the graph, to which we would like to define the PredMap.
166.79 - ///\todo The graph alone may be insufficient for the initialization
166.80 - static PredMap *createPredMap(const GR &G)
166.81 - {
166.82 - return new PredMap(G);
166.83 - }
166.84 -// ///\brief The type of the map that stores the last but one
166.85 -// ///nodes of the shortest paths.
166.86 -// ///
166.87 -// ///The type of the map that stores the last but one
166.88 -// ///nodes of the shortest paths.
166.89 -// ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.90 -// ///
166.91 -// typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
166.92 -// ///Instantiates a PredNodeMap.
166.93 -
166.94 -// ///This function instantiates a \ref PredNodeMap.
166.95 -// ///\param G is the graph, to which
166.96 -// ///we would like to define the \ref PredNodeMap
166.97 -// static PredNodeMap *createPredNodeMap(const GR &G)
166.98 -// {
166.99 -// return new PredNodeMap();
166.100 -// }
166.101 -
166.102 - ///The type of the map that stores whether a nodes is processed.
166.103 -
166.104 - ///The type of the map that stores whether a nodes is processed.
166.105 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.106 - ///By default it is a NullMap.
166.107 - ///\todo If it is set to a real map,
166.108 - ///Dijkstra::processed() should read this.
166.109 - ///\todo named parameter to set this type, function to read and write.
166.110 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
166.111 - ///Instantiates a ProcessedMap.
166.112 -
166.113 - ///This function instantiates a \ref ProcessedMap.
166.114 - ///\param G is the graph, to which
166.115 - ///we would like to define the \ref ProcessedMap
166.116 - static ProcessedMap *createProcessedMap(const GR &)
166.117 - {
166.118 - return new ProcessedMap();
166.119 - }
166.120 - ///The type of the map that stores the dists of the nodes.
166.121 -
166.122 - ///The type of the map that stores the dists of the nodes.
166.123 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.124 - ///
166.125 - typedef typename Graph::template NodeMap<typename LM::Value> DistMap;
166.126 - ///Instantiates a DistMap.
166.127 -
166.128 - ///This function instantiates a \ref DistMap.
166.129 - ///\param G is the graph, to which we would like to define the \ref DistMap
166.130 - static DistMap *createDistMap(const GR &G)
166.131 - {
166.132 - return new DistMap(G);
166.133 - }
166.134 - };
166.135 -
166.136 - ///%Dijkstra algorithm class.
166.137 -
166.138 - /// \ingroup flowalgs
166.139 - ///This class provides an efficient implementation of %Dijkstra algorithm.
166.140 - ///The edge lengths are passed to the algorithm using a
166.141 - ///\ref concept::ReadMap "ReadMap",
166.142 - ///so it is easy to change it to any kind of length.
166.143 - ///
166.144 - ///The type of the length is determined by the
166.145 - ///\ref concept::ReadMap::Value "Value" of the length map.
166.146 - ///
166.147 - ///It is also possible to change the underlying priority heap.
166.148 - ///
166.149 - ///\param GR The graph type the algorithm runs on. The default value
166.150 - ///is \ref ListGraph. The value of GR is not used directly by
166.151 - ///Dijkstra, it is only passed to \ref DijkstraDefaultTraits.
166.152 - ///\param LM This read-only EdgeMap determines the lengths of the
166.153 - ///edges. It is read once for each edge, so the map may involve in
166.154 - ///relatively time consuming process to compute the edge length if
166.155 - ///it is necessary. The default map type is \ref
166.156 - ///concept::StaticGraph::EdgeMap "Graph::EdgeMap<int>". The value
166.157 - ///of LM is not used directly by Dijkstra, it is only passed to \ref
166.158 - ///DijkstraDefaultTraits. \param TR Traits class to set
166.159 - ///various data types used by the algorithm. The default traits
166.160 - ///class is \ref DijkstraDefaultTraits
166.161 - ///"DijkstraDefaultTraits<GR,LM>". See \ref
166.162 - ///DijkstraDefaultTraits for the documentation of a Dijkstra traits
166.163 - ///class.
166.164 - ///
166.165 - ///\author Jacint Szabo and Alpar Juttner
166.166 - ///\todo A compare object would be nice.
166.167 -
166.168 -#ifdef DOXYGEN
166.169 - template <typename GR,
166.170 - typename LM,
166.171 - typename TR>
166.172 -#else
166.173 - template <typename GR=ListGraph,
166.174 - typename LM=typename GR::template EdgeMap<int>,
166.175 - typename TR=DijkstraDefaultTraits<GR,LM> >
166.176 -#endif
166.177 - class Dijkstra {
166.178 - public:
166.179 - /**
166.180 - * \brief \ref Exception for uninitialized parameters.
166.181 - *
166.182 - * This error represents problems in the initialization
166.183 - * of the parameters of the algorithms.
166.184 - */
166.185 - class UninitializedParameter : public lemon::UninitializedParameter {
166.186 - public:
166.187 - virtual const char* exceptionName() const {
166.188 - return "lemon::Dijkstra::UninitializedParameter";
166.189 - }
166.190 - };
166.191 -
166.192 - typedef TR Traits;
166.193 - ///The type of the underlying graph.
166.194 - typedef typename TR::Graph Graph;
166.195 - ///\e
166.196 - typedef typename Graph::Node Node;
166.197 - ///\e
166.198 - typedef typename Graph::NodeIt NodeIt;
166.199 - ///\e
166.200 - typedef typename Graph::Edge Edge;
166.201 - ///\e
166.202 - typedef typename Graph::OutEdgeIt OutEdgeIt;
166.203 -
166.204 - ///The type of the length of the edges.
166.205 - typedef typename TR::LengthMap::Value Value;
166.206 - ///The type of the map that stores the edge lengths.
166.207 - typedef typename TR::LengthMap LengthMap;
166.208 - ///\brief The type of the map that stores the last
166.209 - ///edges of the shortest paths.
166.210 - typedef typename TR::PredMap PredMap;
166.211 -// ///\brief The type of the map that stores the last but one
166.212 -// ///nodes of the shortest paths.
166.213 -// typedef typename TR::PredNodeMap PredNodeMap;
166.214 - ///The type of the map indicating if a node is processed.
166.215 - typedef typename TR::ProcessedMap ProcessedMap;
166.216 - ///The type of the map that stores the dists of the nodes.
166.217 - typedef typename TR::DistMap DistMap;
166.218 - ///The heap type used by the dijkstra algorithm.
166.219 - typedef typename TR::Heap Heap;
166.220 - private:
166.221 - /// Pointer to the underlying graph.
166.222 - const Graph *G;
166.223 - /// Pointer to the length map
166.224 - const LengthMap *length;
166.225 - ///Pointer to the map of predecessors edges.
166.226 - PredMap *_pred;
166.227 - ///Indicates if \ref _pred is locally allocated (\c true) or not.
166.228 - bool local_pred;
166.229 -// ///Pointer to the map of predecessors nodes.
166.230 -// PredNodeMap *_predNode;
166.231 -// ///Indicates if \ref _predNode is locally allocated (\c true) or not.
166.232 -// bool local_predNode;
166.233 - ///Pointer to the map of distances.
166.234 - DistMap *_dist;
166.235 - ///Indicates if \ref _dist is locally allocated (\c true) or not.
166.236 - bool local_dist;
166.237 - ///Pointer to the map of processed status of the nodes.
166.238 - ProcessedMap *_processed;
166.239 - ///Indicates if \ref _processed is locally allocated (\c true) or not.
166.240 - bool local_processed;
166.241 -
166.242 -// ///The source node of the last execution.
166.243 -// Node source;
166.244 -
166.245 - ///Creates the maps if necessary.
166.246 -
166.247 - ///\todo Error if \c G or are \c NULL. What about \c length?
166.248 - ///\todo Better memory allocation (instead of new).
166.249 - void create_maps()
166.250 - {
166.251 - if(!_pred) {
166.252 - local_pred = true;
166.253 - _pred = Traits::createPredMap(*G);
166.254 - }
166.255 -// if(!_predNode) {
166.256 -// local_predNode = true;
166.257 -// _predNode = Traits::createPredNodeMap(*G);
166.258 -// }
166.259 - if(!_dist) {
166.260 - local_dist = true;
166.261 - _dist = Traits::createDistMap(*G);
166.262 - }
166.263 - if(!_processed) {
166.264 - local_processed = true;
166.265 - _processed = Traits::createProcessedMap(*G);
166.266 - }
166.267 - }
166.268 -
166.269 - public :
166.270 -
166.271 - ///\name Named template parameters
166.272 -
166.273 - ///@{
166.274 -
166.275 - template <class T>
166.276 - struct DefPredMapTraits : public Traits {
166.277 - typedef T PredMap;
166.278 - static PredMap *createPredMap(const Graph &G)
166.279 - {
166.280 - throw UninitializedParameter();
166.281 - }
166.282 - };
166.283 - ///\ref named-templ-param "Named parameter" for setting PredMap type
166.284 -
166.285 - ///\ref named-templ-param "Named parameter" for setting PredMap type
166.286 - ///
166.287 - template <class T>
166.288 - class DefPredMap : public Dijkstra< Graph,
166.289 - LengthMap,
166.290 - DefPredMapTraits<T> > { };
166.291 -
166.292 -// template <class T>
166.293 -// struct DefPredNodeMapTraits : public Traits {
166.294 -// typedef T PredNodeMap;
166.295 -// static PredNodeMap *createPredNodeMap(const Graph &G)
166.296 -// {
166.297 -// throw UninitializedParameter();
166.298 -// }
166.299 -// };
166.300 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
166.301 -
166.302 -// ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
166.303 -// ///
166.304 -// template <class T>
166.305 -// class DefPredNodeMap : public Dijkstra< Graph,
166.306 -// LengthMap,
166.307 -// DefPredNodeMapTraits<T> > { };
166.308 -
166.309 - template <class T>
166.310 - struct DefDistMapTraits : public Traits {
166.311 - typedef T DistMap;
166.312 - static DistMap *createDistMap(const Graph &G)
166.313 - {
166.314 - throw UninitializedParameter();
166.315 - }
166.316 - };
166.317 - ///\ref named-templ-param "Named parameter" for setting DistMap type
166.318 -
166.319 - ///\ref named-templ-param "Named parameter" for setting DistMap type
166.320 - ///
166.321 - template <class T>
166.322 - class DefDistMap : public Dijkstra< Graph,
166.323 - LengthMap,
166.324 - DefDistMapTraits<T> > { };
166.325 -
166.326 - template <class T>
166.327 - struct DefProcessedMapTraits : public Traits {
166.328 - typedef T ProcessedMap;
166.329 - static ProcessedMap *createProcessedMap(const Graph &G)
166.330 - {
166.331 - throw UninitializedParameter();
166.332 - }
166.333 - };
166.334 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
166.335 -
166.336 - ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
166.337 - ///
166.338 - template <class T>
166.339 - class DefProcessedMap : public Dijkstra< Graph,
166.340 - LengthMap,
166.341 - DefProcessedMapTraits<T> > { };
166.342 -
166.343 - struct DefGraphProcessedMapTraits : public Traits {
166.344 - typedef typename Graph::template NodeMap<bool> ProcessedMap;
166.345 - static ProcessedMap *createProcessedMap(const Graph &G)
166.346 - {
166.347 - return new ProcessedMap(G);
166.348 - }
166.349 - };
166.350 - ///\brief \ref named-templ-param "Named parameter"
166.351 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
166.352 - ///
166.353 - ///\ref named-templ-param "Named parameter"
166.354 - ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
166.355 - ///If you don't set it explicitely, it will be automatically allocated.
166.356 - template <class T>
166.357 - class DefProcessedMapToBeDefaultMap :
166.358 - public Dijkstra< Graph,
166.359 - LengthMap,
166.360 - DefGraphProcessedMapTraits> { };
166.361 -
166.362 - ///@}
166.363 -
166.364 -
166.365 - private:
166.366 - typename Graph::template NodeMap<int> _heap_map;
166.367 - Heap _heap;
166.368 - public:
166.369 -
166.370 - ///Constructor.
166.371 -
166.372 - ///\param _G the graph the algorithm will run on.
166.373 - ///\param _length the length map used by the algorithm.
166.374 - Dijkstra(const Graph& _G, const LengthMap& _length) :
166.375 - G(&_G), length(&_length),
166.376 - _pred(NULL), local_pred(false),
166.377 -// _predNode(NULL), local_predNode(false),
166.378 - _dist(NULL), local_dist(false),
166.379 - _processed(NULL), local_processed(false),
166.380 - _heap_map(*G,-1),_heap(_heap_map)
166.381 - { }
166.382 -
166.383 - ///Destructor.
166.384 - ~Dijkstra()
166.385 - {
166.386 - if(local_pred) delete _pred;
166.387 -// if(local_predNode) delete _predNode;
166.388 - if(local_dist) delete _dist;
166.389 - if(local_processed) delete _processed;
166.390 - }
166.391 -
166.392 - ///Sets the length map.
166.393 -
166.394 - ///Sets the length map.
166.395 - ///\return <tt> (*this) </tt>
166.396 - Dijkstra &lengthMap(const LengthMap &m)
166.397 - {
166.398 - length = &m;
166.399 - return *this;
166.400 - }
166.401 -
166.402 - ///Sets the map storing the predecessor edges.
166.403 -
166.404 - ///Sets the map storing the predecessor edges.
166.405 - ///If you don't use this function before calling \ref run(),
166.406 - ///it will allocate one. The destuctor deallocates this
166.407 - ///automatically allocated map, of course.
166.408 - ///\return <tt> (*this) </tt>
166.409 - Dijkstra &predMap(PredMap &m)
166.410 - {
166.411 - if(local_pred) {
166.412 - delete _pred;
166.413 - local_pred=false;
166.414 - }
166.415 - _pred = &m;
166.416 - return *this;
166.417 - }
166.418 -
166.419 -// ///Sets the map storing the predecessor nodes.
166.420 -
166.421 -// ///Sets the map storing the predecessor nodes.
166.422 -// ///If you don't use this function before calling \ref run(),
166.423 -// ///it will allocate one. The destuctor deallocates this
166.424 -// ///automatically allocated map, of course.
166.425 -// ///\return <tt> (*this) </tt>
166.426 -// Dijkstra &predNodeMap(PredNodeMap &m)
166.427 -// {
166.428 -// if(local_predNode) {
166.429 -// delete _predNode;
166.430 -// local_predNode=false;
166.431 -// }
166.432 -// _predNode = &m;
166.433 -// return *this;
166.434 -// }
166.435 -
166.436 - ///Sets the map storing the distances calculated by the algorithm.
166.437 -
166.438 - ///Sets the map storing the distances calculated by the algorithm.
166.439 - ///If you don't use this function before calling \ref run(),
166.440 - ///it will allocate one. The destuctor deallocates this
166.441 - ///automatically allocated map, of course.
166.442 - ///\return <tt> (*this) </tt>
166.443 - Dijkstra &distMap(DistMap &m)
166.444 - {
166.445 - if(local_dist) {
166.446 - delete _dist;
166.447 - local_dist=false;
166.448 - }
166.449 - _dist = &m;
166.450 - return *this;
166.451 - }
166.452 -
166.453 - private:
166.454 - void finalizeNodeData(Node v,Value dst)
166.455 - {
166.456 - _processed->set(v,true);
166.457 - _dist->set(v, dst);
166.458 -// if((*_pred)[v]!=INVALID)
166.459 -// _predNode->set(v,G->source((*_pred)[v])); ///\todo What to do?
166.460 - }
166.461 -
166.462 - public:
166.463 - ///\name Execution control
166.464 - ///The simplest way to execute the algorithm is to use
166.465 - ///one of the member functions called \c run(...).
166.466 - ///\n
166.467 - ///If you need more control on the execution,
166.468 - ///first you must call \ref init(), then you can add several source nodes
166.469 - ///with \ref addSource().
166.470 - ///Finally \ref start() will perform the actual path
166.471 - ///computation.
166.472 -
166.473 - ///@{
166.474 -
166.475 - ///Initializes the internal data structures.
166.476 -
166.477 - ///Initializes the internal data structures.
166.478 - ///
166.479 - ///\todo _heap_map's type could also be in the traits class.
166.480 - ///\todo The heaps should be able to make themselves empty directly.
166.481 - void init()
166.482 - {
166.483 - create_maps();
166.484 - while(!_heap.empty()) _heap.pop();
166.485 - for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
166.486 - _pred->set(u,INVALID);
166.487 -// _predNode->set(u,INVALID);
166.488 - _processed->set(u,false);
166.489 - _heap_map.set(u,Heap::PRE_HEAP);
166.490 - }
166.491 - }
166.492 -
166.493 - ///Adds a new source node.
166.494 -
166.495 - ///Adds a new source node to the priority heap.
166.496 - ///
166.497 - ///The optional second parameter is the initial distance of the node.
166.498 - ///
166.499 - ///It checks if the node has already been added to the heap and
166.500 - ///It is pushed to the heap only if either it was not in the heap
166.501 - ///or the shortest path found till then is longer then \c dst.
166.502 - void addSource(Node s,Value dst=0)
166.503 - {
166.504 -// source = s;
166.505 - if(_heap.state(s) != Heap::IN_HEAP) _heap.push(s,dst);
166.506 - else if(_heap[s]<dst) {
166.507 - _heap.push(s,dst);
166.508 - _pred->set(s,INVALID);
166.509 - }
166.510 - }
166.511 -
166.512 - ///Processes the next node in the priority heap
166.513 -
166.514 - ///Processes the next node in the priority heap.
166.515 - ///
166.516 - ///\warning The priority heap must not be empty!
166.517 - void processNextNode()
166.518 - {
166.519 - Node v=_heap.top();
166.520 - Value oldvalue=_heap[v];
166.521 - _heap.pop();
166.522 - finalizeNodeData(v,oldvalue);
166.523 -
166.524 - for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
166.525 - Node w=G->target(e);
166.526 - switch(_heap.state(w)) {
166.527 - case Heap::PRE_HEAP:
166.528 - _heap.push(w,oldvalue+(*length)[e]);
166.529 - _pred->set(w,e);
166.530 -// _predNode->set(w,v);
166.531 - break;
166.532 - case Heap::IN_HEAP:
166.533 - if ( oldvalue+(*length)[e] < _heap[w] ) {
166.534 - _heap.decrease(w, oldvalue+(*length)[e]);
166.535 - _pred->set(w,e);
166.536 -// _predNode->set(w,v);
166.537 - }
166.538 - break;
166.539 - case Heap::POST_HEAP:
166.540 - break;
166.541 - }
166.542 - }
166.543 - }
166.544 -
166.545 - ///\brief Returns \c false if there are nodes
166.546 - ///to be processed in the priority heap
166.547 - ///
166.548 - ///Returns \c false if there are nodes
166.549 - ///to be processed in the priority heap
166.550 - bool emptyQueue() { return _heap.empty(); }
166.551 - ///Returns the number of the nodes to be processed in the priority heap
166.552 -
166.553 - ///Returns the number of the nodes to be processed in the priority heap
166.554 - ///
166.555 - int queueSize() { return _heap.size(); }
166.556 -
166.557 - ///Executes the algorithm.
166.558 -
166.559 - ///Executes the algorithm.
166.560 - ///
166.561 - ///\pre init() must be called and at least one node should be added
166.562 - ///with addSource() before using this function.
166.563 - ///
166.564 - ///This method runs the %Dijkstra algorithm from the root node(s)
166.565 - ///in order to
166.566 - ///compute the
166.567 - ///shortest path to each node. The algorithm computes
166.568 - ///- The shortest path tree.
166.569 - ///- The distance of each node from the root(s).
166.570 - ///
166.571 - void start()
166.572 - {
166.573 - while ( !_heap.empty() ) processNextNode();
166.574 - }
166.575 -
166.576 - ///Executes the algorithm until \c dest is reached.
166.577 -
166.578 - ///Executes the algorithm until \c dest is reached.
166.579 - ///
166.580 - ///\pre init() must be called and at least one node should be added
166.581 - ///with addSource() before using this function.
166.582 - ///
166.583 - ///This method runs the %Dijkstra algorithm from the root node(s)
166.584 - ///in order to
166.585 - ///compute the
166.586 - ///shortest path to \c dest. The algorithm computes
166.587 - ///- The shortest path to \c dest.
166.588 - ///- The distance of \c dest from the root(s).
166.589 - ///
166.590 - void start(Node dest)
166.591 - {
166.592 - while ( !_heap.empty() && _heap.top()!=dest ) processNextNode();
166.593 - if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
166.594 - }
166.595 -
166.596 - ///Executes the algorithm until a condition is met.
166.597 -
166.598 - ///Executes the algorithm until a condition is met.
166.599 - ///
166.600 - ///\pre init() must be called and at least one node should be added
166.601 - ///with addSource() before using this function.
166.602 - ///
166.603 - ///\param nm must be a bool (or convertible) node map. The algorithm
166.604 - ///will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
166.605 - template<class NodeBoolMap>
166.606 - void start(const NodeBoolMap &nm)
166.607 - {
166.608 - while ( !_heap.empty() && !nm[_heap.top()] ) processNextNode();
166.609 - if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
166.610 - }
166.611 -
166.612 - ///Runs %Dijkstra algorithm from node \c s.
166.613 -
166.614 - ///This method runs the %Dijkstra algorithm from a root node \c s
166.615 - ///in order to
166.616 - ///compute the
166.617 - ///shortest path to each node. The algorithm computes
166.618 - ///- The shortest path tree.
166.619 - ///- The distance of each node from the root.
166.620 - ///
166.621 - ///\note d.run(s) is just a shortcut of the following code.
166.622 - ///\code
166.623 - /// d.init();
166.624 - /// d.addSource(s);
166.625 - /// d.start();
166.626 - ///\endcode
166.627 - void run(Node s) {
166.628 - init();
166.629 - addSource(s);
166.630 - start();
166.631 - }
166.632 -
166.633 - ///Finds the shortest path between \c s and \c t.
166.634 -
166.635 - ///Finds the shortest path between \c s and \c t.
166.636 - ///
166.637 - ///\return The length of the shortest s---t path if there exists one,
166.638 - ///0 otherwise.
166.639 - ///\note Apart from the return value, d.run(s) is
166.640 - ///just a shortcut of the following code.
166.641 - ///\code
166.642 - /// d.init();
166.643 - /// d.addSource(s);
166.644 - /// d.start(t);
166.645 - ///\endcode
166.646 - Value run(Node s,Node t) {
166.647 - init();
166.648 - addSource(s);
166.649 - start(t);
166.650 - return (*_pred)[t]==INVALID?0:(*_dist)[t];
166.651 - }
166.652 -
166.653 - ///@}
166.654 -
166.655 - ///\name Query Functions
166.656 - ///The result of the %Dijkstra algorithm can be obtained using these
166.657 - ///functions.\n
166.658 - ///Before the use of these functions,
166.659 - ///either run() or start() must be called.
166.660 -
166.661 - ///@{
166.662 -
166.663 - ///Copies the shortest path to \c t into \c p
166.664 -
166.665 - ///This function copies the shortest path to \c t into \c p.
166.666 - ///If it \c \t is a source itself or unreachable, then it does not
166.667 - ///alter \c p.
166.668 - ///\todo Is it the right way to handle unreachable nodes?
166.669 - ///\return Returns \c true if a path to \c t was actually copied to \c p,
166.670 - ///\c false otherwise.
166.671 - ///\sa DirPath
166.672 - template<class P>
166.673 - bool getPath(P &p,Node t)
166.674 - {
166.675 - if(reached(t)) {
166.676 - p.clear();
166.677 - typename P::Builder b(p);
166.678 - for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
166.679 - b.pushFront(pred(t));
166.680 - b.commit();
166.681 - return true;
166.682 - }
166.683 - return false;
166.684 - }
166.685 -
166.686 - ///The distance of a node from the root.
166.687 -
166.688 - ///Returns the distance of a node from the root.
166.689 - ///\pre \ref run() must be called before using this function.
166.690 - ///\warning If node \c v in unreachable from the root the return value
166.691 - ///of this funcion is undefined.
166.692 - Value dist(Node v) const { return (*_dist)[v]; }
166.693 -
166.694 - ///Returns the 'previous edge' of the shortest path tree.
166.695 -
166.696 - ///For a node \c v it returns the 'previous edge' of the shortest path tree,
166.697 - ///i.e. it returns the last edge of a shortest path from the root to \c
166.698 - ///v. It is \ref INVALID
166.699 - ///if \c v is unreachable from the root or if \c v=s. The
166.700 - ///shortest path tree used here is equal to the shortest path tree used in
166.701 - ///\ref predNode(Node v). \pre \ref run() must be called before using
166.702 - ///this function.
166.703 - ///\todo predEdge could be a better name.
166.704 - Edge pred(Node v) const { return (*_pred)[v]; }
166.705 -
166.706 - ///Returns the 'previous node' of the shortest path tree.
166.707 -
166.708 - ///For a node \c v it returns the 'previous node' of the shortest path tree,
166.709 - ///i.e. it returns the last but one node from a shortest path from the
166.710 - ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
166.711 - ///\c v=s. The shortest path tree used here is equal to the shortest path
166.712 - ///tree used in \ref pred(Node v). \pre \ref run() must be called before
166.713 - ///using this function.
166.714 - Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
166.715 - G->source((*_pred)[v]); }
166.716 -
166.717 - ///Returns a reference to the NodeMap of distances.
166.718 -
166.719 - ///Returns a reference to the NodeMap of distances. \pre \ref run() must
166.720 - ///be called before using this function.
166.721 - const DistMap &distMap() const { return *_dist;}
166.722 -
166.723 - ///Returns a reference to the shortest path tree map.
166.724 -
166.725 - ///Returns a reference to the NodeMap of the edges of the
166.726 - ///shortest path tree.
166.727 - ///\pre \ref run() must be called before using this function.
166.728 - const PredMap &predMap() const { return *_pred;}
166.729 -
166.730 -// ///Returns a reference to the map of nodes of shortest paths.
166.731 -
166.732 -// ///Returns a reference to the NodeMap of the last but one nodes of the
166.733 -// ///shortest path tree.
166.734 -// ///\pre \ref run() must be called before using this function.
166.735 -// const PredNodeMap &predNodeMap() const { return *_predNode;}
166.736 -
166.737 - ///Checks if a node is reachable from the root.
166.738 -
166.739 - ///Returns \c true if \c v is reachable from the root.
166.740 - ///\warning The source nodes are inditated as unreached.
166.741 - ///\pre \ref run() must be called before using this function.
166.742 - ///
166.743 - bool reached(Node v) { return _heap_map[v]!=Heap::PRE_HEAP; }
166.744 -
166.745 - ///@}
166.746 - };
166.747 -
166.748 -
166.749 -
166.750 -
166.751 -
166.752 - ///Default traits class of Dijkstra function.
166.753 -
166.754 - ///Default traits class of Dijkstra function.
166.755 - ///\param GR Graph type.
166.756 - ///\param LM Type of length map.
166.757 - template<class GR, class LM>
166.758 - struct DijkstraWizardDefaultTraits
166.759 - {
166.760 - ///The graph type the algorithm runs on.
166.761 - typedef GR Graph;
166.762 - ///The type of the map that stores the edge lengths.
166.763 -
166.764 - ///The type of the map that stores the edge lengths.
166.765 - ///It must meet the \ref concept::ReadMap "ReadMap" concept.
166.766 - typedef LM LengthMap;
166.767 - //The type of the length of the edges.
166.768 - typedef typename LM::Value Value;
166.769 - ///The heap type used by Dijkstra algorithm.
166.770 -
166.771 - ///The heap type used by Dijkstra algorithm.
166.772 - ///
166.773 - ///\sa BinHeap
166.774 - ///\sa Dijkstra
166.775 - typedef BinHeap<typename Graph::Node,
166.776 - typename LM::Value,
166.777 - typename GR::template NodeMap<int>,
166.778 - std::less<Value> > Heap;
166.779 -
166.780 - ///\brief The type of the map that stores the last
166.781 - ///edges of the shortest paths.
166.782 - ///
166.783 - ///The type of the map that stores the last
166.784 - ///edges of the shortest paths.
166.785 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.786 - ///
166.787 - typedef NullMap <typename GR::Node,typename GR::Edge> PredMap;
166.788 - ///Instantiates a PredMap.
166.789 -
166.790 - ///This function instantiates a \ref PredMap.
166.791 - ///\param G is the graph, to which we would like to define the PredMap.
166.792 - ///\todo The graph alone may be insufficient for the initialization
166.793 - static PredMap *createPredMap(const GR &)
166.794 - {
166.795 - return new PredMap();
166.796 - }
166.797 - ///The type of the map that stores whether a nodes is processed.
166.798 -
166.799 - ///The type of the map that stores whether a nodes is processed.
166.800 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.801 - ///By default it is a NullMap.
166.802 - ///\todo If it is set to a real map,
166.803 - ///Dijkstra::processed() should read this.
166.804 - ///\todo named parameter to set this type, function to read and write.
166.805 - typedef NullMap<typename Graph::Node,bool> ProcessedMap;
166.806 - ///Instantiates a ProcessedMap.
166.807 -
166.808 - ///This function instantiates a \ref ProcessedMap.
166.809 - ///\param G is the graph, to which
166.810 - ///we would like to define the \ref ProcessedMap
166.811 - static ProcessedMap *createProcessedMap(const GR &)
166.812 - {
166.813 - return new ProcessedMap();
166.814 - }
166.815 - ///The type of the map that stores the dists of the nodes.
166.816 -
166.817 - ///The type of the map that stores the dists of the nodes.
166.818 - ///It must meet the \ref concept::WriteMap "WriteMap" concept.
166.819 - ///
166.820 - typedef NullMap<typename Graph::Node,typename LM::Value> DistMap;
166.821 - ///Instantiates a DistMap.
166.822 -
166.823 - ///This function instantiates a \ref DistMap.
166.824 - ///\param G is the graph, to which we would like to define the \ref DistMap
166.825 - static DistMap *createDistMap(const GR &)
166.826 - {
166.827 - return new DistMap();
166.828 - }
166.829 - };
166.830 -
166.831 - /// Default traits used by \ref DijkstraWizard
166.832 -
166.833 - /// To make it easier to use Dijkstra algorithm
166.834 - ///we have created a wizard class.
166.835 - /// This \ref DijkstraWizard class needs default traits,
166.836 - ///as well as the \ref Dijkstra class.
166.837 - /// The \ref DijkstraWizardBase is a class to be the default traits of the
166.838 - /// \ref DijkstraWizard class.
166.839 - /// \todo More named parameters are required...
166.840 - template<class GR,class LM>
166.841 - class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
166.842 - {
166.843 -
166.844 - typedef DijkstraWizardDefaultTraits<GR,LM> Base;
166.845 - protected:
166.846 - /// Type of the nodes in the graph.
166.847 - typedef typename Base::Graph::Node Node;
166.848 -
166.849 - /// Pointer to the underlying graph.
166.850 - void *_g;
166.851 - /// Pointer to the length map
166.852 - void *_length;
166.853 - ///Pointer to the map of predecessors edges.
166.854 - void *_pred;
166.855 -// ///Pointer to the map of predecessors nodes.
166.856 -// void *_predNode;
166.857 - ///Pointer to the map of distances.
166.858 - void *_dist;
166.859 - ///Pointer to the source node.
166.860 - Node _source;
166.861 -
166.862 - public:
166.863 - /// Constructor.
166.864 -
166.865 - /// This constructor does not require parameters, therefore it initiates
166.866 - /// all of the attributes to default values (0, INVALID).
166.867 - DijkstraWizardBase() : _g(0), _length(0), _pred(0),
166.868 -// _predNode(0),
166.869 - _dist(0), _source(INVALID) {}
166.870 -
166.871 - /// Constructor.
166.872 -
166.873 - /// This constructor requires some parameters,
166.874 - /// listed in the parameters list.
166.875 - /// Others are initiated to 0.
166.876 - /// \param g is the initial value of \ref _g
166.877 - /// \param l is the initial value of \ref _length
166.878 - /// \param s is the initial value of \ref _source
166.879 - DijkstraWizardBase(const GR &g,const LM &l, Node s=INVALID) :
166.880 - _g((void *)&g), _length((void *)&l), _pred(0),
166.881 -// _predNode(0),
166.882 - _dist(0), _source(s) {}
166.883 -
166.884 - };
166.885 -
166.886 - /// A class to make the usage of Dijkstra algorithm easier
166.887 -
166.888 - /// This class is created to make it easier to use Dijkstra algorithm.
166.889 - /// It uses the functions and features of the plain \ref Dijkstra,
166.890 - /// but it is much simpler to use it.
166.891 - ///
166.892 - /// Simplicity means that the way to change the types defined
166.893 - /// in the traits class is based on functions that returns the new class
166.894 - /// and not on templatable built-in classes.
166.895 - /// When using the plain \ref Dijkstra
166.896 - /// the new class with the modified type comes from
166.897 - /// the original class by using the ::
166.898 - /// operator. In the case of \ref DijkstraWizard only
166.899 - /// a function have to be called and it will
166.900 - /// return the needed class.
166.901 - ///
166.902 - /// It does not have own \ref run method. When its \ref run method is called
166.903 - /// it initiates a plain \ref Dijkstra class, and calls the \ref Dijkstra::run
166.904 - /// method of it.
166.905 - template<class TR>
166.906 - class DijkstraWizard : public TR
166.907 - {
166.908 - typedef TR Base;
166.909 -
166.910 - ///The type of the underlying graph.
166.911 - typedef typename TR::Graph Graph;
166.912 - //\e
166.913 - typedef typename Graph::Node Node;
166.914 - //\e
166.915 - typedef typename Graph::NodeIt NodeIt;
166.916 - //\e
166.917 - typedef typename Graph::Edge Edge;
166.918 - //\e
166.919 - typedef typename Graph::OutEdgeIt OutEdgeIt;
166.920 -
166.921 - ///The type of the map that stores the edge lengths.
166.922 - typedef typename TR::LengthMap LengthMap;
166.923 - ///The type of the length of the edges.
166.924 - typedef typename LengthMap::Value Value;
166.925 - ///\brief The type of the map that stores the last
166.926 - ///edges of the shortest paths.
166.927 - typedef typename TR::PredMap PredMap;
166.928 -// ///\brief The type of the map that stores the last but one
166.929 -// ///nodes of the shortest paths.
166.930 -// typedef typename TR::PredNodeMap PredNodeMap;
166.931 - ///The type of the map that stores the dists of the nodes.
166.932 - typedef typename TR::DistMap DistMap;
166.933 -
166.934 - ///The heap type used by the dijkstra algorithm.
166.935 - typedef typename TR::Heap Heap;
166.936 -public:
166.937 - /// Constructor.
166.938 - DijkstraWizard() : TR() {}
166.939 -
166.940 - /// Constructor that requires parameters.
166.941 -
166.942 - /// Constructor that requires parameters.
166.943 - /// These parameters will be the default values for the traits class.
166.944 - DijkstraWizard(const Graph &g,const LengthMap &l, Node s=INVALID) :
166.945 - TR(g,l,s) {}
166.946 -
166.947 - ///Copy constructor
166.948 - DijkstraWizard(const TR &b) : TR(b) {}
166.949 -
166.950 - ~DijkstraWizard() {}
166.951 -
166.952 - ///Runs Dijkstra algorithm from a given node.
166.953 -
166.954 - ///Runs Dijkstra algorithm from a given node.
166.955 - ///The node can be given by the \ref source function.
166.956 - void run()
166.957 - {
166.958 - if(Base::_source==INVALID) throw UninitializedParameter();
166.959 - Dijkstra<Graph,LengthMap,TR>
166.960 - dij(*(Graph*)Base::_g,*(LengthMap*)Base::_length);
166.961 - if(Base::_pred) dij.predMap(*(PredMap*)Base::_pred);
166.962 -// if(Base::_predNode) Dij.predNodeMap(*(PredNodeMap*)Base::_predNode);
166.963 - if(Base::_dist) dij.distMap(*(DistMap*)Base::_dist);
166.964 - dij.run(Base::_source);
166.965 - }
166.966 -
166.967 - ///Runs Dijkstra algorithm from the given node.
166.968 -
166.969 - ///Runs Dijkstra algorithm from the given node.
166.970 - ///\param s is the given source.
166.971 - void run(Node s)
166.972 - {
166.973 - Base::_source=s;
166.974 - run();
166.975 - }
166.976 -
166.977 - template<class T>
166.978 - struct DefPredMapBase : public Base {
166.979 - typedef T PredMap;
166.980 - static PredMap *createPredMap(const Graph &) { return 0; };
166.981 - DefPredMapBase(const TR &b) : TR(b) {}
166.982 - };
166.983 -
166.984 - ///\brief \ref named-templ-param "Named parameter"
166.985 - ///function for setting PredMap type
166.986 - ///
166.987 - /// \ref named-templ-param "Named parameter"
166.988 - ///function for setting PredMap type
166.989 - ///
166.990 - template<class T>
166.991 - DijkstraWizard<DefPredMapBase<T> > predMap(const T &t)
166.992 - {
166.993 - Base::_pred=(void *)&t;
166.994 - return DijkstraWizard<DefPredMapBase<T> >(*this);
166.995 - }
166.996 -
166.997 -
166.998 -// template<class T>
166.999 -// struct DefPredNodeMapBase : public Base {
166.1000 -// typedef T PredNodeMap;
166.1001 -// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
166.1002 -// DefPredNodeMapBase(const TR &b) : TR(b) {}
166.1003 -// };
166.1004 -
166.1005 -// ///\brief \ref named-templ-param "Named parameter"
166.1006 -// ///function for setting PredNodeMap type
166.1007 -// ///
166.1008 -// /// \ref named-templ-param "Named parameter"
166.1009 -// ///function for setting PredNodeMap type
166.1010 -// ///
166.1011 -// template<class T>
166.1012 -// DijkstraWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
166.1013 -// {
166.1014 -// Base::_predNode=(void *)&t;
166.1015 -// return DijkstraWizard<DefPredNodeMapBase<T> >(*this);
166.1016 -// }
166.1017 -
166.1018 - template<class T>
166.1019 - struct DefDistMapBase : public Base {
166.1020 - typedef T DistMap;
166.1021 - static DistMap *createDistMap(const Graph &) { return 0; };
166.1022 - DefDistMapBase(const TR &b) : TR(b) {}
166.1023 - };
166.1024 -
166.1025 - ///\brief \ref named-templ-param "Named parameter"
166.1026 - ///function for setting DistMap type
166.1027 - ///
166.1028 - /// \ref named-templ-param "Named parameter"
166.1029 - ///function for setting DistMap type
166.1030 - ///
166.1031 - template<class T>
166.1032 - DijkstraWizard<DefDistMapBase<T> > distMap(const T &t)
166.1033 - {
166.1034 - Base::_dist=(void *)&t;
166.1035 - return DijkstraWizard<DefDistMapBase<T> >(*this);
166.1036 - }
166.1037 -
166.1038 - /// Sets the source node, from which the Dijkstra algorithm runs.
166.1039 -
166.1040 - /// Sets the source node, from which the Dijkstra algorithm runs.
166.1041 - /// \param s is the source node.
166.1042 - DijkstraWizard<TR> &source(Node s)
166.1043 - {
166.1044 - Base::_source=s;
166.1045 - return *this;
166.1046 - }
166.1047 -
166.1048 - };
166.1049 -
166.1050 - ///Function type interface for Dijkstra algorithm.
166.1051 -
166.1052 - /// \ingroup flowalgs
166.1053 - ///Function type interface for Dijkstra algorithm.
166.1054 - ///
166.1055 - ///This function also has several
166.1056 - ///\ref named-templ-func-param "named parameters",
166.1057 - ///they are declared as the members of class \ref DijkstraWizard.
166.1058 - ///The following
166.1059 - ///example shows how to use these parameters.
166.1060 - ///\code
166.1061 - /// dijkstra(g,length,source).predMap(preds).run();
166.1062 - ///\endcode
166.1063 - ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
166.1064 - ///to the end of the parameter list.
166.1065 - ///\sa DijkstraWizard
166.1066 - ///\sa Dijkstra
166.1067 - template<class GR, class LM>
166.1068 - DijkstraWizard<DijkstraWizardBase<GR,LM> >
166.1069 - dijkstra(const GR &g,const LM &l,typename GR::Node s=INVALID)
166.1070 - {
166.1071 - return DijkstraWizard<DijkstraWizardBase<GR,LM> >(g,l,s);
166.1072 - }
166.1073 -
166.1074 -} //END OF NAMESPACE LEMON
166.1075 -
166.1076 -#endif
166.1077 -
167.1 --- a/src/lemon/dimacs.h Sat May 21 21:04:57 2005 +0000
167.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
167.3 @@ -1,228 +0,0 @@
167.4 -/* -*- C++ -*-
167.5 - * src/lemon/dimacs.h - Part of LEMON, a generic C++ optimization library
167.6 - *
167.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
167.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
167.9 - *
167.10 - * Permission to use, modify and distribute this software is granted
167.11 - * provided that this copyright notice appears in all copies. For
167.12 - * precise terms see the accompanying LICENSE file.
167.13 - *
167.14 - * This software is provided "AS IS" with no warranty of any kind,
167.15 - * express or implied, and with no claim as to its suitability for any
167.16 - * purpose.
167.17 - *
167.18 - */
167.19 -
167.20 -#ifndef LEMON_DIMACS_H
167.21 -#define LEMON_DIMACS_H
167.22 -
167.23 -#include <iostream>
167.24 -#include <string>
167.25 -#include <vector>
167.26 -#include <lemon/maps.h>
167.27 -#include <lemon/invalid.h>
167.28 -
167.29 -/// \ingroup dimacs_group
167.30 -/// \file
167.31 -/// \brief Dimacs file format reader.
167.32 -
167.33 -namespace lemon {
167.34 -
167.35 - ///
167.36 - ///@defgroup dimacs_group DIMACS format
167.37 - ///\brief Read and write files in DIMACS format
167.38 - ///
167.39 - ///Tools to read a graph from or write it to a file in DIMACS format
167.40 - ///data
167.41 - ///\ingroup io_group
167.42 -
167.43 - /// \addtogroup dimacs_group
167.44 - /// @{
167.45 -
167.46 - /// Dimacs min cost flow reader function.
167.47 -
167.48 - /// This function reads a min cost flow instance from dimacs format,
167.49 - /// i.e. from dimacs files having a line starting with
167.50 - /// \code
167.51 - /// p "min"
167.52 - /// \endcode
167.53 - /// At the beginning \c g is cleared by \c g.clear(). The edge
167.54 - /// capacities are written to \c capacity, \c s and \c t are set to
167.55 - /// the source and the target nodes resp. and the cost of the edges
167.56 - /// are written to \c cost.
167.57 - ///
167.58 - /// \author Marton Makai
167.59 - template<typename Graph, typename CapacityMap, typename CostMap>
167.60 - void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
167.61 - typename Graph::Node &s, typename Graph::Node &t,
167.62 - CostMap& cost) {
167.63 - g.clear();
167.64 - typename CapacityMap::Value _cap;
167.65 - typename CostMap::Value _cost;
167.66 - char d;
167.67 - std::string problem;
167.68 - char c;
167.69 - int i, j;
167.70 - std::string str;
167.71 - int n, m;
167.72 - typename Graph::Edge e;
167.73 - std::vector<typename Graph::Node> nodes;
167.74 - while (is>>c) {
167.75 - switch (c) {
167.76 - case 'c': //comment
167.77 - getline(is, str);
167.78 - break;
167.79 - case 'p': //problem definition
167.80 - is >> problem >> n >> m;
167.81 - getline(is, str);
167.82 - nodes.resize(n+1);
167.83 - for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
167.84 - break;
167.85 - case 'n': //node definition
167.86 - if (problem=="sp") { //shortest path problem
167.87 - is >> i;
167.88 - getline(is, str);
167.89 - s=nodes[i];
167.90 - }
167.91 - if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
167.92 - is >> i >> d;
167.93 - getline(is, str);
167.94 - if (d=='s') s=nodes[i];
167.95 - if (d=='t') t=nodes[i];
167.96 - }
167.97 - break;
167.98 - case 'a':
167.99 - if ( problem == "max" || problem == "sp") {
167.100 - is >> i >> j >> _cap;
167.101 - getline(is, str);
167.102 - e=g.addEdge(nodes[i], nodes[j]);
167.103 - //capacity.update();
167.104 - capacity.set(e, _cap);
167.105 - } else {
167.106 - if ( problem == "min" ) {
167.107 - is >> i >> j >> _cap >> _cost;
167.108 - getline(is, str);
167.109 - e=g.addEdge(nodes[i], nodes[j]);
167.110 - //capacity.update();
167.111 - capacity.set(e, _cap);
167.112 - //cost.update();
167.113 - cost.set(e, _cost);
167.114 - } else {
167.115 - is >> i >> j;
167.116 - getline(is, str);
167.117 - g.addEdge(nodes[i], nodes[j]);
167.118 - }
167.119 - }
167.120 - break;
167.121 - }
167.122 - }
167.123 - }
167.124 -
167.125 -
167.126 - /// Dimacs max flow reader function.
167.127 -
167.128 - /// This function reads a max flow instance from dimacs format,
167.129 - /// i.e. from dimacs files having a line starting with
167.130 - /// \code
167.131 - /// p "max"
167.132 - /// \endcode
167.133 - ///At the beginning \c g is cleared by \c g.clear(). The
167.134 - /// edge capacities are written to \c capacity and \c s and \c t are
167.135 - /// set to the source and the target nodes.
167.136 - ///
167.137 - /// \author Marton Makai
167.138 - template<typename Graph, typename CapacityMap>
167.139 - void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
167.140 - typename Graph::Node &s, typename Graph::Node &t) {
167.141 - NullMap<typename Graph::Edge, int> n;
167.142 - readDimacs(is, g, capacity, s, t, n);
167.143 - }
167.144 -
167.145 -
167.146 - /// Dimacs shortest path reader function.
167.147 -
167.148 - /// This function reads a shortest path instance from dimacs format,
167.149 - /// i.e. from dimacs files having a line starting with
167.150 - /// \code
167.151 - /// p "sp"
167.152 - /// \endcode
167.153 - /// At the beginning \c g is cleared by \c g.clear(). The edge
167.154 - /// capacities are written to \c capacity and \c s is set to the
167.155 - /// source node.
167.156 - ///
167.157 - /// \author Marton Makai
167.158 - template<typename Graph, typename CapacityMap>
167.159 - void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity,
167.160 - typename Graph::Node &s) {
167.161 - NullMap<typename Graph::Edge, int> n;
167.162 - readDimacs(is, g, capacity, s, s, n);
167.163 - }
167.164 -
167.165 -
167.166 - /// Dimacs capacitated graph reader function.
167.167 -
167.168 - /// This function reads an edge capacitated graph instance from
167.169 - /// dimacs format. At the beginning \c g is cleared by \c g.clear()
167.170 - /// and the edge capacities are written to \c capacity.
167.171 - ///
167.172 - /// \author Marton Makai
167.173 - template<typename Graph, typename CapacityMap>
167.174 - void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
167.175 - typename Graph::Node u;
167.176 - NullMap<typename Graph::Edge, int> n;
167.177 - readDimacs(is, g, capacity, u, u, n);
167.178 - }
167.179 -
167.180 -
167.181 - /// Dimacs plain graph reader function.
167.182 -
167.183 - /// This function reads a graph without any designated nodes and
167.184 - /// maps from dimacs format, i.e. from dimacs files having a line
167.185 - /// starting with
167.186 - /// \code
167.187 - /// p "mat"
167.188 - /// \endcode
167.189 - /// At the beginning \c g is cleared
167.190 - /// by \c g.clear().
167.191 - ///
167.192 - /// \author Marton Makai
167.193 - template<typename Graph>
167.194 - void readDimacs(std::istream& is, Graph &g) {
167.195 - typename Graph::Node u;
167.196 - NullMap<typename Graph::Edge, int> n;
167.197 - readDimacs(is, g, n, u, u, n);
167.198 - }
167.199 -
167.200 -
167.201 -
167.202 -
167.203 - /// write matching problem
167.204 - template<typename Graph>
167.205 - void writeDimacs(std::ostream& os, const Graph &g) {
167.206 - typedef typename Graph::NodeIt NodeIt;
167.207 - typedef typename Graph::EdgeIt EdgeIt;
167.208 -
167.209 - typename Graph::template NodeMap<int> nodes(g);
167.210 -
167.211 - os << "c matching problem" << std::endl;
167.212 -
167.213 - int i=1;
167.214 - for(NodeIt v(g); v!=INVALID; ++v) {
167.215 - nodes.set(v, i);
167.216 - ++i;
167.217 - }
167.218 -
167.219 - os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
167.220 -
167.221 - for(EdgeIt e(g); e!=INVALID; ++e) {
167.222 - os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)] << std::endl;
167.223 - }
167.224 -
167.225 - }
167.226 -
167.227 - /// @}
167.228 -
167.229 -} //namespace lemon
167.230 -
167.231 -#endif //LEMON_DIMACS_H
168.1 --- a/src/lemon/error.h Sat May 21 21:04:57 2005 +0000
168.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
168.3 @@ -1,540 +0,0 @@
168.4 -/* -*- C++ -*-
168.5 - *
168.6 - * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
168.7 - *
168.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
168.9 - * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
168.10 - * EGRES).
168.11 - *
168.12 - * Permission to use, modify and distribute this software is granted
168.13 - * provided that this copyright notice appears in all copies. For
168.14 - * precise terms see the accompanying LICENSE file.
168.15 - *
168.16 - * This software is provided "AS IS" with no warranty of any kind,
168.17 - * express or implied, and with no claim as to its suitability for any
168.18 - * purpose.
168.19 - *
168.20 - */
168.21 -
168.22 -#ifndef LEMON_ERROR_H
168.23 -#define LEMON_ERROR_H
168.24 -
168.25 -//! \ingroup exceptions
168.26 -//! \file
168.27 -//! \brief Basic exception classes and error handling.
168.28 -
168.29 -#include <exception>
168.30 -#include <string>
168.31 -#include <sstream>
168.32 -#include <iostream>
168.33 -#include <cstdlib>
168.34 -#include <memory>
168.35 -
168.36 -namespace lemon {
168.37 -
168.38 - /// \addtogroup exceptions
168.39 - /// @{
168.40 -
168.41 - /// \brief Exception safe wrapper class.
168.42 - ///
168.43 - /// Exception safe wrapper class to implement the members of exceptions.
168.44 - template <typename _Type>
168.45 - class ExceptionMember {
168.46 - public:
168.47 - typedef _Type Type;
168.48 -
168.49 - ExceptionMember() throw () {
168.50 - try {
168.51 - ptr.reset(new Type());
168.52 - } catch (...) {}
168.53 - }
168.54 -
168.55 - ExceptionMember(const Type& type) throw () {
168.56 - try {
168.57 - ptr.reset(new Type());
168.58 - if (ptr.get() == 0) return;
168.59 - *ptr = type;
168.60 - } catch (...) {}
168.61 - }
168.62 -
168.63 - ExceptionMember(const ExceptionMember& copy) throw() {
168.64 - try {
168.65 - if (!copy.valid()) return;
168.66 - ptr.reset(new Type());
168.67 - if (ptr.get() == 0) return;
168.68 - *ptr = copy.get();
168.69 - } catch (...) {}
168.70 - }
168.71 -
168.72 - ExceptionMember& operator=(const ExceptionMember& copy) {
168.73 - if (ptr.get() == 0) return;
168.74 - try {
168.75 - if (!copy.valid()) return;
168.76 - *ptr = copy.get();
168.77 - } catch (...) {}
168.78 - }
168.79 -
168.80 - void set(const Type& type) {
168.81 - if (ptr.get() == 0) return;
168.82 - try {
168.83 - *ptr = type;
168.84 - } catch (...) {}
168.85 - }
168.86 -
168.87 - const Type& get() const {
168.88 - return *ptr;
168.89 - }
168.90 -
168.91 - bool valid() const {
168.92 - return ptr.get() != 0;
168.93 - }
168.94 -
168.95 - private:
168.96 - std::auto_ptr<_Type> ptr;
168.97 - };
168.98 -
168.99 - /// Exception-safe convenient "error message" class.
168.100 -
168.101 - /// Helper class which provides a convenient ostream-like (operator <<
168.102 - /// based) interface to create a string message. Mostly useful in
168.103 - /// exception classes (therefore the name).
168.104 - class ErrorMessage {
168.105 - protected:
168.106 - ///\e
168.107 - ///\todo The good solution is boost:shared_ptr...
168.108 - mutable
168.109 - std::auto_ptr<std::ostringstream> buf;
168.110 -
168.111 - ///\e
168.112 - bool init() throw() {
168.113 - try {
168.114 - buf.reset(new std::ostringstream);
168.115 - }
168.116 - catch(...) {
168.117 - buf.reset();
168.118 - }
168.119 - return buf.get();
168.120 - }
168.121 -
168.122 - public:
168.123 -
168.124 - ///\e
168.125 - ErrorMessage() throw() { init(); }
168.126 -
168.127 - ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
168.128 -
168.129 - ///\e
168.130 - ErrorMessage(const char *message) throw() {
168.131 - init();
168.132 - *this << message;
168.133 - }
168.134 -
168.135 - ///\e
168.136 - ErrorMessage(const std::string &message) throw() {
168.137 - init();
168.138 - *this << message;
168.139 - }
168.140 -
168.141 - ///\e
168.142 - template <typename T>
168.143 - ErrorMessage& operator<<(const T &t) throw() {
168.144 - if( ! buf.get() ) return *this;
168.145 -
168.146 - try {
168.147 - *buf << t;
168.148 - }
168.149 - catch(...) {
168.150 - buf.reset();
168.151 - }
168.152 - return *this;
168.153 - }
168.154 -
168.155 - ///\e
168.156 - const char* message() throw() {
168.157 - if( ! buf.get() ) return 0;
168.158 -
168.159 - const char* mes = 0;
168.160 - try {
168.161 - mes = buf->str().c_str();
168.162 - }
168.163 - catch(...) {}
168.164 - return mes;
168.165 - }
168.166 -
168.167 - };
168.168 -
168.169 - /**
168.170 - * \brief Generic exception class.
168.171 - *
168.172 - * Base class for exceptions used in LEMON.
168.173 - */
168.174 - class Exception : public std::exception {
168.175 - public:
168.176 - ///\e
168.177 - Exception() {}
168.178 - ///\e
168.179 - virtual ~Exception() throw() {}
168.180 -
168.181 - ///\e
168.182 - virtual const char* exceptionName() const {
168.183 - return "lemon::Exception";
168.184 - }
168.185 -
168.186 - ///\e
168.187 - virtual const char* what() const throw() {
168.188 - return exceptionName();
168.189 - }
168.190 - };
168.191 -
168.192 - /**
168.193 - * \brief One of the two main subclasses of \ref Exception.
168.194 - *
168.195 - * Logic errors represent problems in the internal logic of a program;
168.196 - * in theory, these are preventable, and even detectable before the
168.197 - * program runs (e.g., violations of class invariants).
168.198 - *
168.199 - * A typical example for this is \ref UninitializedParameter.
168.200 - */
168.201 - class LogicError : public Exception {
168.202 - public:
168.203 - virtual const char* exceptionName() const {
168.204 - return "lemon::LogicError";
168.205 - }
168.206 - };
168.207 -
168.208 - /**
168.209 - * \brief \ref Exception for uninitialized parameters.
168.210 - *
168.211 - * This error represents problems in the initialization
168.212 - * of the parameters of the algorithms.
168.213 - */
168.214 - class UninitializedParameter : public LogicError {
168.215 - public:
168.216 - virtual const char* exceptionName() const {
168.217 - return "lemon::UninitializedParameter";
168.218 - }
168.219 - };
168.220 -
168.221 -
168.222 - /**
168.223 - * \brief One of the two main subclasses of \ref Exception.
168.224 - *
168.225 - * Runtime errors represent problems outside the scope of a program;
168.226 - * they cannot be easily predicted and can generally only be caught as
168.227 - * the program executes.
168.228 - */
168.229 - class RuntimeError : public Exception {
168.230 - public:
168.231 - virtual const char* exceptionName() const {
168.232 - return "lemon::RuntimeError";
168.233 - }
168.234 - };
168.235 -
168.236 - ///\e
168.237 - class RangeError : public RuntimeError {
168.238 - public:
168.239 - virtual const char* exceptionName() const {
168.240 - return "lemon::RangeError";
168.241 - }
168.242 - };
168.243 -
168.244 - ///\e
168.245 - class IOError : public RuntimeError {
168.246 - public:
168.247 - virtual const char* exceptionName() const {
168.248 - return "lemon::IOError";
168.249 - }
168.250 - };
168.251 -
168.252 - ///\e
168.253 - class DataFormatError : public IOError {
168.254 - protected:
168.255 - ExceptionMember<std::string> _message;
168.256 - ExceptionMember<std::string> _file;
168.257 - int _line;
168.258 -
168.259 - mutable ExceptionMember<std::string> _message_holder;
168.260 - public:
168.261 -
168.262 - DataFormatError(const DataFormatError &dfe) :
168.263 - IOError(dfe), _message(dfe._message), _file(dfe._file),
168.264 - _line(dfe._line) {}
168.265 -
168.266 - ///\e
168.267 - explicit DataFormatError(const char *the_message)
168.268 - : _message(the_message), _line(0) {}
168.269 -
168.270 - ///\e
168.271 - DataFormatError(const std::string &file_name, int line_num,
168.272 - const char *the_message)
168.273 - : _message(the_message), _line(line_num) { file(file_name); }
168.274 -
168.275 - ///\e
168.276 - void line(int line) { _line = line; }
168.277 - ///\e
168.278 - void message(const std::string& message) { _message.set(message); }
168.279 - ///\e
168.280 - void file(const std::string &file) { _file.set(file); }
168.281 -
168.282 - ///\e
168.283 - int line() const { return _line; }
168.284 - ///\e
168.285 - const char* message() const {
168.286 - if (_message.valid() && !_message.get().empty()) {
168.287 - return _message.get().c_str();
168.288 - } else {
168.289 - return 0;
168.290 - }
168.291 - }
168.292 -
168.293 - /// \brief Returns the filename.
168.294 - ///
168.295 - /// Returns \e null if the filename was not specified.
168.296 - const char* file() const {
168.297 - if (_file.valid() && !_file.get().empty()) {
168.298 - return _file.get().c_str();
168.299 - } else {
168.300 - return 0;
168.301 - }
168.302 - }
168.303 -
168.304 - ///\e
168.305 - virtual const char* what() const throw() {
168.306 - try {
168.307 - std::ostringstream ostr;
168.308 - ostr << exceptionName() << ": ";
168.309 - if (message()) ostr << message();
168.310 - if( file() || line() != 0 ) {
168.311 - ostr << " (";
168.312 - if( file() ) ostr << "in file '" << file() << "'";
168.313 - if( file() && line() != 0 ) ostr << " ";
168.314 - if( line() != 0 ) ostr << "at line " << line();
168.315 - ostr << ")";
168.316 - }
168.317 - _message_holder.set(ostr.str());
168.318 - }
168.319 - catch (...) {}
168.320 - if( _message_holder.valid()) return _message_holder.get().c_str();
168.321 - return exceptionName();
168.322 - }
168.323 -
168.324 - virtual const char* exceptionName() const {
168.325 - return "lemon::DataFormatError";
168.326 - }
168.327 -
168.328 - virtual ~DataFormatError() throw() {}
168.329 - };
168.330 -
168.331 - class IOParameterError : public LogicError {
168.332 - protected:
168.333 - ExceptionMember<std::string> _message;
168.334 - ExceptionMember<std::string> _file;
168.335 -
168.336 - mutable ExceptionMember<std::string> _message_holder;
168.337 - public:
168.338 -
168.339 - IOParameterError(const IOParameterError &ile) :
168.340 - LogicError(ile), _message(ile._message), _file(ile._file) {}
168.341 -
168.342 - ///\e
168.343 - explicit IOParameterError(const char *the_message)
168.344 - : _message(the_message) {}
168.345 -
168.346 - ///\e
168.347 - IOParameterError(const char *file_name, const char *the_message)
168.348 - : _message(the_message), _file(file_name) {}
168.349 -
168.350 - ///\e
168.351 - void message(const std::string& message) { _message.set(message); }
168.352 - ///\e
168.353 - void file(const std::string &file) { _file.set(file); }
168.354 -
168.355 - ///\e
168.356 - const char* message() const {
168.357 - if (_message.valid()) {
168.358 - return _message.get().c_str();
168.359 - } else {
168.360 - return 0;
168.361 - }
168.362 - }
168.363 -
168.364 - /// \brief Returns the filename.
168.365 - ///
168.366 - /// Returns \e null if the filename was not specified.
168.367 - const char* file() const {
168.368 - if (_file.valid()) {
168.369 - return _file.get().c_str();
168.370 - } else {
168.371 - return 0;
168.372 - }
168.373 - }
168.374 -
168.375 - ///\e
168.376 - virtual const char* what() const throw() {
168.377 - try {
168.378 - std::ostringstream ostr;
168.379 - if (message()) ostr << message();
168.380 - if (file()) ostr << "(when reading file '" << file() << "')";
168.381 - _message_holder.set(ostr.str());
168.382 - }
168.383 - catch (...) {}
168.384 - if( _message_holder.valid() ) return _message_holder.get().c_str();
168.385 - return exceptionName();
168.386 - }
168.387 -
168.388 - virtual const char* exceptionName() const {
168.389 - return "lemon::IOParameterError";
168.390 - }
168.391 -
168.392 - virtual ~IOParameterError() throw() {}
168.393 - };
168.394 -
168.395 -
168.396 - ///\e
168.397 - class AssertionFailedError : public LogicError {
168.398 - protected:
168.399 - const char *assertion;
168.400 - const char *file;
168.401 - int line;
168.402 - const char *function;
168.403 - const char *message;
168.404 -
168.405 - mutable ExceptionMember<std::string> _message_holder;
168.406 - public:
168.407 - ///\e
168.408 - AssertionFailedError(const char *_file, int _line, const char *func,
168.409 - const char *msg, const char *_assertion = 0) :
168.410 - assertion(_assertion), file(_file), line(_line), function(func),
168.411 - message(msg) {}
168.412 -
168.413 - ///\e
168.414 - const char* get_assertion() const { return assertion; }
168.415 - ///\e
168.416 - const char* get_message() const { return message; }
168.417 - ///\e
168.418 - const char* get_file() const { return file; }
168.419 - ///\e
168.420 - const char* get_function() const { return function; }
168.421 - ///\e
168.422 - int get_line() const { return line; }
168.423 -
168.424 -
168.425 - virtual const char* what() const throw() {
168.426 - try {
168.427 - std::ostringstream ostr;
168.428 - ostr << file << ":" << line << ": ";
168.429 - if( function )
168.430 - ostr << function << ": ";
168.431 - ostr << message;
168.432 - if( assertion )
168.433 - ostr << " (assertion '" << assertion << "' failed)";
168.434 - _message_holder.set(ostr.str());
168.435 - return ostr.str().c_str();
168.436 - }
168.437 - catch(...) {}
168.438 - if( _message_holder.valid() ) return _message_holder.get().c_str();
168.439 - return exceptionName();
168.440 - }
168.441 -
168.442 - virtual const char* exceptionName() const {
168.443 - return "lemon::AssertionFailedError";
168.444 - }
168.445 -
168.446 - virtual ~AssertionFailedError() throw() {}
168.447 - };
168.448 -
168.449 -
168.450 - /**************** Macros ****************/
168.451 -
168.452 -
168.453 - inline
168.454 - void assert_fail(const char *file, int line, const char *func,
168.455 - const char *message, const char *assertion = 0,
168.456 - bool do_abort=true)
168.457 - {
168.458 - using namespace std;
168.459 - cerr << file << ":" << line << ": ";
168.460 - if( func )
168.461 - cerr << func << ": ";
168.462 - cerr << message;
168.463 - if( assertion )
168.464 - cerr << " (assertion '" << assertion << "' failed)";
168.465 - cerr << endl;
168.466 - if(do_abort)
168.467 - abort();
168.468 - }
168.469 -
168.470 - inline
168.471 - void assert_fail_throw(const char *file, int line, const char *func,
168.472 - const char *message, const char *assertion = 0,
168.473 - bool = true)
168.474 - {
168.475 - throw AssertionFailedError(file, line, func, message, assertion);
168.476 - }
168.477 -
168.478 -/// @}
168.479 -
168.480 -}
168.481 -#endif // LEMON_ERROR_H
168.482 -
168.483 -#undef LEMON_ASSERT
168.484 -#undef LEMON_FIXME
168.485 -
168.486 -#ifndef LEMON_ASSERT_ABORT
168.487 -# define LEMON_ASSERT_ABORT 1
168.488 -#endif
168.489 -
168.490 -#ifndef LEMON_ASSERT_HANDLER
168.491 -# ifdef LEMON_ASSERT_EXCEPTION
168.492 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
168.493 -# else
168.494 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
168.495 -# endif
168.496 -#endif
168.497 -
168.498 -#if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
168.499 -
168.500 -# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
168.501 -
168.502 -#else
168.503 -
168.504 -/**
168.505 - * \brief Macro for assertions with customizable message
168.506 - *
168.507 - * Macro for assertions with customizable message.
168.508 - *
168.509 - * The behaviour can be customized with LEMON_ASSERT_HANDLER,
168.510 - * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
168.511 - * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
168.512 - *
168.513 - * \todo We should provide some way to reset to the default behaviour,
168.514 - * shouldn't we?
168.515 - *
168.516 - * \todo This whole 'assert' business should be placed in a separate
168.517 - * include file.
168.518 - *
168.519 - * \todo __PRETTY_FUNCTION__ should be replaced by something
168.520 - * compiler-independent, like BOOST_CURRENT_FUNCTION
168.521 - */
168.522 -
168.523 -# define LEMON_ASSERT(exp, msg) \
168.524 - (static_cast<void> (!!(exp) ? 0 : ( \
168.525 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
168.526 - __PRETTY_FUNCTION__, \
168.527 - (msg), #exp, LEMON_ASSERT_ABORT), 0)))
168.528 -
168.529 -#endif // NDEBUG || LEMON_DISABLE_ASSERTS
168.530 -
168.531 -/**
168.532 - * \brief Macro for mark not yet implemented features.
168.533 - *
168.534 - * \todo Is this the right place for this? It should be used only in
168.535 - * modules under development.
168.536 - *
168.537 - * \todo __PRETTY_FUNCTION__ should be replaced by something
168.538 - * compiler-independent, like BOOST_CURRENT_FUNCTION
168.539 - */
168.540 -
168.541 -# define LEMON_FIXME(msg) \
168.542 - (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
168.543 - "FIXME: " msg))
169.1 --- a/src/lemon/fib_heap.h Sat May 21 21:04:57 2005 +0000
169.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
169.3 @@ -1,531 +0,0 @@
169.4 -/* -*- C++ -*-
169.5 - * src/lemon/fib_heap.h - Part of LEMON, a generic C++ optimization library
169.6 - *
169.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
169.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
169.9 - *
169.10 - * Permission to use, modify and distribute this software is granted
169.11 - * provided that this copyright notice appears in all copies. For
169.12 - * precise terms see the accompanying LICENSE file.
169.13 - *
169.14 - * This software is provided "AS IS" with no warranty of any kind,
169.15 - * express or implied, and with no claim as to its suitability for any
169.16 - * purpose.
169.17 - *
169.18 - */
169.19 -
169.20 -#ifndef LEMON_FIB_HEAP_H
169.21 -#define LEMON_FIB_HEAP_H
169.22 -
169.23 -///\file
169.24 -///\ingroup auxdat
169.25 -///\brief Fibonacci Heap implementation.
169.26 -
169.27 -#include <vector>
169.28 -#include <functional>
169.29 -#include <cmath>
169.30 -
169.31 -namespace lemon {
169.32 -
169.33 - /// \addtogroup auxdat
169.34 - /// @{
169.35 -
169.36 - /// Fibonacci Heap.
169.37 -
169.38 - ///This class implements the \e Fibonacci \e heap data structure. A \e heap
169.39 - ///is a data structure for storing items with specified values called \e
169.40 - ///priorities in such a way that finding the item with minimum priority is
169.41 - ///efficient. \c Compare specifies the ordering of the priorities. In a heap
169.42 - ///one can change the priority of an item, add or erase an item, etc.
169.43 - ///
169.44 - ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
169.45 - ///heap. In case of many calls to these operations, it is better to use a
169.46 - ///\e binary \e heap.
169.47 - ///
169.48 - ///\param Item Type of the items to be stored.
169.49 - ///\param Prio Type of the priority of the items.
169.50 - ///\param ItemIntMap A read and writable Item int map, used internally
169.51 - ///to handle the cross references.
169.52 - ///\param Compare A class for the ordering of the priorities. The
169.53 - ///default is \c std::less<Prio>.
169.54 - ///
169.55 - ///\sa BinHeap
169.56 - ///\sa Dijkstra
169.57 - ///\author Jacint Szabo
169.58 -
169.59 -#ifdef DOXYGEN
169.60 - template <typename Item,
169.61 - typename Prio,
169.62 - typename ItemIntMap,
169.63 - typename Compare>
169.64 -#else
169.65 - template <typename Item,
169.66 - typename Prio,
169.67 - typename ItemIntMap,
169.68 - typename Compare = std::less<Prio> >
169.69 -#endif
169.70 - class FibHeap {
169.71 - public:
169.72 - typedef Prio PrioType;
169.73 -
169.74 - private:
169.75 - class store;
169.76 -
169.77 - std::vector<store> container;
169.78 - int minimum;
169.79 - ItemIntMap &iimap;
169.80 - Compare comp;
169.81 - int num_items;
169.82 -
169.83 - public:
169.84 - ///Status of the nodes
169.85 - enum state_enum {
169.86 - ///The node is in the heap
169.87 - IN_HEAP = 0,
169.88 - ///The node has never been in the heap
169.89 - PRE_HEAP = -1,
169.90 - ///The node was in the heap but it got out of it
169.91 - POST_HEAP = -2
169.92 - };
169.93 -
169.94 - ///The constructor
169.95 -
169.96 - /**
169.97 - \c _iimap should be given to the constructor, since it is
169.98 - used internally to handle the cross references.
169.99 - */
169.100 - explicit FibHeap(ItemIntMap &_iimap)
169.101 - : minimum(0), iimap(_iimap), num_items() {}
169.102 -
169.103 - ///The constructor
169.104 -
169.105 - /**
169.106 - \c _iimap should be given to the constructor, since it is used
169.107 - internally to handle the cross references. \c _comp is an
169.108 - object for ordering of the priorities.
169.109 - */
169.110 - FibHeap(ItemIntMap &_iimap, const Compare &_comp) : minimum(0),
169.111 - iimap(_iimap), comp(_comp), num_items() {}
169.112 -
169.113 - ///The number of items stored in the heap.
169.114 -
169.115 - /**
169.116 - Returns the number of items stored in the heap.
169.117 - */
169.118 - int size() const { return num_items; }
169.119 -
169.120 - ///Checks if the heap stores no items.
169.121 -
169.122 - /**
169.123 - Returns \c true if and only if the heap stores no items.
169.124 - */
169.125 - bool empty() const { return num_items==0; }
169.126 -
169.127 - ///\c item gets to the heap with priority \c value independently if \c item was already there.
169.128 -
169.129 - /**
169.130 - This method calls \ref push(\c item, \c value) if \c item is not
169.131 - stored in the heap and it calls \ref decrease(\c item, \c value) or
169.132 - \ref increase(\c item, \c value) otherwise.
169.133 - */
169.134 - void set (Item const item, PrioType const value);
169.135 -
169.136 - ///Adds \c item to the heap with priority \c value.
169.137 -
169.138 - /**
169.139 - Adds \c item to the heap with priority \c value.
169.140 - \pre \c item must not be stored in the heap.
169.141 - */
169.142 - void push (Item const item, PrioType const value);
169.143 -
169.144 - ///Returns the item with minimum priority relative to \c Compare.
169.145 -
169.146 - /**
169.147 - This method returns the item with minimum priority relative to \c
169.148 - Compare.
169.149 - \pre The heap must be nonempty.
169.150 - */
169.151 - Item top() const { return container[minimum].name; }
169.152 -
169.153 - ///Returns the minimum priority relative to \c Compare.
169.154 -
169.155 - /**
169.156 - It returns the minimum priority relative to \c Compare.
169.157 - \pre The heap must be nonempty.
169.158 - */
169.159 - PrioType prio() const { return container[minimum].prio; }
169.160 -
169.161 - ///Returns the priority of \c item.
169.162 -
169.163 - /**
169.164 - This function returns the priority of \c item.
169.165 - \pre \c item must be in the heap.
169.166 - */
169.167 - PrioType& operator[](const Item& item) {
169.168 - return container[iimap[item]].prio;
169.169 - }
169.170 -
169.171 - ///Returns the priority of \c item.
169.172 -
169.173 - /**
169.174 - It returns the priority of \c item.
169.175 - \pre \c item must be in the heap.
169.176 - */
169.177 - const PrioType& operator[](const Item& item) const {
169.178 - return container[iimap[item]].prio;
169.179 - }
169.180 -
169.181 -
169.182 - ///Deletes the item with minimum priority relative to \c Compare.
169.183 -
169.184 - /**
169.185 - This method deletes the item with minimum priority relative to \c
169.186 - Compare from the heap.
169.187 - \pre The heap must be non-empty.
169.188 - */
169.189 - void pop();
169.190 -
169.191 - ///Deletes \c item from the heap.
169.192 -
169.193 - /**
169.194 - This method deletes \c item from the heap, if \c item was already
169.195 - stored in the heap. It is quite inefficient in Fibonacci heaps.
169.196 - */
169.197 - void erase (const Item& item);
169.198 -
169.199 - ///Decreases the priority of \c item to \c value.
169.200 -
169.201 - /**
169.202 - This method decreases the priority of \c item to \c value.
169.203 - \pre \c item must be stored in the heap with priority at least \c
169.204 - value relative to \c Compare.
169.205 - */
169.206 - void decrease (Item item, PrioType const value);
169.207 -
169.208 - ///Increases the priority of \c item to \c value.
169.209 -
169.210 - /**
169.211 - This method sets the priority of \c item to \c value. Though
169.212 - there is no precondition on the priority of \c item, this
169.213 - method should be used only if it is indeed necessary to increase
169.214 - (relative to \c Compare) the priority of \c item, because this
169.215 - method is inefficient.
169.216 - */
169.217 - void increase (Item item, PrioType const value) {
169.218 - erase(item);
169.219 - push(item, value);
169.220 - }
169.221 -
169.222 -
169.223 - ///Returns if \c item is in, has already been in, or has never been in the heap.
169.224 -
169.225 - /**
169.226 - This method returns PRE_HEAP if \c item has never been in the
169.227 - heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
169.228 - otherwise. In the latter case it is possible that \c item will
169.229 - get back to the heap again.
169.230 - */
169.231 - state_enum state(const Item &item) const {
169.232 - int i=iimap[item];
169.233 - if( i>=0 ) {
169.234 - if ( container[i].in ) i=0;
169.235 - else i=-2;
169.236 - }
169.237 - return state_enum(i);
169.238 - }
169.239 -
169.240 - private:
169.241 -
169.242 - void balance();
169.243 - void makeroot(int c);
169.244 - void cut(int a, int b);
169.245 - void cascade(int a);
169.246 - void fuse(int a, int b);
169.247 - void unlace(int a);
169.248 -
169.249 -
169.250 - class store {
169.251 - friend class FibHeap;
169.252 -
169.253 - Item name;
169.254 - int parent;
169.255 - int left_neighbor;
169.256 - int right_neighbor;
169.257 - int child;
169.258 - int degree;
169.259 - bool marked;
169.260 - bool in;
169.261 - PrioType prio;
169.262 -
169.263 - store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
169.264 - };
169.265 - };
169.266 -
169.267 -
169.268 -
169.269 - // **********************************************************************
169.270 - // IMPLEMENTATIONS
169.271 - // **********************************************************************
169.272 -
169.273 - template <typename Item, typename Prio, typename ItemIntMap,
169.274 - typename Compare>
169.275 - void FibHeap<Item, Prio, ItemIntMap, Compare>::set
169.276 - (Item const item, PrioType const value)
169.277 - {
169.278 - int i=iimap[item];
169.279 - if ( i >= 0 && container[i].in ) {
169.280 - if ( comp(value, container[i].prio) ) decrease(item, value);
169.281 - if ( comp(container[i].prio, value) ) increase(item, value);
169.282 - } else push(item, value);
169.283 - }
169.284 -
169.285 - template <typename Item, typename Prio, typename ItemIntMap,
169.286 - typename Compare>
169.287 - void FibHeap<Item, Prio, ItemIntMap, Compare>::push
169.288 - (Item const item, PrioType const value) {
169.289 - int i=iimap[item];
169.290 - if ( i < 0 ) {
169.291 - int s=container.size();
169.292 - iimap.set( item, s );
169.293 - store st;
169.294 - st.name=item;
169.295 - container.push_back(st);
169.296 - i=s;
169.297 - } else {
169.298 - container[i].parent=container[i].child=-1;
169.299 - container[i].degree=0;
169.300 - container[i].in=true;
169.301 - container[i].marked=false;
169.302 - }
169.303 -
169.304 - if ( num_items ) {
169.305 - container[container[minimum].right_neighbor].left_neighbor=i;
169.306 - container[i].right_neighbor=container[minimum].right_neighbor;
169.307 - container[minimum].right_neighbor=i;
169.308 - container[i].left_neighbor=minimum;
169.309 - if ( comp( value, container[minimum].prio) ) minimum=i;
169.310 - } else {
169.311 - container[i].right_neighbor=container[i].left_neighbor=i;
169.312 - minimum=i;
169.313 - }
169.314 - container[i].prio=value;
169.315 - ++num_items;
169.316 - }
169.317 -
169.318 - template <typename Item, typename Prio, typename ItemIntMap,
169.319 - typename Compare>
169.320 - void FibHeap<Item, Prio, ItemIntMap, Compare>::pop() {
169.321 - /*The first case is that there are only one root.*/
169.322 - if ( container[minimum].left_neighbor==minimum ) {
169.323 - container[minimum].in=false;
169.324 - if ( container[minimum].degree!=0 ) {
169.325 - makeroot(container[minimum].child);
169.326 - minimum=container[minimum].child;
169.327 - balance();
169.328 - }
169.329 - } else {
169.330 - int right=container[minimum].right_neighbor;
169.331 - unlace(minimum);
169.332 - container[minimum].in=false;
169.333 - if ( container[minimum].degree > 0 ) {
169.334 - int left=container[minimum].left_neighbor;
169.335 - int child=container[minimum].child;
169.336 - int last_child=container[child].left_neighbor;
169.337 -
169.338 - makeroot(child);
169.339 -
169.340 - container[left].right_neighbor=child;
169.341 - container[child].left_neighbor=left;
169.342 - container[right].left_neighbor=last_child;
169.343 - container[last_child].right_neighbor=right;
169.344 - }
169.345 - minimum=right;
169.346 - balance();
169.347 - } // the case where there are more roots
169.348 - --num_items;
169.349 - }
169.350 -
169.351 -
169.352 - template <typename Item, typename Prio, typename ItemIntMap,
169.353 - typename Compare>
169.354 - void FibHeap<Item, Prio, ItemIntMap, Compare>::erase
169.355 - (const Item& item) {
169.356 - int i=iimap[item];
169.357 -
169.358 - if ( i >= 0 && container[i].in ) {
169.359 - if ( container[i].parent!=-1 ) {
169.360 - int p=container[i].parent;
169.361 - cut(i,p);
169.362 - cascade(p);
169.363 - }
169.364 - minimum=i; //As if its prio would be -infinity
169.365 - pop();
169.366 - }
169.367 - }
169.368 -
169.369 - template <typename Item, typename Prio, typename ItemIntMap,
169.370 - typename Compare>
169.371 - void FibHeap<Item, Prio, ItemIntMap, Compare>::decrease
169.372 - (Item item, PrioType const value) {
169.373 - int i=iimap[item];
169.374 - container[i].prio=value;
169.375 - int p=container[i].parent;
169.376 -
169.377 - if ( p!=-1 && comp(value, container[p].prio) ) {
169.378 - cut(i,p);
169.379 - cascade(p);
169.380 - }
169.381 - if ( comp(value, container[minimum].prio) ) minimum=i;
169.382 - }
169.383 -
169.384 -
169.385 - template <typename Item, typename Prio, typename ItemIntMap,
169.386 - typename Compare>
169.387 - void FibHeap<Item, Prio, ItemIntMap, Compare>::balance() {
169.388 -
169.389 - int maxdeg=int( std::floor( 2.08*log(double(container.size()))))+1;
169.390 -
169.391 - std::vector<int> A(maxdeg,-1);
169.392 -
169.393 - /*
169.394 - *Recall that now minimum does not point to the minimum prio element.
169.395 - *We set minimum to this during balance().
169.396 - */
169.397 - int anchor=container[minimum].left_neighbor;
169.398 - int next=minimum;
169.399 - bool end=false;
169.400 -
169.401 - do {
169.402 - int active=next;
169.403 - if ( anchor==active ) end=true;
169.404 - int d=container[active].degree;
169.405 - next=container[active].right_neighbor;
169.406 -
169.407 - while (A[d]!=-1) {
169.408 - if( comp(container[active].prio, container[A[d]].prio) ) {
169.409 - fuse(active,A[d]);
169.410 - } else {
169.411 - fuse(A[d],active);
169.412 - active=A[d];
169.413 - }
169.414 - A[d]=-1;
169.415 - ++d;
169.416 - }
169.417 - A[d]=active;
169.418 - } while ( !end );
169.419 -
169.420 -
169.421 - while ( container[minimum].parent >=0 ) minimum=container[minimum].parent;
169.422 - int s=minimum;
169.423 - int m=minimum;
169.424 - do {
169.425 - if ( comp(container[s].prio, container[minimum].prio) ) minimum=s;
169.426 - s=container[s].right_neighbor;
169.427 - } while ( s != m );
169.428 - }
169.429 -
169.430 - template <typename Item, typename Prio, typename ItemIntMap,
169.431 - typename Compare>
169.432 - void FibHeap<Item, Prio, ItemIntMap, Compare>::makeroot
169.433 - (int c) {
169.434 - int s=c;
169.435 - do {
169.436 - container[s].parent=-1;
169.437 - s=container[s].right_neighbor;
169.438 - } while ( s != c );
169.439 - }
169.440 -
169.441 -
169.442 - template <typename Item, typename Prio, typename ItemIntMap,
169.443 - typename Compare>
169.444 - void FibHeap<Item, Prio, ItemIntMap, Compare>::cut
169.445 - (int a, int b) {
169.446 - /*
169.447 - *Replacing a from the children of b.
169.448 - */
169.449 - --container[b].degree;
169.450 -
169.451 - if ( container[b].degree !=0 ) {
169.452 - int child=container[b].child;
169.453 - if ( child==a )
169.454 - container[b].child=container[child].right_neighbor;
169.455 - unlace(a);
169.456 - }
169.457 -
169.458 -
169.459 - /*Lacing a to the roots.*/
169.460 - int right=container[minimum].right_neighbor;
169.461 - container[minimum].right_neighbor=a;
169.462 - container[a].left_neighbor=minimum;
169.463 - container[a].right_neighbor=right;
169.464 - container[right].left_neighbor=a;
169.465 -
169.466 - container[a].parent=-1;
169.467 - container[a].marked=false;
169.468 - }
169.469 -
169.470 -
169.471 - template <typename Item, typename Prio, typename ItemIntMap,
169.472 - typename Compare>
169.473 - void FibHeap<Item, Prio, ItemIntMap, Compare>::cascade
169.474 - (int a)
169.475 - {
169.476 - if ( container[a].parent!=-1 ) {
169.477 - int p=container[a].parent;
169.478 -
169.479 - if ( container[a].marked==false ) container[a].marked=true;
169.480 - else {
169.481 - cut(a,p);
169.482 - cascade(p);
169.483 - }
169.484 - }
169.485 - }
169.486 -
169.487 -
169.488 - template <typename Item, typename Prio, typename ItemIntMap,
169.489 - typename Compare>
169.490 - void FibHeap<Item, Prio, ItemIntMap, Compare>::fuse
169.491 - (int a, int b) {
169.492 - unlace(b);
169.493 -
169.494 - /*Lacing b under a.*/
169.495 - container[b].parent=a;
169.496 -
169.497 - if (container[a].degree==0) {
169.498 - container[b].left_neighbor=b;
169.499 - container[b].right_neighbor=b;
169.500 - container[a].child=b;
169.501 - } else {
169.502 - int child=container[a].child;
169.503 - int last_child=container[child].left_neighbor;
169.504 - container[child].left_neighbor=b;
169.505 - container[b].right_neighbor=child;
169.506 - container[last_child].right_neighbor=b;
169.507 - container[b].left_neighbor=last_child;
169.508 - }
169.509 -
169.510 - ++container[a].degree;
169.511 -
169.512 - container[b].marked=false;
169.513 - }
169.514 -
169.515 -
169.516 - /*
169.517 - *It is invoked only if a has siblings.
169.518 - */
169.519 - template <typename Item, typename Prio, typename ItemIntMap,
169.520 - typename Compare>
169.521 - void FibHeap<Item, Prio, ItemIntMap, Compare>::unlace
169.522 - (int a) {
169.523 - int leftn=container[a].left_neighbor;
169.524 - int rightn=container[a].right_neighbor;
169.525 - container[leftn].right_neighbor=rightn;
169.526 - container[rightn].left_neighbor=leftn;
169.527 - }
169.528 -
169.529 - ///@}
169.530 -
169.531 -} //namespace lemon
169.532 -
169.533 -#endif //LEMON_FIB_HEAP_H
169.534 -
170.1 --- a/src/lemon/full_graph.h Sat May 21 21:04:57 2005 +0000
170.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
170.3 @@ -1,385 +0,0 @@
170.4 -/* -*- C++ -*-
170.5 - * src/lemon/full_graph.h - Part of LEMON, a generic C++ optimization library
170.6 - *
170.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
170.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
170.9 - *
170.10 - * Permission to use, modify and distribute this software is granted
170.11 - * provided that this copyright notice appears in all copies. For
170.12 - * precise terms see the accompanying LICENSE file.
170.13 - *
170.14 - * This software is provided "AS IS" with no warranty of any kind,
170.15 - * express or implied, and with no claim as to its suitability for any
170.16 - * purpose.
170.17 - *
170.18 - */
170.19 -
170.20 -#ifndef LEMON_FULL_GRAPH_H
170.21 -#define LEMON_FULL_GRAPH_H
170.22 -
170.23 -#include <cmath>
170.24 -
170.25 -
170.26 -#include <lemon/bits/iterable_graph_extender.h>
170.27 -#include <lemon/bits/alteration_notifier.h>
170.28 -#include <lemon/bits/default_map.h>
170.29 -
170.30 -#include <lemon/invalid.h>
170.31 -#include <lemon/utility.h>
170.32 -
170.33 -
170.34 -///\ingroup graphs
170.35 -///\file
170.36 -///\brief FullGraph and SymFullGraph classes.
170.37 -
170.38 -
170.39 -namespace lemon {
170.40 -
170.41 -/// \addtogroup graphs
170.42 -/// @{
170.43 -
170.44 - class FullGraphBase {
170.45 - int NodeNum;
170.46 - int EdgeNum;
170.47 - public:
170.48 -
170.49 - typedef FullGraphBase Graph;
170.50 -
170.51 - class Node;
170.52 - class Edge;
170.53 -
170.54 - public:
170.55 -
170.56 - FullGraphBase() {}
170.57 -
170.58 -
170.59 - ///Creates a full graph with \c n nodes.
170.60 - void construct(int n) { NodeNum = n; EdgeNum = n * n; }
170.61 - ///
170.62 - // FullGraphBase(const FullGraphBase &_g)
170.63 - // : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
170.64 -
170.65 - typedef True NodeNumTag;
170.66 - typedef True EdgeNumTag;
170.67 -
170.68 - ///Number of nodes.
170.69 - int nodeNum() const { return NodeNum; }
170.70 - ///Number of edges.
170.71 - int edgeNum() const { return EdgeNum; }
170.72 -
170.73 - /// Maximum node ID.
170.74 -
170.75 - /// Maximum node ID.
170.76 - ///\sa id(Node)
170.77 - int maxId(Node = INVALID) const { return NodeNum-1; }
170.78 - /// Maximum edge ID.
170.79 -
170.80 - /// Maximum edge ID.
170.81 - ///\sa id(Edge)
170.82 - int maxId(Edge = INVALID) const { return EdgeNum-1; }
170.83 -
170.84 - Node source(Edge e) const { return e.id % NodeNum; }
170.85 - Node target(Edge e) const { return e.id / NodeNum; }
170.86 -
170.87 -
170.88 - /// Node ID.
170.89 -
170.90 - /// The ID of a valid Node is a nonnegative integer not greater than
170.91 - /// \ref maxNodeId(). The range of the ID's is not surely continuous
170.92 - /// and the greatest node ID can be actually less then \ref maxNodeId().
170.93 - ///
170.94 - /// The ID of the \ref INVALID node is -1.
170.95 - ///\return The ID of the node \c v.
170.96 -
170.97 - static int id(Node v) { return v.id; }
170.98 - /// Edge ID.
170.99 -
170.100 - /// The ID of a valid Edge is a nonnegative integer not greater than
170.101 - /// \ref maxEdgeId(). The range of the ID's is not surely continuous
170.102 - /// and the greatest edge ID can be actually less then \ref maxEdgeId().
170.103 - ///
170.104 - /// The ID of the \ref INVALID edge is -1.
170.105 - ///\return The ID of the edge \c e.
170.106 - static int id(Edge e) { return e.id; }
170.107 -
170.108 - static Node fromId(int id, Node) { return Node(id);}
170.109 -
170.110 - static Edge fromId(int id, Edge) { return Edge(id);}
170.111 -
170.112 - /// Finds an edge between two nodes.
170.113 -
170.114 - /// Finds an edge from node \c u to node \c v.
170.115 - ///
170.116 - /// If \c prev is \ref INVALID (this is the default value), then
170.117 - /// It finds the first edge from \c u to \c v. Otherwise it looks for
170.118 - /// the next edge from \c u to \c v after \c prev.
170.119 - /// \return The found edge or INVALID if there is no such an edge.
170.120 - Edge findEdge(Node u,Node v, Edge prev = INVALID)
170.121 - {
170.122 - return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
170.123 - }
170.124 -
170.125 -
170.126 - class Node {
170.127 - friend class FullGraphBase;
170.128 -
170.129 - protected:
170.130 - int id;
170.131 - Node(int _id) { id = _id;}
170.132 - public:
170.133 - Node() {}
170.134 - Node (Invalid) { id = -1; }
170.135 - bool operator==(const Node node) const {return id == node.id;}
170.136 - bool operator!=(const Node node) const {return id != node.id;}
170.137 - bool operator<(const Node node) const {return id < node.id;}
170.138 - };
170.139 -
170.140 -
170.141 -
170.142 - class Edge {
170.143 - friend class FullGraphBase;
170.144 -
170.145 - protected:
170.146 - int id; // NodeNum * target + source;
170.147 -
170.148 - Edge(int _id) : id(_id) {}
170.149 -
170.150 - Edge(const FullGraphBase& _graph, int source, int target)
170.151 - : id(_graph.NodeNum * target+source) {}
170.152 - public:
170.153 - Edge() { }
170.154 - Edge (Invalid) { id = -1; }
170.155 - bool operator==(const Edge edge) const {return id == edge.id;}
170.156 - bool operator!=(const Edge edge) const {return id != edge.id;}
170.157 - bool operator<(const Edge edge) const {return id < edge.id;}
170.158 - };
170.159 -
170.160 - void first(Node& node) const {
170.161 - node.id = NodeNum-1;
170.162 - }
170.163 -
170.164 - static void next(Node& node) {
170.165 - --node.id;
170.166 - }
170.167 -
170.168 - void first(Edge& edge) const {
170.169 - edge.id = EdgeNum-1;
170.170 - }
170.171 -
170.172 - static void next(Edge& edge) {
170.173 - --edge.id;
170.174 - }
170.175 -
170.176 - void firstOut(Edge& edge, const Node& node) const {
170.177 - edge.id = EdgeNum + node.id - NodeNum;
170.178 - }
170.179 -
170.180 - void nextOut(Edge& edge) const {
170.181 - edge.id -= NodeNum;
170.182 - if (edge.id < 0) edge.id = -1;
170.183 - }
170.184 -
170.185 - void firstIn(Edge& edge, const Node& node) const {
170.186 - edge.id = node.id * NodeNum;
170.187 - }
170.188 -
170.189 - void nextIn(Edge& edge) const {
170.190 - ++edge.id;
170.191 - if (edge.id % NodeNum == 0) edge.id = -1;
170.192 - }
170.193 -
170.194 - };
170.195 -
170.196 -
170.197 - typedef AlterableGraphExtender<FullGraphBase> AlterableFullGraphBase;
170.198 - typedef IterableGraphExtender<AlterableFullGraphBase> IterableFullGraphBase;
170.199 - typedef DefaultMappableGraphExtender<IterableFullGraphBase> MappableFullGraphBase;
170.200 -
170.201 - ///A full graph class.
170.202 -
170.203 - ///This is a simple and fast directed full graph implementation.
170.204 - ///It is completely static, so you can neither add nor delete either
170.205 - ///edges or nodes.
170.206 - ///Thus it conforms to
170.207 - ///the \ref concept::StaticGraph "StaticGraph" concept
170.208 - ///\sa concept::StaticGraph.
170.209 - ///
170.210 - ///\author Alpar Juttner
170.211 - class FullGraph : public MappableFullGraphBase {
170.212 - public:
170.213 -
170.214 - FullGraph(int n) { construct(n); }
170.215 - };
170.216 -
170.217 -
170.218 - // Base graph class for UndirFullGraph.
170.219 - class UndirFullGraphBase {
170.220 - int NodeNum;
170.221 - int EdgeNum;
170.222 - public:
170.223 -
170.224 - typedef UndirFullGraphBase Graph;
170.225 -
170.226 - class Node;
170.227 - class Edge;
170.228 -
170.229 - public:
170.230 -
170.231 - UndirFullGraphBase() {}
170.232 -
170.233 -
170.234 - ///Creates a full graph with \c n nodes.
170.235 - void construct(int n) { NodeNum = n; EdgeNum = n * (n - 1) / 2; }
170.236 - ///
170.237 - // FullGraphBase(const FullGraphBase &_g)
170.238 - // : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
170.239 -
170.240 - typedef True NodeNumTag;
170.241 - typedef True EdgeNumTag;
170.242 -
170.243 - ///Number of nodes.
170.244 - int nodeNum() const { return NodeNum; }
170.245 - ///Number of edges.
170.246 - int edgeNum() const { return EdgeNum; }
170.247 -
170.248 - /// Maximum node ID.
170.249 -
170.250 - /// Maximum node ID.
170.251 - ///\sa id(Node)
170.252 - int maxId(Node = INVALID) const { return NodeNum-1; }
170.253 - /// Maximum edge ID.
170.254 -
170.255 - /// Maximum edge ID.
170.256 - ///\sa id(Edge)
170.257 - int maxId(Edge = INVALID) const { return EdgeNum-1; }
170.258 -
170.259 - Node source(Edge e) const {
170.260 - /// \todo we may do it faster
170.261 - return ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;
170.262 - }
170.263 -
170.264 - Node target(Edge e) const {
170.265 - int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
170.266 - return e.id - (source) * (source - 1) / 2;
170.267 - }
170.268 -
170.269 -
170.270 - /// Node ID.
170.271 -
170.272 - /// The ID of a valid Node is a nonnegative integer not greater than
170.273 - /// \ref maxNodeId(). The range of the ID's is not surely continuous
170.274 - /// and the greatest node ID can be actually less then \ref maxNodeId().
170.275 - ///
170.276 - /// The ID of the \ref INVALID node is -1.
170.277 - ///\return The ID of the node \c v.
170.278 -
170.279 - static int id(Node v) { return v.id; }
170.280 - /// Edge ID.
170.281 -
170.282 - /// The ID of a valid Edge is a nonnegative integer not greater than
170.283 - /// \ref maxEdgeId(). The range of the ID's is not surely continuous
170.284 - /// and the greatest edge ID can be actually less then \ref maxEdgeId().
170.285 - ///
170.286 - /// The ID of the \ref INVALID edge is -1.
170.287 - ///\return The ID of the edge \c e.
170.288 - static int id(Edge e) { return e.id; }
170.289 -
170.290 - /// Finds an edge between two nodes.
170.291 -
170.292 - /// Finds an edge from node \c u to node \c v.
170.293 - ///
170.294 - /// If \c prev is \ref INVALID (this is the default value), then
170.295 - /// It finds the first edge from \c u to \c v. Otherwise it looks for
170.296 - /// the next edge from \c u to \c v after \c prev.
170.297 - /// \return The found edge or INVALID if there is no such an edge.
170.298 - Edge findEdge(Node u,Node v, Edge prev = INVALID)
170.299 - {
170.300 - return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
170.301 - }
170.302 -
170.303 -
170.304 - class Node {
170.305 - friend class UndirFullGraphBase;
170.306 -
170.307 - protected:
170.308 - int id;
170.309 - Node(int _id) { id = _id;}
170.310 - public:
170.311 - Node() {}
170.312 - Node (Invalid) { id = -1; }
170.313 - bool operator==(const Node node) const {return id == node.id;}
170.314 - bool operator!=(const Node node) const {return id != node.id;}
170.315 - bool operator<(const Node node) const {return id < node.id;}
170.316 - };
170.317 -
170.318 -
170.319 -
170.320 - class Edge {
170.321 - friend class UndirFullGraphBase;
170.322 -
170.323 - protected:
170.324 - int id; // NodeNum * target + source;
170.325 -
170.326 - Edge(int _id) : id(_id) {}
170.327 -
170.328 - Edge(const UndirFullGraphBase& _graph, int source, int target)
170.329 - : id(_graph.NodeNum * target+source) {}
170.330 - public:
170.331 - Edge() { }
170.332 - Edge (Invalid) { id = -1; }
170.333 - bool operator==(const Edge edge) const {return id == edge.id;}
170.334 - bool operator!=(const Edge edge) const {return id != edge.id;}
170.335 - bool operator<(const Edge edge) const {return id < edge.id;}
170.336 - };
170.337 -
170.338 - void first(Node& node) const {
170.339 - node.id = NodeNum-1;
170.340 - }
170.341 -
170.342 - static void next(Node& node) {
170.343 - --node.id;
170.344 - }
170.345 -
170.346 - void first(Edge& edge) const {
170.347 - edge.id = EdgeNum-1;
170.348 - }
170.349 -
170.350 - static void next(Edge& edge) {
170.351 - --edge.id;
170.352 - }
170.353 -
170.354 - void firstOut(Edge& edge, const Node& node) const {
170.355 - edge.id = node.id != 0 ? node.id * (node.id - 1) / 2 : -1;
170.356 - }
170.357 -
170.358 - /// \todo with specialized iterators we can make faster iterating
170.359 - void nextOut(Edge& e) const {
170.360 - int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
170.361 - int target = e.id - (source) * (source - 1) / 2;
170.362 - ++target;
170.363 - e.id = target < source ? source * (source - 1) / 2 + target : -1;
170.364 - }
170.365 -
170.366 - void firstIn(Edge& edge, const Node& node) const {
170.367 - edge.id = node.id * (node.id + 1) / 2 - 1;
170.368 - }
170.369 -
170.370 - void nextIn(Edge& e) const {
170.371 - int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
170.372 - int target = e.id - (source) * (source - 1) / 2; ++target;
170.373 - ++source;
170.374 - e.id = source < NodeNum ? source * (source - 1) / 2 + target : -1;
170.375 - }
170.376 -
170.377 - };
170.378 -
170.379 - /// \todo UndirFullGraph from the UndirFullGraphBase
170.380 -
170.381 -
170.382 -
170.383 - /// @}
170.384 -
170.385 -} //namespace lemon
170.386 -
170.387 -
170.388 -#endif //LEMON_FULL_GRAPH_H
171.1 --- a/src/lemon/graph_adaptor.h Sat May 21 21:04:57 2005 +0000
171.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
171.3 @@ -1,1218 +0,0 @@
171.4 -/* -*- C++ -*-
171.5 - * src/lemon/graph_adaptor.h - Part of LEMON, a generic C++ optimization library
171.6 - *
171.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
171.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
171.9 - *
171.10 - * Permission to use, modify and distribute this software is granted
171.11 - * provided that this copyright notice appears in all copies. For
171.12 - * precise terms see the accompanying LICENSE file.
171.13 - *
171.14 - * This software is provided "AS IS" with no warranty of any kind,
171.15 - * express or implied, and with no claim as to its suitability for any
171.16 - * purpose.
171.17 - *
171.18 - */
171.19 -
171.20 -#ifndef LEMON_GRAPH_ADAPTOR_H
171.21 -#define LEMON_GRAPH_ADAPTOR_H
171.22 -
171.23 -///\ingroup graph_adaptors
171.24 -///\file
171.25 -///\brief Several graph adaptors.
171.26 -///
171.27 -///This file contains several useful graph adaptor functions.
171.28 -///
171.29 -///\author Marton Makai
171.30 -
171.31 -#include <lemon/invalid.h>
171.32 -#include <lemon/maps.h>
171.33 -#include <lemon/bits/iterable_graph_extender.h>
171.34 -#include <lemon/bits/undir_graph_extender.h>
171.35 -#include <iostream>
171.36 -
171.37 -namespace lemon {
171.38 -
171.39 - // Graph adaptors
171.40 -
171.41 - /*!
171.42 - \addtogroup graph_adaptors
171.43 - @{
171.44 - */
171.45 -
171.46 - /*!
171.47 - Base type for the Graph Adaptors
171.48 -
171.49 - \warning Graph adaptors are in even more experimental state than the other
171.50 - parts of the lib. Use them at you own risk.
171.51 -
171.52 - This is the base type for most of LEMON graph adaptors.
171.53 - This class implements a trivial graph adaptor i.e. it only wraps the
171.54 - functions and types of the graph. The purpose of this class is to
171.55 - make easier implementing graph adaptors. E.g. if an adaptor is
171.56 - considered which differs from the wrapped graph only in some of its
171.57 - functions or types, then it can be derived from GraphAdaptor, and only the
171.58 - differences should be implemented.
171.59 -
171.60 - \author Marton Makai
171.61 - */
171.62 - template<typename _Graph>
171.63 - class GraphAdaptorBase {
171.64 - public:
171.65 - typedef _Graph Graph;
171.66 - /// \todo Is it needed?
171.67 - typedef Graph BaseGraph;
171.68 - typedef Graph ParentGraph;
171.69 -
171.70 - protected:
171.71 - Graph* graph;
171.72 - GraphAdaptorBase() : graph(0) { }
171.73 - void setGraph(Graph& _graph) { graph=&_graph; }
171.74 -
171.75 - public:
171.76 - GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
171.77 -
171.78 - typedef typename Graph::Node Node;
171.79 - typedef typename Graph::Edge Edge;
171.80 -
171.81 - void first(Node& i) const { graph->first(i); }
171.82 - void first(Edge& i) const { graph->first(i); }
171.83 - void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
171.84 - void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
171.85 -
171.86 - void next(Node& i) const { graph->next(i); }
171.87 - void next(Edge& i) const { graph->next(i); }
171.88 - void nextIn(Edge& i) const { graph->nextIn(i); }
171.89 - void nextOut(Edge& i) const { graph->nextOut(i); }
171.90 -
171.91 - Node source(const Edge& e) const { return graph->source(e); }
171.92 - Node target(const Edge& e) const { return graph->target(e); }
171.93 -
171.94 - int nodeNum() const { return graph->nodeNum(); }
171.95 - int edgeNum() const { return graph->edgeNum(); }
171.96 -
171.97 - Node addNode() const { return Node(graph->addNode()); }
171.98 - Edge addEdge(const Node& source, const Node& target) const {
171.99 - return Edge(graph->addEdge(source, target)); }
171.100 -
171.101 - void erase(const Node& i) const { graph->erase(i); }
171.102 - void erase(const Edge& i) const { graph->erase(i); }
171.103 -
171.104 - void clear() const { graph->clear(); }
171.105 -
171.106 - bool forward(const Edge& e) const { return graph->forward(e); }
171.107 - bool backward(const Edge& e) const { return graph->backward(e); }
171.108 -
171.109 - int id(const Node& v) const { return graph->id(v); }
171.110 - int id(const Edge& e) const { return graph->id(e); }
171.111 -
171.112 - Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
171.113 -
171.114 - template <typename _Value>
171.115 - class NodeMap : public _Graph::template NodeMap<_Value> {
171.116 - public:
171.117 - typedef typename _Graph::template NodeMap<_Value> Parent;
171.118 - NodeMap(const GraphAdaptorBase<_Graph>& gw) : Parent(*gw.graph) { }
171.119 - NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
171.120 - : Parent(*gw.graph, value) { }
171.121 - };
171.122 -
171.123 - template <typename _Value>
171.124 - class EdgeMap : public _Graph::template EdgeMap<_Value> {
171.125 - public:
171.126 - typedef typename _Graph::template EdgeMap<_Value> Parent;
171.127 - EdgeMap(const GraphAdaptorBase<_Graph>& gw) : Parent(*gw.graph) { }
171.128 - EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
171.129 - : Parent(*gw.graph, value) { }
171.130 - };
171.131 -
171.132 - };
171.133 -
171.134 - template <typename _Graph>
171.135 - class GraphAdaptor :
171.136 - public IterableGraphExtender<GraphAdaptorBase<_Graph> > {
171.137 - public:
171.138 - typedef _Graph Graph;
171.139 - typedef IterableGraphExtender<GraphAdaptorBase<_Graph> > Parent;
171.140 - protected:
171.141 - GraphAdaptor() : Parent() { }
171.142 -
171.143 - public:
171.144 - GraphAdaptor(Graph& _graph) { setGraph(_graph); }
171.145 - };
171.146 -
171.147 - template <typename _Graph>
171.148 - class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
171.149 - public:
171.150 - typedef _Graph Graph;
171.151 - typedef GraphAdaptorBase<_Graph> Parent;
171.152 - protected:
171.153 - RevGraphAdaptorBase() : Parent() { }
171.154 - public:
171.155 - typedef typename Parent::Node Node;
171.156 - typedef typename Parent::Edge Edge;
171.157 -
171.158 - // using Parent::first;
171.159 - void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
171.160 - void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
171.161 -
171.162 - // using Parent::next;
171.163 - void nextIn(Edge& i) const { Parent::nextOut(i); }
171.164 - void nextOut(Edge& i) const { Parent::nextIn(i); }
171.165 -
171.166 - Node source(const Edge& e) const { return Parent::target(e); }
171.167 - Node target(const Edge& e) const { return Parent::source(e); }
171.168 - };
171.169 -
171.170 -
171.171 - /// A graph adaptor which reverses the orientation of the edges.
171.172 -
171.173 - ///\warning Graph adaptors are in even more experimental state than the other
171.174 - ///parts of the lib. Use them at you own risk.
171.175 - ///
171.176 - /// Let \f$G=(V, A)\f$ be a directed graph and
171.177 - /// suppose that a graph instange \c g of type
171.178 - /// \c ListGraph implements \f$G\f$.
171.179 - /// \code
171.180 - /// ListGraph g;
171.181 - /// \endcode
171.182 - /// For each directed edge
171.183 - /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
171.184 - /// reversing its orientation.
171.185 - /// Then RevGraphAdaptor implements the graph structure with node-set
171.186 - /// \f$V\f$ and edge-set
171.187 - /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be
171.188 - /// reversing the orientation of its edges. The following code shows how
171.189 - /// such an instance can be constructed.
171.190 - /// \code
171.191 - /// RevGraphAdaptor<ListGraph> gw(g);
171.192 - /// \endcode
171.193 - ///\author Marton Makai
171.194 - template<typename _Graph>
171.195 - class RevGraphAdaptor :
171.196 - public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
171.197 - public:
171.198 - typedef _Graph Graph;
171.199 - typedef IterableGraphExtender<
171.200 - RevGraphAdaptorBase<_Graph> > Parent;
171.201 - protected:
171.202 - RevGraphAdaptor() { }
171.203 - public:
171.204 - RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
171.205 - };
171.206 -
171.207 -
171.208 - template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
171.209 - class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
171.210 - public:
171.211 - typedef _Graph Graph;
171.212 - typedef GraphAdaptorBase<_Graph> Parent;
171.213 - protected:
171.214 - NodeFilterMap* node_filter_map;
171.215 - EdgeFilterMap* edge_filter_map;
171.216 - SubGraphAdaptorBase() : Parent(),
171.217 - node_filter_map(0), edge_filter_map(0) { }
171.218 -
171.219 - void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
171.220 - node_filter_map=&_node_filter_map;
171.221 - }
171.222 - void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
171.223 - edge_filter_map=&_edge_filter_map;
171.224 - }
171.225 -
171.226 - public:
171.227 -// SubGraphAdaptorBase(Graph& _graph,
171.228 -// NodeFilterMap& _node_filter_map,
171.229 -// EdgeFilterMap& _edge_filter_map) :
171.230 -// Parent(&_graph),
171.231 -// node_filter_map(&node_filter_map),
171.232 -// edge_filter_map(&edge_filter_map) { }
171.233 -
171.234 - typedef typename Parent::Node Node;
171.235 - typedef typename Parent::Edge Edge;
171.236 -
171.237 - void first(Node& i) const {
171.238 - Parent::first(i);
171.239 - while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
171.240 - }
171.241 - void first(Edge& i) const {
171.242 - Parent::first(i);
171.243 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
171.244 - }
171.245 - void firstIn(Edge& i, const Node& n) const {
171.246 - Parent::firstIn(i, n);
171.247 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
171.248 - }
171.249 - void firstOut(Edge& i, const Node& n) const {
171.250 - Parent::firstOut(i, n);
171.251 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
171.252 - }
171.253 -
171.254 - void next(Node& i) const {
171.255 - Parent::next(i);
171.256 - while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
171.257 - }
171.258 - void next(Edge& i) const {
171.259 - Parent::next(i);
171.260 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
171.261 - }
171.262 - void nextIn(Edge& i) const {
171.263 - Parent::nextIn(i);
171.264 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
171.265 - }
171.266 - void nextOut(Edge& i) const {
171.267 - Parent::nextOut(i);
171.268 - while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
171.269 - }
171.270 -
171.271 - /// This function hides \c n in the graph, i.e. the iteration
171.272 - /// jumps over it. This is done by simply setting the value of \c n
171.273 - /// to be false in the corresponding node-map.
171.274 - void hide(const Node& n) const { node_filter_map->set(n, false); }
171.275 -
171.276 - /// This function hides \c e in the graph, i.e. the iteration
171.277 - /// jumps over it. This is done by simply setting the value of \c e
171.278 - /// to be false in the corresponding edge-map.
171.279 - void hide(const Edge& e) const { edge_filter_map->set(e, false); }
171.280 -
171.281 - /// The value of \c n is set to be true in the node-map which stores
171.282 - /// hide information. If \c n was hidden previuosly, then it is shown
171.283 - /// again
171.284 - void unHide(const Node& n) const { node_filter_map->set(n, true); }
171.285 -
171.286 - /// The value of \c e is set to be true in the edge-map which stores
171.287 - /// hide information. If \c e was hidden previuosly, then it is shown
171.288 - /// again
171.289 - void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
171.290 -
171.291 - /// Returns true if \c n is hidden.
171.292 - bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
171.293 -
171.294 - /// Returns true if \c n is hidden.
171.295 - bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
171.296 -
171.297 - /// \warning This is a linear time operation and works only if s
171.298 - /// \c Graph::NodeIt is defined.
171.299 - /// \todo assign tags.
171.300 - int nodeNum() const {
171.301 - int i=0;
171.302 - Node n;
171.303 - for (first(n); n!=INVALID; next(n)) ++i;
171.304 - return i;
171.305 - }
171.306 -
171.307 - /// \warning This is a linear time operation and works only if
171.308 - /// \c Graph::EdgeIt is defined.
171.309 - /// \todo assign tags.
171.310 - int edgeNum() const {
171.311 - int i=0;
171.312 - Edge e;
171.313 - for (first(e); e!=INVALID; next(e)) ++i;
171.314 - return i;
171.315 - }
171.316 -
171.317 -
171.318 - };
171.319 -
171.320 - /*! \brief A graph adaptor for hiding nodes and edges from a graph.
171.321 -
171.322 - \warning Graph adaptors are in even more experimental state than the other
171.323 - parts of the lib. Use them at you own risk.
171.324 -
171.325 - SubGraphAdaptor shows the graph with filtered node-set and
171.326 - edge-set.
171.327 - Let \f$G=(V, A)\f$ be a directed graph
171.328 - and suppose that the graph instance \c g of type ListGraph implements
171.329 - \f$G\f$.
171.330 - Let moreover \f$b_V\f$ and
171.331 - \f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set.
171.332 - SubGraphAdaptor<...>::NodeIt iterates
171.333 - on the node-set \f$\{v\in V : b_V(v)=true\}\f$ and
171.334 - SubGraphAdaptor<...>::EdgeIt iterates
171.335 - on the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly,
171.336 - SubGraphAdaptor<...>::OutEdgeIt and SubGraphAdaptor<...>::InEdgeIt iterates
171.337 - only on edges leaving and entering a specific node which have true value.
171.338 -
171.339 - We have to note that this does not mean that an
171.340 - induced subgraph is obtained, the node-iterator cares only the filter
171.341 - on the node-set, and the edge-iterators care only the filter on the
171.342 - edge-set.
171.343 - \code
171.344 - typedef ListGraph Graph;
171.345 - Graph g;
171.346 - typedef Graph::Node Node;
171.347 - typedef Graph::Edge Edge;
171.348 - Node u=g.addNode(); //node of id 0
171.349 - Node v=g.addNode(); //node of id 1
171.350 - Node e=g.addEdge(u, v); //edge of id 0
171.351 - Node f=g.addEdge(v, u); //edge of id 1
171.352 - Graph::NodeMap<bool> nm(g, true);
171.353 - nm.set(u, false);
171.354 - Graph::EdgeMap<bool> em(g, true);
171.355 - em.set(e, false);
171.356 - typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
171.357 - SubGW gw(g, nm, em);
171.358 - for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
171.359 - std::cout << ":-)" << std::endl;
171.360 - for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
171.361 - \endcode
171.362 - The output of the above code is the following.
171.363 - \code
171.364 - 1
171.365 - :-)
171.366 - 1
171.367 - \endcode
171.368 - Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
171.369 - \c Graph::Node that is why \c g.id(n) can be applied.
171.370 -
171.371 - For other examples see also the documentation of NodeSubGraphAdaptor and
171.372 - EdgeSubGraphAdaptor.
171.373 -
171.374 - \author Marton Makai
171.375 - */
171.376 - template<typename _Graph, typename NodeFilterMap,
171.377 - typename EdgeFilterMap>
171.378 - class SubGraphAdaptor :
171.379 - public IterableGraphExtender<
171.380 - SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > {
171.381 - public:
171.382 - typedef _Graph Graph;
171.383 - typedef IterableGraphExtender<
171.384 - SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
171.385 - protected:
171.386 - SubGraphAdaptor() { }
171.387 - public:
171.388 - SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
171.389 - EdgeFilterMap& _edge_filter_map) {
171.390 - setGraph(_graph);
171.391 - setNodeFilterMap(_node_filter_map);
171.392 - setEdgeFilterMap(_edge_filter_map);
171.393 - }
171.394 - };
171.395 -
171.396 -
171.397 -
171.398 - /*! \brief An adaptor for hiding nodes from a graph.
171.399 -
171.400 - \warning Graph adaptors are in even more experimental state than the other
171.401 - parts of the lib. Use them at you own risk.
171.402 -
171.403 - An adaptor for hiding nodes from a graph.
171.404 - This adaptor specializes SubGraphAdaptor in the way that only the node-set
171.405 - can be filtered. Note that this does not mean of considering induced
171.406 - subgraph, the edge-iterators consider the original edge-set.
171.407 - \author Marton Makai
171.408 - */
171.409 - template<typename Graph, typename NodeFilterMap>
171.410 - class NodeSubGraphAdaptor :
171.411 - public SubGraphAdaptor<Graph, NodeFilterMap,
171.412 - ConstMap<typename Graph::Edge,bool> > {
171.413 - public:
171.414 - typedef SubGraphAdaptor<Graph, NodeFilterMap,
171.415 - ConstMap<typename Graph::Edge,bool> > Parent;
171.416 - protected:
171.417 - ConstMap<typename Graph::Edge, bool> const_true_map;
171.418 - public:
171.419 - NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
171.420 - Parent(), const_true_map(true) {
171.421 - Parent::setGraph(_graph);
171.422 - Parent::setNodeFilterMap(_node_filter_map);
171.423 - Parent::setEdgeFilterMap(const_true_map);
171.424 - }
171.425 - };
171.426 -
171.427 -
171.428 - /*! \brief An adaptor for hiding edges from a graph.
171.429 -
171.430 - \warning Graph adaptors are in even more experimental state than the other
171.431 - parts of the lib. Use them at you own risk.
171.432 -
171.433 - An adaptor for hiding edges from a graph.
171.434 - This adaptor specializes SubGraphAdaptor in the way that only the edge-set
171.435 - can be filtered. The usefulness of this adaptor is demonstrated in the
171.436 - problem of searching a maximum number of edge-disjoint shortest paths
171.437 - between
171.438 - two nodes \c s and \c t. Shortest here means being shortest w.r.t.
171.439 - non-negative edge-lengths. Note that
171.440 - the comprehension of the presented solution
171.441 - need's some elementary knowledge from combinatorial optimization.
171.442 -
171.443 - If a single shortest path is to be
171.444 - searched between \c s and \c t, then this can be done easily by
171.445 - applying the Dijkstra algorithm. What happens, if a maximum number of
171.446 - edge-disjoint shortest paths is to be computed. It can be proved that an
171.447 - edge can be in a shortest path if and only if it is tight with respect to
171.448 - the potential function computed by Dijkstra. Moreover, any path containing
171.449 - only such edges is a shortest one. Thus we have to compute a maximum number
171.450 - of edge-disjoint paths between \c s and \c t in the graph which has edge-set
171.451 - all the tight edges. The computation will be demonstrated on the following
171.452 - graph, which is read from the dimacs file \ref sub_graph_adaptor_demo.dim.
171.453 - The full source code is available in \ref sub_graph_adaptor_demo.cc.
171.454 - If you are interested in more demo programs, you can use
171.455 - \ref dim_to_dot.cc to generate .dot files from dimacs files.
171.456 - The .dot file of the following figure of was generated generated by
171.457 - the demo program \ref dim_to_dot.cc.
171.458 -
171.459 - \dot
171.460 - digraph lemon_dot_example {
171.461 - node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
171.462 - n0 [ label="0 (s)" ];
171.463 - n1 [ label="1" ];
171.464 - n2 [ label="2" ];
171.465 - n3 [ label="3" ];
171.466 - n4 [ label="4" ];
171.467 - n5 [ label="5" ];
171.468 - n6 [ label="6 (t)" ];
171.469 - edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
171.470 - n5 -> n6 [ label="9, length:4" ];
171.471 - n4 -> n6 [ label="8, length:2" ];
171.472 - n3 -> n5 [ label="7, length:1" ];
171.473 - n2 -> n5 [ label="6, length:3" ];
171.474 - n2 -> n6 [ label="5, length:5" ];
171.475 - n2 -> n4 [ label="4, length:2" ];
171.476 - n1 -> n4 [ label="3, length:3" ];
171.477 - n0 -> n3 [ label="2, length:1" ];
171.478 - n0 -> n2 [ label="1, length:2" ];
171.479 - n0 -> n1 [ label="0, length:3" ];
171.480 - }
171.481 - \enddot
171.482 -
171.483 - \code
171.484 - Graph g;
171.485 - Node s, t;
171.486 - LengthMap length(g);
171.487 -
171.488 - readDimacs(std::cin, g, length, s, t);
171.489 -
171.490 - cout << "edges with lengths (of form id, source--length->target): " << endl;
171.491 - for(EdgeIt e(g); e!=INVALID; ++e)
171.492 - cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
171.493 - << length[e] << "->" << g.id(g.target(e)) << endl;
171.494 -
171.495 - cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
171.496 - \endcode
171.497 - Next, the potential function is computed with Dijkstra.
171.498 - \code
171.499 - typedef Dijkstra<Graph, LengthMap> Dijkstra;
171.500 - Dijkstra dijkstra(g, length);
171.501 - dijkstra.run(s);
171.502 - \endcode
171.503 - Next, we consrtruct a map which filters the edge-set to the tight edges.
171.504 - \code
171.505 - typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
171.506 - TightEdgeFilter;
171.507 - TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
171.508 -
171.509 - typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
171.510 - SubGW gw(g, tight_edge_filter);
171.511 - \endcode
171.512 - Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
171.513 - with a max flow algorithm Preflow.
171.514 - \code
171.515 - ConstMap<Edge, int> const_1_map(1);
171.516 - Graph::EdgeMap<int> flow(g, 0);
171.517 -
171.518 - Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
171.519 - preflow(gw, s, t, const_1_map, flow);
171.520 - preflow.run();
171.521 - \endcode
171.522 - Last, the output is:
171.523 - \code
171.524 - cout << "maximum number of edge-disjoint shortest path: "
171.525 - << preflow.flowValue() << endl;
171.526 - cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
171.527 - << endl;
171.528 - for(EdgeIt e(g); e!=INVALID; ++e)
171.529 - if (flow[e])
171.530 - cout << " " << g.id(g.source(e)) << "--"
171.531 - << length[e] << "->" << g.id(g.target(e)) << endl;
171.532 - \endcode
171.533 - The program has the following (expected :-)) output:
171.534 - \code
171.535 - edges with lengths (of form id, source--length->target):
171.536 - 9, 5--4->6
171.537 - 8, 4--2->6
171.538 - 7, 3--1->5
171.539 - 6, 2--3->5
171.540 - 5, 2--5->6
171.541 - 4, 2--2->4
171.542 - 3, 1--3->4
171.543 - 2, 0--1->3
171.544 - 1, 0--2->2
171.545 - 0, 0--3->1
171.546 - s: 0 t: 6
171.547 - maximum number of edge-disjoint shortest path: 2
171.548 - edges of the maximum number of edge-disjoint shortest s-t paths:
171.549 - 9, 5--4->6
171.550 - 8, 4--2->6
171.551 - 7, 3--1->5
171.552 - 4, 2--2->4
171.553 - 2, 0--1->3
171.554 - 1, 0--2->2
171.555 - \endcode
171.556 -
171.557 - \author Marton Makai
171.558 - */
171.559 - template<typename Graph, typename EdgeFilterMap>
171.560 - class EdgeSubGraphAdaptor :
171.561 - public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
171.562 - EdgeFilterMap> {
171.563 - public:
171.564 - typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
171.565 - EdgeFilterMap> Parent;
171.566 - protected:
171.567 - ConstMap<typename Graph::Node, bool> const_true_map;
171.568 - public:
171.569 - EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
171.570 - Parent(), const_true_map(true) {
171.571 - Parent::setGraph(_graph);
171.572 - Parent::setNodeFilterMap(const_true_map);
171.573 - Parent::setEdgeFilterMap(_edge_filter_map);
171.574 - }
171.575 - };
171.576 -
171.577 - template <typename _Graph>
171.578 - class UndirGraphAdaptorBase :
171.579 - public UndirGraphExtender<GraphAdaptorBase<_Graph> > {
171.580 - public:
171.581 - typedef _Graph Graph;
171.582 - typedef UndirGraphExtender<GraphAdaptorBase<_Graph> > Parent;
171.583 - protected:
171.584 - UndirGraphAdaptorBase() : Parent() { }
171.585 - public:
171.586 - typedef typename Parent::UndirEdge UndirEdge;
171.587 - typedef typename Parent::Edge Edge;
171.588 -
171.589 - /// \bug Why cant an edge say that it is forward or not???
171.590 - /// By this, a pointer to the graph have to be stored
171.591 - /// The implementation
171.592 - template <typename T>
171.593 - class EdgeMap {
171.594 - protected:
171.595 - const UndirGraphAdaptorBase<_Graph>* g;
171.596 - template <typename TT> friend class EdgeMap;
171.597 - typename _Graph::template EdgeMap<T> forward_map, backward_map;
171.598 - public:
171.599 - typedef T Value;
171.600 - typedef Edge Key;
171.601 -
171.602 - EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : g(&_g),
171.603 - forward_map(*(g->graph)), backward_map(*(g->graph)) { }
171.604 -
171.605 - EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, T a) : g(&_g),
171.606 - forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
171.607 -
171.608 - void set(Edge e, T a) {
171.609 - if (g->forward(e))
171.610 - forward_map.set(e, a);
171.611 - else
171.612 - backward_map.set(e, a);
171.613 - }
171.614 -
171.615 - T operator[](Edge e) const {
171.616 - if (g->forward(e))
171.617 - return forward_map[e];
171.618 - else
171.619 - return backward_map[e];
171.620 - }
171.621 - };
171.622 -
171.623 - template <typename T>
171.624 - class UndirEdgeMap {
171.625 - template <typename TT> friend class UndirEdgeMap;
171.626 - typename _Graph::template EdgeMap<T> map;
171.627 - public:
171.628 - typedef T Value;
171.629 - typedef UndirEdge Key;
171.630 -
171.631 - UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) :
171.632 - map(*(g.graph)) { }
171.633 -
171.634 - UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, T a) :
171.635 - map(*(g.graph), a) { }
171.636 -
171.637 - void set(UndirEdge e, T a) {
171.638 - map.set(e, a);
171.639 - }
171.640 -
171.641 - T operator[](UndirEdge e) const {
171.642 - return map[e];
171.643 - }
171.644 - };
171.645 -
171.646 - };
171.647 -
171.648 - /// \brief An undirected graph is made from a directed graph by an adaptor
171.649 - ///
171.650 - /// Undocumented, untested!!!
171.651 - /// If somebody knows nice demo application, let's polulate it.
171.652 - ///
171.653 - /// \author Marton Makai
171.654 - template<typename _Graph>
171.655 - class UndirGraphAdaptor :
171.656 - public IterableUndirGraphExtender<
171.657 - UndirGraphAdaptorBase<_Graph> > {
171.658 - public:
171.659 - typedef _Graph Graph;
171.660 - typedef IterableUndirGraphExtender<
171.661 - UndirGraphAdaptorBase<_Graph> > Parent;
171.662 - protected:
171.663 - UndirGraphAdaptor() { }
171.664 - public:
171.665 - UndirGraphAdaptor(_Graph& _graph) {
171.666 - setGraph(_graph);
171.667 - }
171.668 - };
171.669 -
171.670 -
171.671 - template <typename _Graph,
171.672 - typename ForwardFilterMap, typename BackwardFilterMap>
171.673 - class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
171.674 - public:
171.675 - typedef _Graph Graph;
171.676 - typedef GraphAdaptorBase<_Graph> Parent;
171.677 - protected:
171.678 - ForwardFilterMap* forward_filter;
171.679 - BackwardFilterMap* backward_filter;
171.680 - SubBidirGraphAdaptorBase() : Parent(),
171.681 - forward_filter(0), backward_filter(0) { }
171.682 -
171.683 - void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
171.684 - forward_filter=&_forward_filter;
171.685 - }
171.686 - void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
171.687 - backward_filter=&_backward_filter;
171.688 - }
171.689 -
171.690 - public:
171.691 -// SubGraphAdaptorBase(Graph& _graph,
171.692 -// NodeFilterMap& _node_filter_map,
171.693 -// EdgeFilterMap& _edge_filter_map) :
171.694 -// Parent(&_graph),
171.695 -// node_filter_map(&node_filter_map),
171.696 -// edge_filter_map(&edge_filter_map) { }
171.697 -
171.698 - typedef typename Parent::Node Node;
171.699 - typedef typename _Graph::Edge GraphEdge;
171.700 - template <typename T> class EdgeMap;
171.701 - /// SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from
171.702 - /// _Graph::Edge. It contains an extra bool flag which is true
171.703 - /// if and only if the
171.704 - /// edge is the backward version of the original edge.
171.705 - class Edge : public _Graph::Edge {
171.706 - friend class SubBidirGraphAdaptorBase<
171.707 - Graph, ForwardFilterMap, BackwardFilterMap>;
171.708 - template<typename T> friend class EdgeMap;
171.709 - protected:
171.710 - bool backward; //true, iff backward
171.711 - public:
171.712 - Edge() { }
171.713 - /// \todo =false is needed, or causes problems?
171.714 - /// If \c _backward is false, then we get an edge corresponding to the
171.715 - /// original one, otherwise its oppositely directed pair is obtained.
171.716 - Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) :
171.717 - _Graph::Edge(e), backward(_backward) { }
171.718 - Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
171.719 - bool operator==(const Edge& v) const {
171.720 - return (this->backward==v.backward &&
171.721 - static_cast<typename _Graph::Edge>(*this)==
171.722 - static_cast<typename _Graph::Edge>(v));
171.723 - }
171.724 - bool operator!=(const Edge& v) const {
171.725 - return (this->backward!=v.backward ||
171.726 - static_cast<typename _Graph::Edge>(*this)!=
171.727 - static_cast<typename _Graph::Edge>(v));
171.728 - }
171.729 - };
171.730 -
171.731 - void first(Node& i) const {
171.732 - Parent::first(i);
171.733 - }
171.734 -
171.735 - void first(Edge& i) const {
171.736 - Parent::first(i);
171.737 - i.backward=false;
171.738 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.739 - !(*forward_filter)[i]) Parent::next(i);
171.740 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.741 - Parent::first(i);
171.742 - i.backward=true;
171.743 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.744 - !(*backward_filter)[i]) Parent::next(i);
171.745 - }
171.746 - }
171.747 -
171.748 - void firstIn(Edge& i, const Node& n) const {
171.749 - Parent::firstIn(i, n);
171.750 - i.backward=false;
171.751 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.752 - !(*forward_filter)[i]) Parent::nextIn(i);
171.753 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.754 - Parent::firstOut(i, n);
171.755 - i.backward=true;
171.756 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.757 - !(*backward_filter)[i]) Parent::nextOut(i);
171.758 - }
171.759 - }
171.760 -
171.761 - void firstOut(Edge& i, const Node& n) const {
171.762 - Parent::firstOut(i, n);
171.763 - i.backward=false;
171.764 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.765 - !(*forward_filter)[i]) Parent::nextOut(i);
171.766 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.767 - Parent::firstIn(i, n);
171.768 - i.backward=true;
171.769 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.770 - !(*backward_filter)[i]) Parent::nextIn(i);
171.771 - }
171.772 - }
171.773 -
171.774 - void next(Node& i) const {
171.775 - Parent::next(i);
171.776 - }
171.777 -
171.778 - void next(Edge& i) const {
171.779 - if (!(i.backward)) {
171.780 - Parent::next(i);
171.781 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.782 - !(*forward_filter)[i]) Parent::next(i);
171.783 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.784 - Parent::first(i);
171.785 - i.backward=true;
171.786 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.787 - !(*backward_filter)[i]) Parent::next(i);
171.788 - }
171.789 - } else {
171.790 - Parent::next(i);
171.791 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.792 - !(*backward_filter)[i]) Parent::next(i);
171.793 - }
171.794 - }
171.795 -
171.796 - void nextIn(Edge& i) const {
171.797 - if (!(i.backward)) {
171.798 - Node n=Parent::target(i);
171.799 - Parent::nextIn(i);
171.800 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.801 - !(*forward_filter)[i]) Parent::nextIn(i);
171.802 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.803 - Parent::firstOut(i, n);
171.804 - i.backward=true;
171.805 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.806 - !(*backward_filter)[i]) Parent::nextOut(i);
171.807 - }
171.808 - } else {
171.809 - Parent::nextOut(i);
171.810 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.811 - !(*backward_filter)[i]) Parent::nextOut(i);
171.812 - }
171.813 - }
171.814 -
171.815 - void nextOut(Edge& i) const {
171.816 - if (!(i.backward)) {
171.817 - Node n=Parent::source(i);
171.818 - Parent::nextOut(i);
171.819 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.820 - !(*forward_filter)[i]) Parent::nextOut(i);
171.821 - if (*static_cast<GraphEdge*>(&i)==INVALID) {
171.822 - Parent::firstIn(i, n);
171.823 - i.backward=true;
171.824 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.825 - !(*backward_filter)[i]) Parent::nextIn(i);
171.826 - }
171.827 - } else {
171.828 - Parent::nextIn(i);
171.829 - while (*static_cast<GraphEdge*>(&i)!=INVALID &&
171.830 - !(*backward_filter)[i]) Parent::nextIn(i);
171.831 - }
171.832 - }
171.833 -
171.834 - Node source(Edge e) const {
171.835 - return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
171.836 - Node target(Edge e) const {
171.837 - return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
171.838 -
171.839 - /// Gives back the opposite edge.
171.840 - Edge opposite(const Edge& e) const {
171.841 - Edge f=e;
171.842 - f.backward=!f.backward;
171.843 - return f;
171.844 - }
171.845 -
171.846 - /// \warning This is a linear time operation and works only if
171.847 - /// \c Graph::EdgeIt is defined.
171.848 - /// \todo hmm
171.849 - int edgeNum() const {
171.850 - int i=0;
171.851 - Edge e;
171.852 - for (first(e); e!=INVALID; next(e)) ++i;
171.853 - return i;
171.854 - }
171.855 -
171.856 - bool forward(const Edge& e) const { return !e.backward; }
171.857 - bool backward(const Edge& e) const { return e.backward; }
171.858 -
171.859 - template <typename T>
171.860 - /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two
171.861 - /// _Graph::EdgeMap one for the forward edges and
171.862 - /// one for the backward edges.
171.863 - class EdgeMap {
171.864 - template <typename TT> friend class EdgeMap;
171.865 - typename _Graph::template EdgeMap<T> forward_map, backward_map;
171.866 - public:
171.867 - typedef T Value;
171.868 - typedef Edge Key;
171.869 -
171.870 - EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
171.871 - ForwardFilterMap, BackwardFilterMap>& g) :
171.872 - forward_map(*(g.graph)), backward_map(*(g.graph)) { }
171.873 -
171.874 - EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
171.875 - ForwardFilterMap, BackwardFilterMap>& g, T a) :
171.876 - forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
171.877 -
171.878 - void set(Edge e, T a) {
171.879 - if (!e.backward)
171.880 - forward_map.set(e, a);
171.881 - else
171.882 - backward_map.set(e, a);
171.883 - }
171.884 -
171.885 -// typename _Graph::template EdgeMap<T>::ConstReference
171.886 -// operator[](Edge e) const {
171.887 -// if (!e.backward)
171.888 -// return forward_map[e];
171.889 -// else
171.890 -// return backward_map[e];
171.891 -// }
171.892 -
171.893 -// typename _Graph::template EdgeMap<T>::Reference
171.894 - T operator[](Edge e) const {
171.895 - if (!e.backward)
171.896 - return forward_map[e];
171.897 - else
171.898 - return backward_map[e];
171.899 - }
171.900 -
171.901 - void update() {
171.902 - forward_map.update();
171.903 - backward_map.update();
171.904 - }
171.905 - };
171.906 -
171.907 - };
171.908 -
171.909 -
171.910 - ///\brief An adaptor for composing a subgraph of a
171.911 - /// bidirected graph made from a directed one.
171.912 - ///
171.913 - /// An adaptor for composing a subgraph of a
171.914 - /// bidirected graph made from a directed one.
171.915 - ///
171.916 - ///\warning Graph adaptors are in even more experimental state than the other
171.917 - ///parts of the lib. Use them at you own risk.
171.918 - ///
171.919 - /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge
171.920 - /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
171.921 - /// reversing its orientation. We are given moreover two bool valued
171.922 - /// maps on the edge-set,
171.923 - /// \f$forward\_filter\f$, and \f$backward\_filter\f$.
171.924 - /// SubBidirGraphAdaptor implements the graph structure with node-set
171.925 - /// \f$V\f$ and edge-set
171.926 - /// \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$.
171.927 - /// The purpose of writing + instead of union is because parallel
171.928 - /// edges can arise. (Similarly, antiparallel edges also can arise).
171.929 - /// In other words, a subgraph of the bidirected graph obtained, which
171.930 - /// is given by orienting the edges of the original graph in both directions.
171.931 - /// As the oppositely directed edges are logically different,
171.932 - /// the maps are able to attach different values for them.
171.933 - ///
171.934 - /// An example for such a construction is \c RevGraphAdaptor where the
171.935 - /// forward_filter is everywhere false and the backward_filter is
171.936 - /// everywhere true. We note that for sake of efficiency,
171.937 - /// \c RevGraphAdaptor is implemented in a different way.
171.938 - /// But BidirGraphAdaptor is obtained from
171.939 - /// SubBidirGraphAdaptor by considering everywhere true
171.940 - /// valued maps both for forward_filter and backward_filter.
171.941 - ///
171.942 - /// The most important application of SubBidirGraphAdaptor
171.943 - /// is ResGraphAdaptor, which stands for the residual graph in directed
171.944 - /// flow and circulation problems.
171.945 - /// As adaptors usually, the SubBidirGraphAdaptor implements the
171.946 - /// above mentioned graph structure without its physical storage,
171.947 - /// that is the whole stuff is stored in constant memory.
171.948 - template<typename _Graph,
171.949 - typename ForwardFilterMap, typename BackwardFilterMap>
171.950 - class SubBidirGraphAdaptor :
171.951 - public IterableGraphExtender<
171.952 - SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
171.953 - public:
171.954 - typedef _Graph Graph;
171.955 - typedef IterableGraphExtender<
171.956 - SubBidirGraphAdaptorBase<
171.957 - _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
171.958 - protected:
171.959 - SubBidirGraphAdaptor() { }
171.960 - public:
171.961 - SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter,
171.962 - BackwardFilterMap& _backward_filter) {
171.963 - setGraph(_graph);
171.964 - setForwardFilterMap(_forward_filter);
171.965 - setBackwardFilterMap(_backward_filter);
171.966 - }
171.967 - };
171.968 -
171.969 -
171.970 -
171.971 - ///\brief An adaptor for composing bidirected graph from a directed one.
171.972 - ///
171.973 - ///\warning Graph adaptors are in even more experimental state than the other
171.974 - ///parts of the lib. Use them at you own risk.
171.975 - ///
171.976 - /// An adaptor for composing bidirected graph from a directed one.
171.977 - /// A bidirected graph is composed over the directed one without physical
171.978 - /// storage. As the oppositely directed edges are logically different ones
171.979 - /// the maps are able to attach different values for them.
171.980 - template<typename Graph>
171.981 - class BidirGraphAdaptor :
171.982 - public SubBidirGraphAdaptor<
171.983 - Graph,
171.984 - ConstMap<typename Graph::Edge, bool>,
171.985 - ConstMap<typename Graph::Edge, bool> > {
171.986 - public:
171.987 - typedef SubBidirGraphAdaptor<
171.988 - Graph,
171.989 - ConstMap<typename Graph::Edge, bool>,
171.990 - ConstMap<typename Graph::Edge, bool> > Parent;
171.991 - protected:
171.992 - ConstMap<typename Graph::Edge, bool> cm;
171.993 -
171.994 - BidirGraphAdaptor() : Parent(), cm(true) {
171.995 - Parent::setForwardFilterMap(cm);
171.996 - Parent::setBackwardFilterMap(cm);
171.997 - }
171.998 - public:
171.999 - BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) {
171.1000 - Parent::setGraph(_graph);
171.1001 - Parent::setForwardFilterMap(cm);
171.1002 - Parent::setBackwardFilterMap(cm);
171.1003 - }
171.1004 -
171.1005 - int edgeNum() const {
171.1006 - return 2*this->graph->edgeNum();
171.1007 - }
171.1008 - // KEEP_MAPS(Parent, BidirGraphAdaptor);
171.1009 - };
171.1010 -
171.1011 -
171.1012 - template<typename Graph, typename Number,
171.1013 - typename CapacityMap, typename FlowMap>
171.1014 - class ResForwardFilter {
171.1015 - // const Graph* graph;
171.1016 - const CapacityMap* capacity;
171.1017 - const FlowMap* flow;
171.1018 - public:
171.1019 - ResForwardFilter(/*const Graph& _graph, */
171.1020 - const CapacityMap& _capacity, const FlowMap& _flow) :
171.1021 - /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
171.1022 - ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
171.1023 - void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
171.1024 - void setFlow(const FlowMap& _flow) { flow=&_flow; }
171.1025 - bool operator[](const typename Graph::Edge& e) const {
171.1026 - return (Number((*flow)[e]) < Number((*capacity)[e]));
171.1027 - }
171.1028 - };
171.1029 -
171.1030 - template<typename Graph, typename Number,
171.1031 - typename CapacityMap, typename FlowMap>
171.1032 - class ResBackwardFilter {
171.1033 - const CapacityMap* capacity;
171.1034 - const FlowMap* flow;
171.1035 - public:
171.1036 - ResBackwardFilter(/*const Graph& _graph,*/
171.1037 - const CapacityMap& _capacity, const FlowMap& _flow) :
171.1038 - /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
171.1039 - ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
171.1040 - void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
171.1041 - void setFlow(const FlowMap& _flow) { flow=&_flow; }
171.1042 - bool operator[](const typename Graph::Edge& e) const {
171.1043 - return (Number(0) < Number((*flow)[e]));
171.1044 - }
171.1045 - };
171.1046 -
171.1047 -
171.1048 - /*! \brief An adaptor for composing the residual graph for directed flow and circulation problems.
171.1049 -
171.1050 - An adaptor for composing the residual graph for directed flow and circulation problems.
171.1051 - Let \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a
171.1052 - number type. Let moreover
171.1053 - \f$f,c:A\to F\f$, be functions on the edge-set.
171.1054 - In the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow
171.1055 - and \f$c\f$ for a capacity function.
171.1056 - Suppose that a graph instange \c g of type
171.1057 - \c ListGraph implements \f$G\f$.
171.1058 - \code
171.1059 - ListGraph g;
171.1060 - \endcode
171.1061 - Then RevGraphAdaptor implements the graph structure with node-set
171.1062 - \f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where
171.1063 - \f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and
171.1064 - \f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$,
171.1065 - i.e. the so called residual graph.
171.1066 - When we take the union \f$A_{forward}\cup A_{backward}\f$,
171.1067 - multilicities are counted, i.e. if an edge is in both
171.1068 - \f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it
171.1069 - appears twice.
171.1070 - The following code shows how
171.1071 - such an instance can be constructed.
171.1072 - \code
171.1073 - typedef ListGraph Graph;
171.1074 - Graph::EdgeMap<int> f(g);
171.1075 - Graph::EdgeMap<int> c(g);
171.1076 - ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
171.1077 - \endcode
171.1078 - \author Marton Makai
171.1079 - */
171.1080 - template<typename Graph, typename Number,
171.1081 - typename CapacityMap, typename FlowMap>
171.1082 - class ResGraphAdaptor :
171.1083 - public SubBidirGraphAdaptor<
171.1084 - Graph,
171.1085 - ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
171.1086 - ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
171.1087 - public:
171.1088 - typedef SubBidirGraphAdaptor<
171.1089 - Graph,
171.1090 - ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
171.1091 - ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
171.1092 - protected:
171.1093 - const CapacityMap* capacity;
171.1094 - FlowMap* flow;
171.1095 - ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
171.1096 - ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
171.1097 - ResGraphAdaptor() : Parent(),
171.1098 - capacity(0), flow(0) { }
171.1099 - void setCapacityMap(const CapacityMap& _capacity) {
171.1100 - capacity=&_capacity;
171.1101 - forward_filter.setCapacity(_capacity);
171.1102 - backward_filter.setCapacity(_capacity);
171.1103 - }
171.1104 - void setFlowMap(FlowMap& _flow) {
171.1105 - flow=&_flow;
171.1106 - forward_filter.setFlow(_flow);
171.1107 - backward_filter.setFlow(_flow);
171.1108 - }
171.1109 - public:
171.1110 - ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity,
171.1111 - FlowMap& _flow) :
171.1112 - Parent(), capacity(&_capacity), flow(&_flow),
171.1113 - forward_filter(/*_graph,*/ _capacity, _flow),
171.1114 - backward_filter(/*_graph,*/ _capacity, _flow) {
171.1115 - Parent::setGraph(_graph);
171.1116 - Parent::setForwardFilterMap(forward_filter);
171.1117 - Parent::setBackwardFilterMap(backward_filter);
171.1118 - }
171.1119 -
171.1120 - typedef typename Parent::Edge Edge;
171.1121 -
171.1122 - void augment(const Edge& e, Number a) const {
171.1123 - if (Parent::forward(e))
171.1124 - flow->set(e, (*flow)[e]+a);
171.1125 - else
171.1126 - flow->set(e, (*flow)[e]-a);
171.1127 - }
171.1128 -
171.1129 - /// \brief Residual capacity map.
171.1130 - ///
171.1131 - /// In generic residual graphs the residual capacity can be obtained
171.1132 - /// as a map.
171.1133 - class ResCap {
171.1134 - protected:
171.1135 - const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
171.1136 - public:
171.1137 - typedef Number Value;
171.1138 - typedef Edge Key;
171.1139 - ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>&
171.1140 - _res_graph) : res_graph(&_res_graph) { }
171.1141 - Number operator[](const Edge& e) const {
171.1142 - if (res_graph->forward(e))
171.1143 - return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];
171.1144 - else
171.1145 - return (*(res_graph->flow))[e];
171.1146 - }
171.1147 - };
171.1148 -
171.1149 - // KEEP_MAPS(Parent, ResGraphAdaptor);
171.1150 - };
171.1151 -
171.1152 -
171.1153 -
171.1154 - template <typename _Graph, typename FirstOutEdgesMap>
171.1155 - class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
171.1156 - public:
171.1157 - typedef _Graph Graph;
171.1158 - typedef GraphAdaptorBase<_Graph> Parent;
171.1159 - protected:
171.1160 - FirstOutEdgesMap* first_out_edges;
171.1161 - ErasingFirstGraphAdaptorBase() : Parent(),
171.1162 - first_out_edges(0) { }
171.1163 -
171.1164 - void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
171.1165 - first_out_edges=&_first_out_edges;
171.1166 - }
171.1167 -
171.1168 - public:
171.1169 -
171.1170 - typedef typename Parent::Node Node;
171.1171 - typedef typename Parent::Edge Edge;
171.1172 -
171.1173 - void firstOut(Edge& i, const Node& n) const {
171.1174 - i=(*first_out_edges)[n];
171.1175 - }
171.1176 -
171.1177 - void erase(const Edge& e) const {
171.1178 - Node n=source(e);
171.1179 - Edge f=e;
171.1180 - Parent::nextOut(f);
171.1181 - first_out_edges->set(n, f);
171.1182 - }
171.1183 - };
171.1184 -
171.1185 -
171.1186 - /// For blocking flows.
171.1187 -
171.1188 - ///\warning Graph adaptors are in even more experimental state than the other
171.1189 - ///parts of the lib. Use them at you own risk.
171.1190 - ///
171.1191 - /// This graph adaptor is used for on-the-fly
171.1192 - /// Dinits blocking flow computations.
171.1193 - /// For each node, an out-edge is stored which is used when the
171.1194 - /// \code
171.1195 - /// OutEdgeIt& first(OutEdgeIt&, const Node&)
171.1196 - /// \endcode
171.1197 - /// is called.
171.1198 - ///
171.1199 - /// \author Marton Makai
171.1200 - template <typename _Graph, typename FirstOutEdgesMap>
171.1201 - class ErasingFirstGraphAdaptor :
171.1202 - public IterableGraphExtender<
171.1203 - ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
171.1204 - public:
171.1205 - typedef _Graph Graph;
171.1206 - typedef IterableGraphExtender<
171.1207 - ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
171.1208 - ErasingFirstGraphAdaptor(Graph& _graph,
171.1209 - FirstOutEdgesMap& _first_out_edges) {
171.1210 - setGraph(_graph);
171.1211 - setFirstOutEdgesMap(_first_out_edges);
171.1212 - }
171.1213 -
171.1214 - };
171.1215 -
171.1216 - ///@}
171.1217 -
171.1218 -} //namespace lemon
171.1219 -
171.1220 -#endif //LEMON_GRAPH_ADAPTOR_H
171.1221 -
172.1 --- a/src/lemon/graph_reader.h Sat May 21 21:04:57 2005 +0000
172.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
172.3 @@ -1,808 +0,0 @@
172.4 -/* -*- C++ -*-
172.5 - * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
172.6 - *
172.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
172.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
172.9 - *
172.10 - * Permission to use, modify and distribute this software is granted
172.11 - * provided that this copyright notice appears in all copies. For
172.12 - * precise terms see the accompanying LICENSE file.
172.13 - *
172.14 - * This software is provided "AS IS" with no warranty of any kind,
172.15 - * express or implied, and with no claim as to its suitability for any
172.16 - * purpose.
172.17 - *
172.18 - */
172.19 -
172.20 -///\ingroup io_group
172.21 -///\file
172.22 -///\brief Lemon Graph Format reader.
172.23 -
172.24 -#ifndef LEMON_GRAPH_READER_H
172.25 -#define LEMON_GRAPH_READER_H
172.26 -
172.27 -#include <iostream>
172.28 -
172.29 -#include <lemon/error.h>
172.30 -#include <lemon/lemon_reader.h>
172.31 -
172.32 -namespace lemon {
172.33 -
172.34 - /// \addtogroup io_group
172.35 - /// @{
172.36 -
172.37 - /// \brief The graph reader class.
172.38 - ///
172.39 - /// The given file format may contain several maps and labeled nodes or
172.40 - /// edges.
172.41 - ///
172.42 - /// If you read a graph you need not read all the maps and items just those
172.43 - /// that you need. The interface of the \c GraphReader is very similar to
172.44 - /// the GraphWriter but the reading method does not depend on the order the
172.45 - /// given commands.
172.46 - ///
172.47 - /// The reader object suppose that each not readed value does not contain
172.48 - /// whitespaces, therefore it has some extra possibilities to control how
172.49 - /// it should skip the values when the string representation contains spaces.
172.50 - ///
172.51 - /// \code
172.52 - /// GraphReader<ListGraph> reader(std::cin, graph);
172.53 - /// \endcode
172.54 - ///
172.55 - /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
172.56 - /// If there is a map that you do not want to read from the file and there is
172.57 - /// whitespace in the string represenation of the values then you should
172.58 - /// call the \c skipNodeMap() template member function with proper
172.59 - /// parameters.
172.60 - ///
172.61 - /// \code
172.62 - /// reader.readNodeMap("coords", coords);
172.63 - ///
172.64 - /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
172.65 - /// reader.skipNodeMap<QuotedStringReader>("description");
172.66 - ///
172.67 - /// reader.readNodeMap("color", colorMap);
172.68 - /// \endcode
172.69 - ///
172.70 - /// With the \c readEdgeMap() member function you can give an edge map
172.71 - /// reading command similar to the NodeMaps.
172.72 - ///
172.73 - /// \code
172.74 - /// reader.readEdgeMap("weight", weightMap);
172.75 - /// reader.readEdgeMap("label", labelMap);
172.76 - /// \endcode
172.77 - ///
172.78 - /// With \c readNode() and \c readEdge() functions you can read
172.79 - /// labeled Nodes and Edges.
172.80 - ///
172.81 - /// \code
172.82 - /// reader.readNode("source", sourceNode);
172.83 - /// reader.readNode("target", targetNode);
172.84 - ///
172.85 - /// reader.readEdge("observed", edge);
172.86 - /// \endcode
172.87 - ///
172.88 - /// With the \c readAttribute() functions you can read an attribute
172.89 - /// in a variable. You can specify the reader for the attribute as
172.90 - /// the nodemaps.
172.91 - ///
172.92 - /// After you give all read commands you must call the \c run() member
172.93 - /// function, which execute all the commands.
172.94 - ///
172.95 - /// \code
172.96 - /// reader.run();
172.97 - /// \endcode
172.98 - ///
172.99 - /// \see DefaultReaderTraits
172.100 - /// \see QuotedStringReader
172.101 - /// \see \ref GraphWriter
172.102 - /// \see \ref graph-io-page
172.103 - /// \author Balazs Dezso
172.104 - template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
172.105 - class GraphReader {
172.106 - public:
172.107 -
172.108 - typedef _Graph Graph;
172.109 - typedef typename Graph::Node Node;
172.110 - typedef typename Graph::Edge Edge;
172.111 -
172.112 - typedef _ReaderTraits ReaderTraits;
172.113 - typedef typename ReaderTraits::Skipper DefaultSkipper;
172.114 -
172.115 - /// \brief Construct a new GraphReader.
172.116 - ///
172.117 - /// Construct a new GraphReader. It reads into the given graph
172.118 - /// and it use the given reader as the default skipper.
172.119 - GraphReader(std::istream& _is,
172.120 - typename SmartParameter<Graph>::Type _graph,
172.121 - const DefaultSkipper& _skipper = DefaultSkipper())
172.122 - : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
172.123 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.124 - edgeset_reader(*reader, _graph, nodeset_reader,
172.125 - std::string(), skipper),
172.126 - node_reader(*reader, nodeset_reader, std::string()),
172.127 - edge_reader(*reader, edgeset_reader, std::string()),
172.128 - attribute_reader(*reader, std::string()) {}
172.129 -
172.130 - /// \brief Construct a new GraphReader.
172.131 - ///
172.132 - /// Construct a new GraphReader. It reads into the given graph
172.133 - /// and it use the given reader as the default skipper.
172.134 - GraphReader(const std::string& _filename,
172.135 - typename SmartParameter<Graph>::Type _graph,
172.136 - const DefaultSkipper& _skipper = DefaultSkipper())
172.137 - : reader(new LemonReader(_filename)), own_reader(true),
172.138 - skipper(_skipper),
172.139 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.140 - edgeset_reader(*reader, _graph, nodeset_reader,
172.141 - std::string(), skipper),
172.142 - node_reader(*reader, nodeset_reader, std::string()),
172.143 - edge_reader(*reader, edgeset_reader, std::string()),
172.144 - attribute_reader(*reader, std::string()) {}
172.145 -
172.146 - /// \brief Construct a new GraphReader.
172.147 - ///
172.148 - /// Construct a new GraphReader. It reads into the given graph
172.149 - /// and it use the given reader as the default skipper.
172.150 - GraphReader(LemonReader& _reader,
172.151 - typename SmartParameter<Graph>::Type _graph,
172.152 - const DefaultSkipper& _skipper = DefaultSkipper())
172.153 - : reader(_reader), own_reader(false), skipper(_skipper),
172.154 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.155 - edgeset_reader(*reader, _graph, nodeset_reader,
172.156 - std::string(), skipper),
172.157 - node_reader(*reader, nodeset_reader, std::string()),
172.158 - edge_reader(*reader, edgeset_reader, std::string()),
172.159 - attribute_reader(*reader, std::string()) {}
172.160 -
172.161 - /// \brief Destruct the graph reader.
172.162 - ///
172.163 - /// Destruct the graph reader.
172.164 - ~GraphReader() {
172.165 - if (own_reader)
172.166 - delete reader;
172.167 - }
172.168 -
172.169 - /// \brief Add a new node map reader command for the reader.
172.170 - ///
172.171 - /// Add a new node map reader command for the reader.
172.172 - template <typename Map>
172.173 - GraphReader& readNodeMap(std::string name, Map& map) {
172.174 - nodeset_reader.readNodeMap(name, map);
172.175 - return *this;
172.176 - }
172.177 -
172.178 - template <typename Map>
172.179 - GraphReader& readNodeMap(std::string name, const Map& map) {
172.180 - nodeset_reader.readNodeMap(name, map);
172.181 - return *this;
172.182 - }
172.183 -
172.184 - /// \brief Add a new node map reader command for the reader.
172.185 - ///
172.186 - /// Add a new node map reader command for the reader.
172.187 - template <typename Reader, typename Map>
172.188 - GraphReader& readNodeMap(std::string name, Map& map,
172.189 - const Reader& reader = Reader()) {
172.190 - nodeset_reader.readNodeMap(name, map, reader);
172.191 - return *this;
172.192 - }
172.193 -
172.194 - template <typename Reader, typename Map>
172.195 - GraphReader& readNodeMap(std::string name, const Map& map,
172.196 - const Reader& reader = Reader()) {
172.197 - nodeset_reader.readNodeMap(name, map, reader);
172.198 - return *this;
172.199 - }
172.200 -
172.201 - /// \brief Add a new node map skipper command for the reader.
172.202 - ///
172.203 - /// Add a new node map skipper command for the reader.
172.204 - template <typename Reader>
172.205 - GraphReader& skipNodeMap(std::string name,
172.206 - const Reader& reader = Reader()) {
172.207 - nodeset_reader.skipNodeMap(name, reader);
172.208 - return *this;
172.209 - }
172.210 -
172.211 - /// \brief Add a new edge map reader command for the reader.
172.212 - ///
172.213 - /// Add a new edge map reader command for the reader.
172.214 - template <typename Map>
172.215 - GraphReader& readEdgeMap(std::string name, Map& map) {
172.216 - edgeset_reader.readEdgeMap(name, map);
172.217 - return *this;
172.218 - }
172.219 -
172.220 - template <typename Map>
172.221 - GraphReader& readEdgeMap(std::string name, const Map& map) {
172.222 - edgeset_reader.readEdgeMap(name, map);
172.223 - return *this;
172.224 - }
172.225 -
172.226 -
172.227 - /// \brief Add a new edge map reader command for the reader.
172.228 - ///
172.229 - /// Add a new edge map reader command for the reader.
172.230 - template <typename Reader, typename Map>
172.231 - GraphReader& readEdgeMap(std::string name, Map& map,
172.232 - const Reader& reader = Reader()) {
172.233 - edgeset_reader.readEdgeMap(name, map, reader);
172.234 - return *this;
172.235 - }
172.236 -
172.237 - template <typename Reader, typename Map>
172.238 - GraphReader& readEdgeMap(std::string name, const Map& map,
172.239 - const Reader& reader = Reader()) {
172.240 - edgeset_reader.readEdgeMap(name, map, reader);
172.241 - return *this;
172.242 - }
172.243 -
172.244 - /// \brief Add a new edge map skipper command for the reader.
172.245 - ///
172.246 - /// Add a new edge map skipper command for the reader.
172.247 - template <typename Reader>
172.248 - GraphReader& skipEdgeMap(std::string name,
172.249 - const Reader& reader = Reader()) {
172.250 - edgeset_reader.skipEdgeMap(name, reader);
172.251 - return *this;
172.252 - }
172.253 -
172.254 - /// \brief Add a new labeled node reader for the reader.
172.255 - ///
172.256 - /// Add a new labeled node reader for the reader.
172.257 - GraphReader& readNode(std::string name, Node& node) {
172.258 - node_reader.readNode(name, node);
172.259 - return *this;
172.260 - }
172.261 -
172.262 - /// \brief Add a new labeled edge reader for the reader.
172.263 - ///
172.264 - /// Add a new labeled edge reader for the reader.
172.265 - GraphReader& readEdge(std::string name, Edge& edge) {
172.266 - edge_reader.readEdge(name, edge);
172.267 - }
172.268 -
172.269 - /// \brief Add a new attribute reader command.
172.270 - ///
172.271 - /// Add a new attribute reader command.
172.272 - template <typename Value>
172.273 - GraphReader& readAttribute(std::string name, Value& value) {
172.274 - attribute_reader.readAttribute(name, value);
172.275 - return *this;
172.276 - }
172.277 -
172.278 - /// \brief Add a new attribute reader command.
172.279 - ///
172.280 - /// Add a new attribute reader command.
172.281 - template <typename Reader, typename Value>
172.282 - GraphReader& readAttribute(std::string name, Value& value,
172.283 - const Reader& reader) {
172.284 - attribute_reader.readAttribute<Reader>(name, value, reader);
172.285 - return *this;
172.286 - }
172.287 -
172.288 - /// \brief Conversion operator to LemonReader.
172.289 - ///
172.290 - /// Conversion operator to LemonReader. It make possible
172.291 - /// to access the encapsulated \e LemonReader, this way
172.292 - /// you can attach to this reader new instances of
172.293 - /// \e LemonReader::SectionReader.
172.294 - operator LemonReader&() {
172.295 - return *reader;
172.296 - }
172.297 -
172.298 - /// \brief Executes the reader commands.
172.299 - ///
172.300 - /// Executes the reader commands.
172.301 - void run() {
172.302 - reader->run();
172.303 - }
172.304 -
172.305 - /// \brief Gives back the node by its id.
172.306 - ///
172.307 - /// It reads an id from the stream and gives back which node belongs to
172.308 - /// it. It is possible only if there was read an "id" named node map.
172.309 - Node readId(std::istream& is, Node) const {
172.310 - return nodeset_reader.readId(is, Node());
172.311 - }
172.312 -
172.313 - /// \brief Gives back the edge by its id.
172.314 - ///
172.315 - /// It reads an id from the stream and gives back which edge belongs to
172.316 - /// it. It is possible only if there was read an "id" named edge map.
172.317 - Edge readId(std::istream& is, Edge) const {
172.318 - return edgeset_reader.readId(is, Edge());
172.319 - }
172.320 -
172.321 - private:
172.322 -
172.323 - LemonReader* reader;
172.324 - bool own_reader;
172.325 -
172.326 - DefaultSkipper skipper;
172.327 -
172.328 - NodeSetReader<Graph, ReaderTraits> nodeset_reader;
172.329 - EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
172.330 -
172.331 - NodeReader<Graph> node_reader;
172.332 - EdgeReader<Graph> edge_reader;
172.333 -
172.334 - AttributeReader<ReaderTraits> attribute_reader;
172.335 - };
172.336 -
172.337 - /// \brief Read a graph from the input.
172.338 - ///
172.339 - /// Read a graph from the input.
172.340 - /// \param is The input stream.
172.341 - /// \param g The graph.
172.342 - /// \param capacity The capacity map.
172.343 - /// \param s The source node.
172.344 - /// \param t The target node.
172.345 - /// \param cost The cost map.
172.346 - template<typename Graph, typename CapacityMap, typename CostMap>
172.347 - void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
172.348 - typename Graph::Node &s, typename Graph::Node &t,
172.349 - CostMap& cost) {
172.350 - GraphReader<Graph> reader(is, g);
172.351 - reader.readEdgeMap("capacity", capacity);
172.352 - reader.readEdgeMap("cost", cost);
172.353 - reader.readNode("source", s);
172.354 - reader.readNode("target", t);
172.355 - reader.run();
172.356 - }
172.357 -
172.358 - /// \brief Read a graph from the input.
172.359 - ///
172.360 - /// Read a graph from the input.
172.361 - /// \param is The input stream.
172.362 - /// \param g The graph.
172.363 - /// \param capacity The capacity map.
172.364 - /// \param s The source node.
172.365 - /// \param t The target node.
172.366 - template<typename Graph, typename CapacityMap>
172.367 - void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
172.368 - typename Graph::Node &s, typename Graph::Node &t) {
172.369 - GraphReader<Graph> reader(is, g);
172.370 - reader.readEdgeMap("capacity", capacity);
172.371 - reader.readNode("source", s);
172.372 - reader.readNode("target", t);
172.373 - reader.run();
172.374 - }
172.375 -
172.376 - /// \brief Read a graph from the input.
172.377 - ///
172.378 - /// Read a graph from the input.
172.379 - /// \param is The input stream.
172.380 - /// \param g The graph.
172.381 - /// \param capacity The capacity map.
172.382 - /// \param s The source node.
172.383 - template<typename Graph, typename CapacityMap>
172.384 - void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
172.385 - typename Graph::Node &s) {
172.386 - GraphReader<Graph> reader(is, g);
172.387 - reader.readEdgeMap("capacity", capacity);
172.388 - reader.readNode("source", s);
172.389 - reader.run();
172.390 - }
172.391 -
172.392 - /// \brief Read a graph from the input.
172.393 - ///
172.394 - /// Read a graph from the input.
172.395 - /// \param is The input stream.
172.396 - /// \param g The graph.
172.397 - /// \param capacity The capacity map.
172.398 - template<typename Graph, typename CapacityMap>
172.399 - void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
172.400 - GraphReader<Graph> reader(is, g);
172.401 - reader.readEdgeMap("capacity", capacity);
172.402 - reader.run();
172.403 - }
172.404 -
172.405 - /// \brief Read a graph from the input.
172.406 - ///
172.407 - /// Read a graph from the input.
172.408 - /// \param is The input stream.
172.409 - /// \param g The graph.
172.410 - template<typename Graph>
172.411 - void readGraph(std::istream& is, Graph &g) {
172.412 - GraphReader<Graph> reader(is, g);
172.413 - reader.run();
172.414 - }
172.415 -
172.416 - /// \brief The undir graph reader class.
172.417 - ///
172.418 - /// The given file format may contain several maps and labeled nodes or
172.419 - /// edges.
172.420 - ///
172.421 - /// If you read a graph you need not read all the maps and items just those
172.422 - /// that you need. The interface of the \c GraphReader is very similar to
172.423 - /// the GraphWriter but the reading method does not depend on the order the
172.424 - /// given commands.
172.425 - ///
172.426 - /// The reader object suppose that each not readed value does not contain
172.427 - /// whitespaces, therefore it has some extra possibilities to control how
172.428 - /// it should skip the values when the string representation contains spaces.
172.429 - ///
172.430 - /// \code
172.431 - /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
172.432 - /// \endcode
172.433 - ///
172.434 - /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
172.435 - /// If there is a map that you do not want to read from the file and there is
172.436 - /// whitespace in the string represenation of the values then you should
172.437 - /// call the \c skipNodeMap() template member function with proper
172.438 - /// parameters.
172.439 - ///
172.440 - /// \code
172.441 - /// reader.readNodeMap("coords", coords);
172.442 - ///
172.443 - /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
172.444 - /// reader.skipNodeMap<QuotedStringReader>("description");
172.445 - ///
172.446 - /// reader.readNodeMap("color", colorMap);
172.447 - /// \endcode
172.448 - ///
172.449 - /// With the \c readUndirEdgeMap() member function you can give an
172.450 - /// undir edge map reading command similar to the NodeMaps.
172.451 - ///
172.452 - /// \code
172.453 - /// reader.readUndirEdgeMap("capacity", capacityMap);
172.454 - /// \endcode
172.455 - ///
172.456 - /// The reading of the directed edge maps is just a syntactical sugar.
172.457 - /// It reads two undirected edgemaps into a directed edge map. The
172.458 - /// undirected edge maps' name should be start with the \c '+' and the
172.459 - /// \c '-' character and the same.
172.460 - ///
172.461 - /// \code
172.462 - /// reader.readEdgeMap("flow", flowMap);
172.463 - /// \endcode
172.464 - ///
172.465 - /// With \c readNode() and \c readUndirEdge() functions you can read
172.466 - /// labeled Nodes and UndirEdges.
172.467 - ///
172.468 - /// \code
172.469 - /// reader.readNode("source", sourceNode);
172.470 - /// reader.readNode("target", targetNode);
172.471 - ///
172.472 - /// reader.readUndirEdge("observed", undirEdge);
172.473 - /// \endcode
172.474 - ///
172.475 - /// With the \c readAttribute() functions you can read an attribute
172.476 - /// in a variable. You can specify the reader for the attribute as
172.477 - /// the nodemaps.
172.478 - ///
172.479 - /// After you give all read commands you must call the \c run() member
172.480 - /// function, which execute all the commands.
172.481 - ///
172.482 - /// \code
172.483 - /// reader.run();
172.484 - /// \endcode
172.485 - ///
172.486 - /// \see GraphReader
172.487 - /// \see DefaultReaderTraits
172.488 - /// \see \ref UndirGraphWriter
172.489 - /// \see \ref graph-io-page
172.490 - ///
172.491 - /// \author Balazs Dezso
172.492 - template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
172.493 - class UndirGraphReader {
172.494 - public:
172.495 -
172.496 - typedef _Graph Graph;
172.497 - typedef typename Graph::Node Node;
172.498 - typedef typename Graph::Edge Edge;
172.499 - typedef typename Graph::UndirEdge UndirEdge;
172.500 -
172.501 - typedef _ReaderTraits ReaderTraits;
172.502 - typedef typename ReaderTraits::Skipper DefaultSkipper;
172.503 -
172.504 - /// \brief Construct a new UndirGraphReader.
172.505 - ///
172.506 - /// Construct a new UndirGraphReader. It reads into the given graph
172.507 - /// and it use the given reader as the default skipper.
172.508 - UndirGraphReader(std::istream& _is, Graph& _graph,
172.509 - const DefaultSkipper& _skipper = DefaultSkipper())
172.510 - : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
172.511 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.512 - undir_edgeset_reader(*reader, _graph, nodeset_reader,
172.513 - std::string(), skipper),
172.514 - node_reader(*reader, nodeset_reader, std::string()),
172.515 - undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
172.516 - attribute_reader(*reader, std::string()) {}
172.517 -
172.518 - /// \brief Construct a new UndirGraphReader.
172.519 - ///
172.520 - /// Construct a new UndirGraphReader. It reads into the given graph
172.521 - /// and it use the given reader as the default skipper.
172.522 - UndirGraphReader(const std::string& _filename, Graph& _graph,
172.523 - const DefaultSkipper& _skipper = DefaultSkipper())
172.524 - : reader(new LemonReader(_filename)), own_reader(true),
172.525 - skipper(_skipper),
172.526 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.527 - undir_edgeset_reader(*reader, _graph, nodeset_reader,
172.528 - std::string(), skipper),
172.529 - node_reader(*reader, nodeset_reader, std::string()),
172.530 - undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
172.531 - attribute_reader(*reader, std::string()) {}
172.532 -
172.533 - /// \brief Construct a new UndirGraphReader.
172.534 - ///
172.535 - /// Construct a new UndirGraphReader. It reads into the given graph
172.536 - /// and it use the given reader as the default skipper.
172.537 - UndirGraphReader(LemonReader& _reader, Graph& _graph,
172.538 - const DefaultSkipper& _skipper = DefaultSkipper())
172.539 - : reader(_reader), own_reader(false), skipper(_skipper),
172.540 - nodeset_reader(*reader, _graph, std::string(), skipper),
172.541 - undir_edgeset_reader(*reader, _graph, nodeset_reader,
172.542 - std::string(), skipper),
172.543 - node_reader(*reader, nodeset_reader, std::string()),
172.544 - undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
172.545 - attribute_reader(*reader, std::string()) {}
172.546 -
172.547 - /// \brief Destruct the graph reader.
172.548 - ///
172.549 - /// Destruct the graph reader.
172.550 - ~UndirGraphReader() {
172.551 - if (own_reader)
172.552 - delete reader;
172.553 - }
172.554 -
172.555 - /// \brief Add a new node map reader command for the reader.
172.556 - ///
172.557 - /// Add a new node map reader command for the reader.
172.558 - template <typename Map>
172.559 - UndirGraphReader& readNodeMap(std::string name, Map& map) {
172.560 - nodeset_reader.readNodeMap(name, map);
172.561 - return *this;
172.562 - }
172.563 -
172.564 - template <typename Map>
172.565 - UndirGraphReader& readNodeMap(std::string name, const Map& map) {
172.566 - nodeset_reader.readNodeMap(name, map);
172.567 - return *this;
172.568 - }
172.569 -
172.570 - /// \brief Add a new node map reader command for the reader.
172.571 - ///
172.572 - /// Add a new node map reader command for the reader.
172.573 - template <typename Reader, typename Map>
172.574 - UndirGraphReader& readNodeMap(std::string name, Map& map,
172.575 - const Reader& reader = Reader()) {
172.576 - nodeset_reader.readNodeMap(name, map, reader);
172.577 - return *this;
172.578 - }
172.579 -
172.580 - template <typename Reader, typename Map>
172.581 - UndirGraphReader& readNodeMap(std::string name, const Map& map,
172.582 - const Reader& reader = Reader()) {
172.583 - nodeset_reader.readNodeMap(name, map, reader);
172.584 - return *this;
172.585 - }
172.586 -
172.587 - /// \brief Add a new node map skipper command for the reader.
172.588 - ///
172.589 - /// Add a new node map skipper command for the reader.
172.590 - template <typename Reader>
172.591 - UndirGraphReader& skipNodeMap(std::string name,
172.592 - const Reader& reader = Reader()) {
172.593 - nodeset_reader.skipNodeMap(name, reader);
172.594 - return *this;
172.595 - }
172.596 -
172.597 - /// \brief Add a new undirected edge map reader command for the reader.
172.598 - ///
172.599 - /// Add a new undirected edge map reader command for the reader.
172.600 - template <typename Map>
172.601 - UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
172.602 - undir_edgeset_reader.readUndirEdgeMap(name, map);
172.603 - return *this;
172.604 - }
172.605 -
172.606 - template <typename Map>
172.607 - UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
172.608 - undir_edgeset_reader.readUndirEdgeMap(name, map);
172.609 - return *this;
172.610 - }
172.611 -
172.612 -
172.613 - /// \brief Add a new undirected edge map reader command for the reader.
172.614 - ///
172.615 - /// Add a new undirected edge map reader command for the reader.
172.616 - template <typename Reader, typename Map>
172.617 - UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
172.618 - const Reader& reader = Reader()) {
172.619 - undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
172.620 - return *this;
172.621 - }
172.622 -
172.623 - template <typename Reader, typename Map>
172.624 - UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
172.625 - const Reader& reader = Reader()) {
172.626 - undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
172.627 - return *this;
172.628 - }
172.629 -
172.630 - /// \brief Add a new undirected edge map skipper command for the reader.
172.631 - ///
172.632 - /// Add a new undirected edge map skipper command for the reader.
172.633 - template <typename Reader>
172.634 - UndirGraphReader& skipUndirEdgeMap(std::string name,
172.635 - const Reader& reader = Reader()) {
172.636 - undir_edgeset_reader.skipUndirMap(name, reader);
172.637 - return *this;
172.638 - }
172.639 -
172.640 -
172.641 - /// \brief Add a new edge map reader command for the reader.
172.642 - ///
172.643 - /// Add a new edge map reader command for the reader.
172.644 - template <typename Map>
172.645 - UndirGraphReader& readEdgeMap(std::string name, Map& map) {
172.646 - undir_edgeset_reader.readEdgeMap(name, map);
172.647 - return *this;
172.648 - }
172.649 -
172.650 - template <typename Map>
172.651 - UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
172.652 - undir_edgeset_reader.readEdgeMap(name, map);
172.653 - return *this;
172.654 - }
172.655 -
172.656 -
172.657 - /// \brief Add a new edge map reader command for the reader.
172.658 - ///
172.659 - /// Add a new edge map reader command for the reader.
172.660 - template <typename Reader, typename Map>
172.661 - UndirGraphReader& readEdgeMap(std::string name, Map& map,
172.662 - const Reader& reader = Reader()) {
172.663 - undir_edgeset_reader.readEdgeMap(name, map, reader);
172.664 - return *this;
172.665 - }
172.666 -
172.667 - template <typename Reader, typename Map>
172.668 - UndirGraphReader& readEdgeMap(std::string name, const Map& map,
172.669 - const Reader& reader = Reader()) {
172.670 - undir_edgeset_reader.readEdgeMap(name, map, reader);
172.671 - return *this;
172.672 - }
172.673 -
172.674 - /// \brief Add a new edge map skipper command for the reader.
172.675 - ///
172.676 - /// Add a new edge map skipper command for the reader.
172.677 - template <typename Reader>
172.678 - UndirGraphReader& skipEdgeMap(std::string name,
172.679 - const Reader& reader = Reader()) {
172.680 - undir_edgeset_reader.skipEdgeMap(name, reader);
172.681 - return *this;
172.682 - }
172.683 -
172.684 - /// \brief Add a new labeled node reader for the reader.
172.685 - ///
172.686 - /// Add a new labeled node reader for the reader.
172.687 - UndirGraphReader& readNode(std::string name, Node& node) {
172.688 - node_reader.readNode(name, node);
172.689 - return *this;
172.690 - }
172.691 -
172.692 - /// \brief Add a new labeled edge reader for the reader.
172.693 - ///
172.694 - /// Add a new labeled edge reader for the reader.
172.695 - UndirGraphReader& readEdge(std::string name, Edge& edge) {
172.696 - undir_edge_reader.readEdge(name, edge);
172.697 - }
172.698 -
172.699 - /// \brief Add a new labeled undirected edge reader for the reader.
172.700 - ///
172.701 - /// Add a new labeled undirected edge reader for the reader.
172.702 - UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
172.703 - undir_edge_reader.readUndirEdge(name, edge);
172.704 - }
172.705 -
172.706 - /// \brief Add a new attribute reader command.
172.707 - ///
172.708 - /// Add a new attribute reader command.
172.709 - template <typename Value>
172.710 - UndirGraphReader& readAttribute(std::string name, Value& value) {
172.711 - attribute_reader.readAttribute(name, value);
172.712 - return *this;
172.713 - }
172.714 -
172.715 - /// \brief Add a new attribute reader command.
172.716 - ///
172.717 - /// Add a new attribute reader command.
172.718 - template <typename Reader, typename Value>
172.719 - UndirGraphReader& readAttribute(std::string name, Value& value,
172.720 - const Reader& reader) {
172.721 - attribute_reader.readAttribute<Reader>(name, value, reader);
172.722 - return *this;
172.723 - }
172.724 -
172.725 - /// \brief Conversion operator to LemonReader.
172.726 - ///
172.727 - /// Conversion operator to LemonReader. It make possible
172.728 - /// to access the encapsulated \e LemonReader, this way
172.729 - /// you can attach to this reader new instances of
172.730 - /// \e LemonReader::SectionReader.
172.731 - operator LemonReader&() {
172.732 - return *reader;
172.733 - }
172.734 -
172.735 - /// \brief Executes the reader commands.
172.736 - ///
172.737 - /// Executes the reader commands.
172.738 - void run() {
172.739 - reader->run();
172.740 - }
172.741 -
172.742 - /// \brief Gives back the node by its id.
172.743 - ///
172.744 - /// It reads an id from the stream and gives back which node belongs to
172.745 - /// it. It is possible only if there was read an "id" named node map.
172.746 - Node readId(std::istream& is, Node) const {
172.747 - return nodeset_reader.readId(is, Node());
172.748 - }
172.749 -
172.750 - /// \brief Gives back the edge by its id.
172.751 - ///
172.752 - /// It reads an id from the stream and gives back which edge belongs to
172.753 - /// it. It is possible only if there was read an "id" named edge map.
172.754 - Edge readId(std::istream& is, Edge) const {
172.755 - return undir_edgeset_reader.readId(is, Edge());
172.756 - }
172.757 -
172.758 - /// \brief Gives back the undirected edge by its id.
172.759 - ///
172.760 - /// It reads an id from the stream and gives back which undirected edge
172.761 - /// belongs to it. It is possible only if there was read an "id" named
172.762 - /// edge map.
172.763 - UndirEdge readId(std::istream& is, UndirEdge) const {
172.764 - return undir_edgeset_reader.readId(is, UndirEdge());
172.765 - }
172.766 -
172.767 -
172.768 - private:
172.769 -
172.770 - LemonReader* reader;
172.771 - bool own_reader;
172.772 -
172.773 - DefaultSkipper skipper;
172.774 -
172.775 - NodeSetReader<Graph, ReaderTraits> nodeset_reader;
172.776 - UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
172.777 -
172.778 - NodeReader<Graph> node_reader;
172.779 - UndirEdgeReader<Graph> undir_edge_reader;
172.780 -
172.781 - AttributeReader<ReaderTraits> attribute_reader;
172.782 - };
172.783 -
172.784 - /// \brief Read an undir graph from the input.
172.785 - ///
172.786 - /// Read an undir graph from the input.
172.787 - /// \param is The input stream.
172.788 - /// \param g The graph.
172.789 - /// \param capacity The capacity map.
172.790 - template<typename Graph, typename CapacityMap>
172.791 - void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
172.792 - UndirGraphReader<Graph> reader(is, g);
172.793 - reader.readUndirEdgeMap("capacity", capacity);
172.794 - reader.run();
172.795 - }
172.796 -
172.797 - /// \brief Read an undir graph from the input.
172.798 - ///
172.799 - /// Read an undir graph from the input.
172.800 - /// \param is The input stream.
172.801 - /// \param g The graph.
172.802 - template<typename Graph>
172.803 - void readUndirGraph(std::istream& is, Graph &g) {
172.804 - UndirGraphReader<Graph> reader(is, g);
172.805 - reader.run();
172.806 - }
172.807 -
172.808 - /// @}
172.809 -}
172.810 -
172.811 -#endif
173.1 --- a/src/lemon/graph_to_eps.h Sat May 21 21:04:57 2005 +0000
173.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
173.3 @@ -1,1026 +0,0 @@
173.4 -/* -*- C++ -*-
173.5 - * src/lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
173.6 - *
173.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
173.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
173.9 - *
173.10 - * Permission to use, modify and distribute this software is granted
173.11 - * provided that this copyright notice appears in all copies. For
173.12 - * precise terms see the accompanying LICENSE file.
173.13 - *
173.14 - * This software is provided "AS IS" with no warranty of any kind,
173.15 - * express or implied, and with no claim as to its suitability for any
173.16 - * purpose.
173.17 - *
173.18 - */
173.19 -
173.20 -#ifndef LEMON_GRAPH_TO_EPS_H
173.21 -#define LEMON_GRAPH_TO_EPS_H
173.22 -
173.23 -#include <sys/time.h>
173.24 -
173.25 -#include<iostream>
173.26 -#include<fstream>
173.27 -#include<sstream>
173.28 -#include<algorithm>
173.29 -#include<vector>
173.30 -
173.31 -#include <ctime>
173.32 -#include <cmath>
173.33 -
173.34 -#include<lemon/invalid.h>
173.35 -#include<lemon/xy.h>
173.36 -#include<lemon/maps.h>
173.37 -#include<lemon/bezier.h>
173.38 -
173.39 -
173.40 -///\ingroup io_group
173.41 -///\file
173.42 -///\brief Simple graph drawer
173.43 -///
173.44 -///\author Alpar Juttner
173.45 -
173.46 -namespace lemon {
173.47 -
173.48 -///Data structure representing RGB colors.
173.49 -
173.50 -///Data structure representing RGB colors.
173.51 -///\ingroup misc
173.52 -class Color
173.53 -{
173.54 - double _r,_g,_b;
173.55 -public:
173.56 - ///Default constructor
173.57 - Color() {}
173.58 - ///Constructor
173.59 - Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
173.60 - ///Returns the red component
173.61 -
173.62 - ///\todo \c red() could be a better name...
173.63 - double getR() const {return _r;}
173.64 - ///Returns the green component
173.65 - double getG() const {return _g;}
173.66 - ///Returns the blue component
173.67 - double getB() const {return _b;}
173.68 - ///Set the color components
173.69 - void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
173.70 -};
173.71 -
173.72 -///Maps <tt>int</tt>s to different \ref Color "Color"s
173.73 -
173.74 -///This map assing one of the predefined \ref Color "Color"s
173.75 -///to each <tt>int</tt>. It is possible to change the colors as well as their
173.76 -///number. The integer range is cyclically mapped to the provided set of colors.
173.77 -///
173.78 -///This is a true \ref concept::ReferenceMap "reference map", so you can also
173.79 -///change the actual colors.
173.80 -
173.81 -class ColorSet : public MapBase<int,Color>
173.82 -{
173.83 - std::vector<Color> colors;
173.84 -public:
173.85 - ///Constructor
173.86 -
173.87 - ///Constructor
173.88 - ///\param have_white indicates wheter white is
173.89 - ///amongst the provided color (\c true) or not (\c false). If it is true,
173.90 - ///white will be assigned to \c 0.
173.91 - ///\param num the number of the allocated colors. If it is \c 0
173.92 - ///the default color configuration is set up (26 color plus the while).
173.93 - ///If \c num is less then 26/27 then the default color list is cut. Otherwise
173.94 - ///the color list is filled repeatedly with the default color list.
173.95 - ColorSet(bool have_white=false,int num=0)
173.96 - {
173.97 - do {
173.98 - if(have_white) colors.push_back(Color(1,1,1));
173.99 -
173.100 - colors.push_back(Color(0,0,0));
173.101 - colors.push_back(Color(1,0,0));
173.102 - colors.push_back(Color(0,1,0));
173.103 - colors.push_back(Color(0,0,1));
173.104 - colors.push_back(Color(1,1,0));
173.105 - colors.push_back(Color(1,0,1));
173.106 - colors.push_back(Color(0,1,1));
173.107 -
173.108 - colors.push_back(Color(.5,0,0));
173.109 - colors.push_back(Color(0,.5,0));
173.110 - colors.push_back(Color(0,0,.5));
173.111 - colors.push_back(Color(.5,.5,0));
173.112 - colors.push_back(Color(.5,0,.5));
173.113 - colors.push_back(Color(0,.5,.5));
173.114 -
173.115 - colors.push_back(Color(.5,.5,.5));
173.116 - colors.push_back(Color(1,.5,.5));
173.117 - colors.push_back(Color(.5,1,.5));
173.118 - colors.push_back(Color(.5,.5,1));
173.119 - colors.push_back(Color(1,1,.5));
173.120 - colors.push_back(Color(1,.5,1));
173.121 - colors.push_back(Color(.5,1,1));
173.122 -
173.123 - colors.push_back(Color(1,.5,0));
173.124 - colors.push_back(Color(.5,1,0));
173.125 - colors.push_back(Color(1,0,.5));
173.126 - colors.push_back(Color(0,1,.5));
173.127 - colors.push_back(Color(0,.5,1));
173.128 - colors.push_back(Color(.5,0,1));
173.129 - } while(int(colors.size())<num);
173.130 - // colors.push_back(Color(1,1,1));
173.131 - if(num>0) colors.resize(num);
173.132 - }
173.133 - ///\e
173.134 - Color &operator[](int i)
173.135 - {
173.136 - return colors[i%colors.size()];
173.137 - }
173.138 - ///\e
173.139 - const Color &operator[](int i) const
173.140 - {
173.141 - return colors[i%colors.size()];
173.142 - }
173.143 - ///\e
173.144 - void set(int i,const Color &c)
173.145 - {
173.146 - colors[i%colors.size()]=c;
173.147 - }
173.148 - ///Sets the number of the exiting colors.
173.149 - void resize(int s) { colors.resize(s);}
173.150 - ///Returns the munber of the existing colors.
173.151 - std::size_t size() { return colors.size();}
173.152 -};
173.153 -
173.154 -///Returns a visible distinct \ref Color
173.155 -
173.156 -///Returns a \ref Color which is as different from the given parameter
173.157 -///as it is possible.
173.158 -inline Color distantColor(const Color &c)
173.159 -{
173.160 - return Color(c.getR()<.5?1:0,c.getG()<.5?1:0,c.getB()<.5?1:0);
173.161 -}
173.162 -///Returns black for light colors and white for the dark ones.
173.163 -
173.164 -///Returns black for light colors and white for the dark ones.
173.165 -///\todo weighted average would be better
173.166 -inline Color distantBW(const Color &c){
173.167 - double v=(.2125*c.getR()+.7154*c.getG()+.0721*c.getB())<.5?1:0;
173.168 - return Color(v,v,v);
173.169 -}
173.170 -
173.171 -///Default traits class of \ref GraphToEps
173.172 -
173.173 -///Default traits class of \ref GraphToEps
173.174 -///
173.175 -///\c G is the type of the underlying graph.
173.176 -template<class G>
173.177 -struct DefaultGraphToEpsTraits
173.178 -{
173.179 - typedef G Graph;
173.180 - typedef typename Graph::Node Node;
173.181 - typedef typename Graph::NodeIt NodeIt;
173.182 - typedef typename Graph::Edge Edge;
173.183 - typedef typename Graph::EdgeIt EdgeIt;
173.184 - typedef typename Graph::InEdgeIt InEdgeIt;
173.185 - typedef typename Graph::OutEdgeIt OutEdgeIt;
173.186 -
173.187 -
173.188 - const Graph &g;
173.189 -
173.190 - std::ostream& os;
173.191 -
173.192 - ConstMap<typename Graph::Node,xy<double> > _coords;
173.193 - ConstMap<typename Graph::Node,double > _nodeSizes;
173.194 - ConstMap<typename Graph::Node,int > _nodeShapes;
173.195 -
173.196 - ConstMap<typename Graph::Node,Color > _nodeColors;
173.197 - ConstMap<typename Graph::Edge,Color > _edgeColors;
173.198 -
173.199 - ConstMap<typename Graph::Edge,double > _edgeWidths;
173.200 -
173.201 - double _edgeWidthScale;
173.202 -
173.203 - double _nodeScale;
173.204 - double _xBorder, _yBorder;
173.205 - double _scale;
173.206 - double _nodeBorderQuotient;
173.207 -
173.208 - bool _drawArrows;
173.209 - double _arrowLength, _arrowWidth;
173.210 -
173.211 - bool _showNodes, _showEdges;
173.212 -
173.213 - bool _enableParallel;
173.214 - double _parEdgeDist;
173.215 -
173.216 - bool _showNodeText;
173.217 - ConstMap<typename Graph::Node,bool > _nodeTexts;
173.218 - double _nodeTextSize;
173.219 -
173.220 - bool _showNodePsText;
173.221 - ConstMap<typename Graph::Node,bool > _nodePsTexts;
173.222 - char *_nodePsTextsPreamble;
173.223 -
173.224 - bool _undir;
173.225 - bool _pleaseRemoveOsStream;
173.226 -
173.227 - bool _scaleToA4;
173.228 -
173.229 - std::string _title;
173.230 - std::string _copyright;
173.231 -
173.232 - enum NodeTextColorType
173.233 - { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
173.234 - ConstMap<typename Graph::Node,Color > _nodeTextColors;
173.235 -
173.236 - ///Constructor
173.237 -
173.238 - ///Constructor
173.239 - ///\param _g is a reference to the graph to be printed
173.240 - ///\param _os is a reference to the output stream.
173.241 - ///\param _os is a reference to the output stream.
173.242 - ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
173.243 - ///will be explicitly deallocated by the destructor.
173.244 - ///By default it is <tt>std::cout</tt>
173.245 - DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
173.246 - bool _pros=false) :
173.247 - g(_g), os(_os),
173.248 - _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
173.249 - _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
173.250 - _edgeWidths(1), _edgeWidthScale(0.3),
173.251 - _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
173.252 - _nodeBorderQuotient(.1),
173.253 - _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
173.254 - _showNodes(true), _showEdges(true),
173.255 - _enableParallel(false), _parEdgeDist(1),
173.256 - _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
173.257 - _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
173.258 - _undir(false),
173.259 - _pleaseRemoveOsStream(_pros), _scaleToA4(false),
173.260 - _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0))
173.261 - {}
173.262 -};
173.263 -
173.264 -///Helper class to implement the named parameters of \ref graphToEps()
173.265 -
173.266 -///Helper class to implement the named parameters of \ref graphToEps()
173.267 -///\todo Is 'helper class' a good name for this?
173.268 -///
173.269 -///\todo Follow PostScript's DSC.
173.270 -/// Use own dictionary.
173.271 -///\todo Useful new features.
173.272 -/// - Linestyles: dotted, dashed etc.
173.273 -/// - A second color and percent value for the lines.
173.274 -template<class T> class GraphToEps : public T
173.275 -{
173.276 - // Can't believe it is required by the C++ standard
173.277 - using T::g;
173.278 - using T::os;
173.279 -
173.280 - using T::_coords;
173.281 - using T::_nodeSizes;
173.282 - using T::_nodeShapes;
173.283 - using T::_nodeColors;
173.284 - using T::_edgeColors;
173.285 - using T::_edgeWidths;
173.286 -
173.287 - using T::_edgeWidthScale;
173.288 - using T::_nodeScale;
173.289 - using T::_xBorder;
173.290 - using T::_yBorder;
173.291 - using T::_scale;
173.292 - using T::_nodeBorderQuotient;
173.293 -
173.294 - using T::_drawArrows;
173.295 - using T::_arrowLength;
173.296 - using T::_arrowWidth;
173.297 -
173.298 - using T::_showNodes;
173.299 - using T::_showEdges;
173.300 -
173.301 - using T::_enableParallel;
173.302 - using T::_parEdgeDist;
173.303 -
173.304 - using T::_showNodeText;
173.305 - using T::_nodeTexts;
173.306 - using T::_nodeTextSize;
173.307 -
173.308 - using T::_showNodePsText;
173.309 - using T::_nodePsTexts;
173.310 - using T::_nodePsTextsPreamble;
173.311 -
173.312 - using T::_undir;
173.313 - using T::_pleaseRemoveOsStream;
173.314 -
173.315 - using T::_scaleToA4;
173.316 -
173.317 - using T::_title;
173.318 - using T::_copyright;
173.319 -
173.320 - using T::NodeTextColorType;
173.321 - using T::CUST_COL;
173.322 - using T::DIST_COL;
173.323 - using T::DIST_BW;
173.324 - using T::_nodeTextColorType;
173.325 - using T::_nodeTextColors;
173.326 - // dradnats ++C eht yb deriuqer si ti eveileb t'naC
173.327 -
173.328 - typedef typename T::Graph Graph;
173.329 - typedef typename Graph::Node Node;
173.330 - typedef typename Graph::NodeIt NodeIt;
173.331 - typedef typename Graph::Edge Edge;
173.332 - typedef typename Graph::EdgeIt EdgeIt;
173.333 - typedef typename Graph::InEdgeIt InEdgeIt;
173.334 - typedef typename Graph::OutEdgeIt OutEdgeIt;
173.335 -
173.336 - static const int INTERPOL_PREC=20;
173.337 - static const double A4HEIGHT = 841.8897637795276;
173.338 - static const double A4WIDTH = 595.275590551181;
173.339 - static const double A4BORDER = 15;
173.340 -
173.341 - bool dontPrint;
173.342 -
173.343 -public:
173.344 - ///Node shapes
173.345 -
173.346 - ///Node shapes
173.347 - ///
173.348 - enum NodeShapes {
173.349 - /// = 0
173.350 - ///\image html nodeshape_0.png
173.351 - ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
173.352 - CIRCLE=0,
173.353 - /// = 1
173.354 - ///\image html nodeshape_1.png
173.355 - ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
173.356 - ///
173.357 - SQUARE=1,
173.358 - /// = 2
173.359 - ///\image html nodeshape_2.png
173.360 - ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
173.361 - ///
173.362 - DIAMOND=2
173.363 - };
173.364 -
173.365 -private:
173.366 - class edgeLess {
173.367 - const Graph &g;
173.368 - public:
173.369 - edgeLess(const Graph &_g) : g(_g) {}
173.370 - bool operator()(Edge a,Edge b) const
173.371 - {
173.372 - Node ai=std::min(g.source(a),g.target(a));
173.373 - Node aa=std::max(g.source(a),g.target(a));
173.374 - Node bi=std::min(g.source(b),g.target(b));
173.375 - Node ba=std::max(g.source(b),g.target(b));
173.376 - return ai<bi ||
173.377 - (ai==bi && (aa < ba ||
173.378 - (aa==ba && ai==g.source(a) && bi==g.target(b))));
173.379 - }
173.380 - };
173.381 - bool isParallel(Edge e,Edge f) const
173.382 - {
173.383 - return (g.source(e)==g.source(f)&&
173.384 - g.target(e)==g.target(f)) ||
173.385 - (g.source(e)==g.target(f)&&
173.386 - g.target(e)==g.source(f));
173.387 - }
173.388 - template<class TT>
173.389 - static std::string psOut(const xy<TT> &p)
173.390 - {
173.391 - std::ostringstream os;
173.392 - os << p.x << ' ' << p.y;
173.393 - return os.str();
173.394 - }
173.395 - static std::string psOut(const Color &c)
173.396 - {
173.397 - std::ostringstream os;
173.398 - os << c.getR() << ' ' << c.getG() << ' ' << c.getB();
173.399 - return os.str();
173.400 - }
173.401 -
173.402 -public:
173.403 - GraphToEps(const T &t) : T(t), dontPrint(false) {};
173.404 -
173.405 - template<class X> struct CoordsTraits : public T {
173.406 - const X &_coords;
173.407 - CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
173.408 - };
173.409 - ///Sets the map of the node coordinates
173.410 -
173.411 - ///Sets the map of the node coordinates.
173.412 - ///\param x must be a node map with xy<double> or \ref xy "xy<int>" values.
173.413 - template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
173.414 - dontPrint=true;
173.415 - return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
173.416 - }
173.417 - template<class X> struct NodeSizesTraits : public T {
173.418 - const X &_nodeSizes;
173.419 - NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
173.420 - };
173.421 - ///Sets the map of the node sizes
173.422 -
173.423 - ///Sets the map of the node sizes
173.424 - ///\param x must be a node map with \c double (or convertible) values.
173.425 - template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
173.426 - {
173.427 - dontPrint=true;
173.428 - return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
173.429 - }
173.430 - template<class X> struct NodeShapesTraits : public T {
173.431 - const X &_nodeShapes;
173.432 - NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
173.433 - };
173.434 - ///Sets the map of the node shapes
173.435 -
173.436 - ///Sets the map of the node shapes.
173.437 - ///The availabe shape values
173.438 - ///can be found in \ref NodeShapes "enum NodeShapes".
173.439 - ///\param x must be a node map with \c int (or convertible) values.
173.440 - ///\sa NodeShapes
173.441 - template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
173.442 - {
173.443 - dontPrint=true;
173.444 - return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
173.445 - }
173.446 - template<class X> struct NodeTextsTraits : public T {
173.447 - const X &_nodeTexts;
173.448 - NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
173.449 - };
173.450 - ///Sets the text printed on the nodes
173.451 -
173.452 - ///Sets the text printed on the nodes
173.453 - ///\param x must be a node map with type that can be pushed to a standard
173.454 - ///ostream.
173.455 - template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
173.456 - {
173.457 - dontPrint=true;
173.458 - _showNodeText=true;
173.459 - return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
173.460 - }
173.461 - template<class X> struct NodePsTextsTraits : public T {
173.462 - const X &_nodePsTexts;
173.463 - NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
173.464 - };
173.465 - ///Inserts a PostScript block to the nodes
173.466 -
173.467 - ///With this command it is possible to insert a verbatim PostScript
173.468 - ///block to the nodes.
173.469 - ///The PS current point will be moved to the centre of the node before
173.470 - ///the PostScript block inserted.
173.471 - ///
173.472 - ///Before and after the block a newline character is inserted to you
173.473 - ///don't have to bother with the separators.
173.474 - ///
173.475 - ///\param x must be a node map with type that can be pushed to a standard
173.476 - ///ostream.
173.477 - ///
173.478 - ///\sa nodePsTextsPreamble()
173.479 - ///\todo Offer the choise not to move to the centre but pass the coordinates
173.480 - ///to the Postscript block inserted.
173.481 - template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
173.482 - {
173.483 - dontPrint=true;
173.484 - _showNodePsText=true;
173.485 - return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
173.486 - }
173.487 - template<class X> struct EdgeWidthsTraits : public T {
173.488 - const X &_edgeWidths;
173.489 - EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
173.490 - };
173.491 - ///Sets the map of the edge widths
173.492 -
173.493 - ///Sets the map of the edge widths
173.494 - ///\param x must be a edge map with \c double (or convertible) values.
173.495 - template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
173.496 - {
173.497 - dontPrint=true;
173.498 - return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
173.499 - }
173.500 -
173.501 - template<class X> struct NodeColorsTraits : public T {
173.502 - const X &_nodeColors;
173.503 - NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
173.504 - };
173.505 - ///Sets the map of the node colors
173.506 -
173.507 - ///Sets the map of the node colors
173.508 - ///\param x must be a node map with \ref Color values.
173.509 - template<class X> GraphToEps<NodeColorsTraits<X> >
173.510 - nodeColors(const X &x)
173.511 - {
173.512 - dontPrint=true;
173.513 - return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
173.514 - }
173.515 - template<class X> struct NodeTextColorsTraits : public T {
173.516 - const X &_nodeTextColors;
173.517 - NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
173.518 - };
173.519 - ///Sets the map of the node text colors
173.520 -
173.521 - ///Sets the map of the node text colors
173.522 - ///\param x must be a node map with \ref Color values.
173.523 - template<class X> GraphToEps<NodeTextColorsTraits<X> >
173.524 - nodeTextColors(const X &x)
173.525 - {
173.526 - dontPrint=true;
173.527 - _nodeTextColorType=CUST_COL;
173.528 - return GraphToEps<NodeTextColorsTraits<X> >
173.529 - (NodeTextColorsTraits<X>(*this,x));
173.530 - }
173.531 - template<class X> struct EdgeColorsTraits : public T {
173.532 - const X &_edgeColors;
173.533 - EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
173.534 - };
173.535 - ///Sets the map of the edge colors
173.536 -
173.537 - ///Sets the map of the edge colors
173.538 - ///\param x must be a edge map with \ref Color values.
173.539 - template<class X> GraphToEps<EdgeColorsTraits<X> >
173.540 - edgeColors(const X &x)
173.541 - {
173.542 - dontPrint=true;
173.543 - return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
173.544 - }
173.545 - ///Sets a global scale factor for node sizes
173.546 -
173.547 - ///Sets a global scale factor for node sizes
173.548 - ///
173.549 - GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
173.550 - ///Sets a global scale factor for edge widths
173.551 -
173.552 - ///Sets a global scale factor for edge widths
173.553 - ///
173.554 - GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
173.555 - ///Sets a global scale factor for the whole picture
173.556 -
173.557 - ///Sets a global scale factor for the whole picture
173.558 - ///
173.559 - GraphToEps<T> &scale(double d) {_scale=d;return *this;}
173.560 - ///Sets the width of the border around the picture
173.561 -
173.562 - ///Sets the width of the border around the picture
173.563 - ///
173.564 - GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
173.565 - ///Sets the width of the border around the picture
173.566 -
173.567 - ///Sets the width of the border around the picture
173.568 - ///
173.569 - GraphToEps<T> &border(double x, double y) {
173.570 - _xBorder=x;_yBorder=y;return *this;
173.571 - }
173.572 - ///Sets whether to draw arrows
173.573 -
173.574 - ///Sets whether to draw arrows
173.575 - ///
173.576 - GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
173.577 - ///Sets the length of the arrowheads
173.578 -
173.579 - ///Sets the length of the arrowheads
173.580 - ///
173.581 - GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
173.582 - ///Sets the width of the arrowheads
173.583 -
173.584 - ///Sets the width of the arrowheads
173.585 - ///
173.586 - GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
173.587 -
173.588 - ///Scales the drawing to fit to A4 page
173.589 -
173.590 - ///Scales the drawing to fit to A4 page
173.591 - ///
173.592 - GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
173.593 -
173.594 - ///Enables parallel edges
173.595 -
173.596 - ///Enables parallel edges
173.597 - ///\todo Partially implemented
173.598 - GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
173.599 -
173.600 - ///Sets the distance
173.601 -
173.602 - ///Sets the distance
173.603 - ///
173.604 - GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
173.605 -
173.606 - ///Hides the edges
173.607 -
173.608 - ///Hides the edges
173.609 - ///
173.610 - GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
173.611 - ///Hides the nodes
173.612 -
173.613 - ///Hides the nodes
173.614 - ///
173.615 - GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
173.616 -
173.617 - ///Sets the size of the node texts
173.618 -
173.619 - ///Sets the size of the node texts
173.620 - ///
173.621 - GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
173.622 -
173.623 - ///Sets the color of the node texts to be different from the node color
173.624 -
173.625 - ///Sets the color of the node texts to be as different from the node color
173.626 - ///as it is possible
173.627 - ///
173.628 - GraphToEps<T> &distantColorNodeTexts()
173.629 - {_nodeTextColorType=DIST_COL;return *this;}
173.630 - ///Sets the color of the node texts to be black or white and always visible.
173.631 -
173.632 - ///Sets the color of the node texts to be black or white according to
173.633 - ///which is more
173.634 - ///different from the node color
173.635 - ///
173.636 - GraphToEps<T> &distantBWNodeTexts()
173.637 - {_nodeTextColorType=DIST_BW;return *this;}
173.638 -
173.639 - ///Gives a preamble block for node Postscript block.
173.640 -
173.641 - ///Gives a preamble block for node Postscript block.
173.642 - ///
173.643 - ///\sa nodePsTexts()
173.644 - GraphToEps<T> & nodePsTextsPreamble(const char *str) {
173.645 - _nodePsTextsPreamble=str ;return *this;
173.646 - }
173.647 - ///Sets whether the the graph is undirected
173.648 -
173.649 - ///Sets whether the the graph is undirected
173.650 - ///
173.651 - GraphToEps<T> &undir(bool b=true) {_undir=b;return *this;}
173.652 - ///Sets whether the the graph is directed
173.653 -
173.654 - ///Sets whether the the graph is directed.
173.655 - ///Use it to show the undirected edges as a pair of directed ones.
173.656 - GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
173.657 -
173.658 - ///Sets the title.
173.659 -
173.660 - ///Sets the title of the generated image,
173.661 - ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
173.662 - ///the EPS file.
173.663 - GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
173.664 - ///Sets the copyright statement.
173.665 -
173.666 - ///Sets the copyright statement of the generated image,
173.667 - ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
173.668 - ///the EPS file.
173.669 - ///\todo Multiline copyright notice could be supported.
173.670 - GraphToEps<T> ©right(const std::string &t) {_copyright=t;return *this;}
173.671 -
173.672 -protected:
173.673 - bool isInsideNode(xy<double> p, double r,int t)
173.674 - {
173.675 - switch(t) {
173.676 - case CIRCLE:
173.677 - return p.normSquare()<=r*r;
173.678 - case SQUARE:
173.679 - return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
173.680 - case DIAMOND:
173.681 - return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
173.682 - }
173.683 - return false;
173.684 - }
173.685 -
173.686 -public:
173.687 - ~GraphToEps() { }
173.688 -
173.689 - ///Draws the graph.
173.690 -
173.691 - ///Like other functions using
173.692 - ///\ref named-templ-func-param "named template parameters",
173.693 - ///this function calles the algorithm itself, i.e. in this case
173.694 - ///it draws the graph.
173.695 - void run() {
173.696 - if(dontPrint) return;
173.697 -
173.698 - os << "%!PS-Adobe-2.0 EPSF-2.0\n";
173.699 - if(_title.size()>0) os << "%%Title: " << _title << '\n';
173.700 - if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
173.701 -// << "%%Copyright: XXXX\n"
173.702 - os << "%%Creator: LEMON GraphToEps function\n";
173.703 -
173.704 - {
173.705 - char cbuf[50];
173.706 - timeval tv;
173.707 - gettimeofday(&tv, 0);
173.708 - ctime_r(&tv.tv_sec,cbuf);
173.709 - os << "%%CreationDate: " << cbuf;
173.710 - }
173.711 - ///\todo: Chech whether the graph is empty.
173.712 - BoundingBox<double> bb;
173.713 - for(NodeIt n(g);n!=INVALID;++n) {
173.714 - double ns=_nodeSizes[n]*_nodeScale;
173.715 - xy<double> p(ns,ns);
173.716 - bb+=p+_coords[n];
173.717 - bb+=-p+_coords[n];
173.718 - }
173.719 - if(_scaleToA4)
173.720 - os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
173.721 - else os << "%%BoundingBox: "
173.722 - << bb.left()* _scale-_xBorder << ' '
173.723 - << bb.bottom()*_scale-_yBorder << ' '
173.724 - << bb.right()* _scale+_xBorder << ' '
173.725 - << bb.top()* _scale+_yBorder << '\n';
173.726 -
173.727 - os << "%%EndComments\n";
173.728 -
173.729 - //x1 y1 x2 y2 x3 y3 cr cg cb w
173.730 - os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
173.731 - << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
173.732 - os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
173.733 - //x y r
173.734 - os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
173.735 - //x y r
173.736 - os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
173.737 - << " 2 index 1 index sub 2 index 2 index add lineto\n"
173.738 - << " 2 index 1 index sub 2 index 2 index sub lineto\n"
173.739 - << " 2 index 1 index add 2 index 2 index sub lineto\n"
173.740 - << " closepath pop pop pop} bind def\n";
173.741 - //x y r
173.742 - os << "/di { newpath 2 index 1 index add 2 index moveto\n"
173.743 - << " 2 index 2 index 2 index add lineto\n"
173.744 - << " 2 index 1 index sub 2 index lineto\n"
173.745 - << " 2 index 2 index 2 index sub lineto\n"
173.746 - << " closepath pop pop pop} bind def\n";
173.747 - // x y r cr cg cb
173.748 - os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
173.749 - << " setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
173.750 - << " } bind def\n";
173.751 - os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
173.752 - << " setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
173.753 - << " } bind def\n";
173.754 - os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
173.755 - << " setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
173.756 - << " } bind def\n";
173.757 - os << "/arrl " << _arrowLength << " def\n";
173.758 - os << "/arrw " << _arrowWidth << " def\n";
173.759 - // l dx_norm dy_norm
173.760 - os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
173.761 - //len w dx_norm dy_norm x1 y1 cr cg cb
173.762 - os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
173.763 - << " /w exch def /len exch def\n"
173.764 - // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
173.765 - << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
173.766 - << " len w sub arrl sub dx dy lrl\n"
173.767 - << " arrw dy dx neg lrl\n"
173.768 - << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
173.769 - << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
173.770 - << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
173.771 - << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
173.772 - << " arrw dy dx neg lrl\n"
173.773 - << " len w sub arrl sub neg dx dy lrl\n"
173.774 - << " closepath fill } bind def\n";
173.775 - os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
173.776 - << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
173.777 -
173.778 - os << "\ngsave\n";
173.779 - if(_scaleToA4)
173.780 - if(bb.height()>bb.width()) {
173.781 - double sc= min((A4HEIGHT-2*A4BORDER)/bb.height(),
173.782 - (A4WIDTH-2*A4BORDER)/bb.width());
173.783 - os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
173.784 - << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER << " translate\n"
173.785 - << sc << " dup scale\n"
173.786 - << -bb.left() << ' ' << -bb.bottom() << " translate\n";
173.787 - }
173.788 - else {
173.789 - //\todo Verify centering
173.790 - double sc= min((A4HEIGHT-2*A4BORDER)/bb.width(),
173.791 - (A4WIDTH-2*A4BORDER)/bb.height());
173.792 - os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
173.793 - << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER << " translate\n"
173.794 - << sc << " dup scale\n90 rotate\n"
173.795 - << -bb.left() << ' ' << -bb.top() << " translate\n";
173.796 - }
173.797 - else if(_scale!=1.0) os << _scale << " dup scale\n";
173.798 -
173.799 - if(_showEdges) {
173.800 - os << "%Edges:\ngsave\n";
173.801 - if(_enableParallel) {
173.802 - std::vector<Edge> el;
173.803 - for(EdgeIt e(g);e!=INVALID;++e)
173.804 - if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
173.805 - el.push_back(e);
173.806 - sort(el.begin(),el.end(),edgeLess(g));
173.807 -
173.808 - typename std::vector<Edge>::iterator j;
173.809 - for(typename std::vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
173.810 - for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
173.811 -
173.812 - double sw=0;
173.813 - for(typename std::vector<Edge>::iterator e=i;e!=j;++e)
173.814 - sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
173.815 - sw-=_parEdgeDist;
173.816 - sw/=-2.0;
173.817 - xy<double> dvec(_coords[g.target(*i)]-_coords[g.source(*i)]);
173.818 - double l=std::sqrt(dvec.normSquare());
173.819 - ///\todo better 'epsilon' would be nice here.
173.820 - xy<double> d(dvec/std::max(l,1e-9));
173.821 - xy<double> m;
173.822 -// m=xy<double>(_coords[g.target(*i)]+_coords[g.source(*i)])/2.0;
173.823 -
173.824 -// m=xy<double>(_coords[g.source(*i)])+
173.825 -// dvec*(double(_nodeSizes[g.source(*i)])/
173.826 -// (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
173.827 -
173.828 - m=xy<double>(_coords[g.source(*i)])+
173.829 - d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
173.830 -
173.831 - for(typename std::vector<Edge>::iterator e=i;e!=j;++e) {
173.832 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
173.833 - xy<double> mm=m+rot90(d)*sw/.75;
173.834 - if(_drawArrows) {
173.835 - int node_shape;
173.836 - xy<double> s=_coords[g.source(*e)];
173.837 - xy<double> t=_coords[g.target(*e)];
173.838 - double rn=_nodeSizes[g.target(*e)]*_nodeScale;
173.839 - node_shape=_nodeShapes[g.target(*e)];
173.840 - Bezier3 bez(s,mm,mm,t);
173.841 - double t1=0,t2=1;
173.842 - for(int i=0;i<INTERPOL_PREC;++i)
173.843 - if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
173.844 - else t1=(t1+t2)/2;
173.845 - xy<double> apoint=bez((t1+t2)/2);
173.846 - rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale;
173.847 - rn*=rn;
173.848 - t2=(t1+t2)/2;t1=0;
173.849 - for(int i=0;i<INTERPOL_PREC;++i)
173.850 - if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
173.851 - else t2=(t1+t2)/2;
173.852 - xy<double> linend=bez((t1+t2)/2);
173.853 - bez=bez.before((t1+t2)/2);
173.854 -// rn=_nodeSizes[g.source(*e)]*_nodeScale;
173.855 -// node_shape=_nodeShapes[g.source(*e)];
173.856 -// t1=0;t2=1;
173.857 -// for(int i=0;i<INTERPOL_PREC;++i)
173.858 -// if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
173.859 -// else t2=(t1+t2)/2;
173.860 -// bez=bez.after((t1+t2)/2);
173.861 - os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
173.862 - << _edgeColors[*e].getR() << ' '
173.863 - << _edgeColors[*e].getG() << ' '
173.864 - << _edgeColors[*e].getB() << " setrgbcolor newpath\n"
173.865 - << bez.p1.x << ' ' << bez.p1.y << " moveto\n"
173.866 - << bez.p2.x << ' ' << bez.p2.y << ' '
173.867 - << bez.p3.x << ' ' << bez.p3.y << ' '
173.868 - << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
173.869 - xy<double> dd(rot90(linend-apoint));
173.870 - dd*=(.5*_edgeWidths[*e]*_edgeWidthScale+_arrowWidth)/
173.871 - std::sqrt(dd.normSquare());
173.872 - os << "newpath " << psOut(apoint) << " moveto "
173.873 - << psOut(linend+dd) << " lineto "
173.874 - << psOut(linend-dd) << " lineto closepath fill\n";
173.875 - }
173.876 - else {
173.877 - os << _coords[g.source(*e)].x << ' '
173.878 - << _coords[g.source(*e)].y << ' '
173.879 - << mm.x << ' ' << mm.y << ' '
173.880 - << _coords[g.target(*e)].x << ' '
173.881 - << _coords[g.target(*e)].y << ' '
173.882 - << _edgeColors[*e].getR() << ' '
173.883 - << _edgeColors[*e].getG() << ' '
173.884 - << _edgeColors[*e].getB() << ' '
173.885 - << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
173.886 - }
173.887 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
173.888 - }
173.889 - }
173.890 - }
173.891 - else for(EdgeIt e(g);e!=INVALID;++e)
173.892 - if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
173.893 - if(_drawArrows) {
173.894 - xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
173.895 - double rn=_nodeSizes[g.target(e)]*_nodeScale;
173.896 - int node_shape=_nodeShapes[g.target(e)];
173.897 - double t1=0,t2=1;
173.898 - for(int i=0;i<INTERPOL_PREC;++i)
173.899 - if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
173.900 - else t2=(t1+t2)/2;
173.901 - double l=sqrt(d.normSquare());
173.902 - d/=l;
173.903 -
173.904 - os << l*(1-(t1+t2)/2) << ' '
173.905 - << _edgeWidths[e]*_edgeWidthScale << ' '
173.906 - << d.x << ' ' << d.y << ' '
173.907 - << _coords[g.source(e)].x << ' '
173.908 - << _coords[g.source(e)].y << ' '
173.909 - << _edgeColors[e].getR() << ' '
173.910 - << _edgeColors[e].getG() << ' '
173.911 - << _edgeColors[e].getB() << " arr\n";
173.912 - }
173.913 - else os << _coords[g.source(e)].x << ' '
173.914 - << _coords[g.source(e)].y << ' '
173.915 - << _coords[g.target(e)].x << ' '
173.916 - << _coords[g.target(e)].y << ' '
173.917 - << _edgeColors[e].getR() << ' '
173.918 - << _edgeColors[e].getG() << ' '
173.919 - << _edgeColors[e].getB() << ' '
173.920 - << _edgeWidths[e]*_edgeWidthScale << " l\n";
173.921 - os << "grestore\n";
173.922 - }
173.923 - if(_showNodes) {
173.924 - os << "%Nodes:\ngsave\n";
173.925 - for(NodeIt n(g);n!=INVALID;++n) {
173.926 - os << _coords[n].x << ' ' << _coords[n].y << ' '
173.927 - << _nodeSizes[n]*_nodeScale << ' '
173.928 - << _nodeColors[n].getR() << ' '
173.929 - << _nodeColors[n].getG() << ' '
173.930 - << _nodeColors[n].getB() << ' ';
173.931 - switch(_nodeShapes[n]) {
173.932 - case CIRCLE:
173.933 - os<< "nc";break;
173.934 - case SQUARE:
173.935 - os<< "nsq";break;
173.936 - case DIAMOND:
173.937 - os<< "ndi";break;
173.938 - }
173.939 - os<<'\n';
173.940 - }
173.941 - os << "grestore\n";
173.942 - }
173.943 - if(_showNodeText) {
173.944 - os << "%Node texts:\ngsave\n";
173.945 - os << "/fosi " << _nodeTextSize << " def\n";
173.946 - os << "(Helvetica) findfont fosi scalefont setfont\n";
173.947 - for(NodeIt n(g);n!=INVALID;++n) {
173.948 - switch(_nodeTextColorType) {
173.949 - case DIST_COL:
173.950 - os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
173.951 - break;
173.952 - case DIST_BW:
173.953 - os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
173.954 - break;
173.955 - case CUST_COL:
173.956 - os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
173.957 - break;
173.958 - default:
173.959 - os << "0 0 0 setrgbcolor\n";
173.960 - }
173.961 - os << _coords[n].x << ' ' << _coords[n].y
173.962 - << " (" << _nodeTexts[n] << ") cshow\n";
173.963 - }
173.964 - os << "grestore\n";
173.965 - }
173.966 - if(_showNodePsText) {
173.967 - os << "%Node PS blocks:\ngsave\n";
173.968 - for(NodeIt n(g);n!=INVALID;++n)
173.969 - os << _coords[n].x << ' ' << _coords[n].y
173.970 - << " moveto\n" << _nodePsTexts[n] << "\n";
173.971 - os << "grestore\n";
173.972 - }
173.973 -
173.974 - os << "grestore\nshowpage\n";
173.975 -
173.976 - //CleanUp:
173.977 - if(_pleaseRemoveOsStream) {delete &os;}
173.978 - }
173.979 -};
173.980 -
173.981 -
173.982 -///Generates an EPS file from a graph
173.983 -
173.984 -///\ingroup io_group
173.985 -///Generates an EPS file from a graph.
173.986 -///\param g is a reference to the graph to be printed
173.987 -///\param os is a reference to the output stream.
173.988 -///By default it is <tt>std::cout</tt>
173.989 -///
173.990 -///This function also has a lot of
173.991 -///\ref named-templ-func-param "named parameters",
173.992 -///they are declared as the members of class \ref GraphToEps. The following
173.993 -///example shows how to use these parameters.
173.994 -///\code
173.995 -/// graphToEps(g,os).scale(10).coords(coords)
173.996 -/// .nodeScale(2).nodeSizes(sizes)
173.997 -/// .edgeWidthScale(.4).run();
173.998 -///\endcode
173.999 -///\warning Don't forget to put the \ref GraphToEps::run() "run()"
173.1000 -///to the end of the parameter list.
173.1001 -///\sa GraphToEps
173.1002 -///\sa graphToEps(G &g, char *file_name)
173.1003 -template<class G>
173.1004 -GraphToEps<DefaultGraphToEpsTraits<G> >
173.1005 -graphToEps(G &g, std::ostream& os=std::cout)
173.1006 -{
173.1007 - return
173.1008 - GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
173.1009 -}
173.1010 -
173.1011 -///Generates an EPS file from a graph
173.1012 -
173.1013 -///\ingroup misc
173.1014 -///This function does the same as
173.1015 -///\ref graphToEps(G &g,std::ostream& os)
173.1016 -///but it writes its output into the file \c file_name
173.1017 -///instead of a stream.
173.1018 -///\sa graphToEps(G &g, std::ostream& os)
173.1019 -template<class G>
173.1020 -GraphToEps<DefaultGraphToEpsTraits<G> >
173.1021 -graphToEps(G &g,const char *file_name)
173.1022 -{
173.1023 - return GraphToEps<DefaultGraphToEpsTraits<G> >
173.1024 - (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
173.1025 -}
173.1026 -
173.1027 -} //END OF NAMESPACE LEMON
173.1028 -
173.1029 -#endif // LEMON_GRAPH_TO_EPS_H
174.1 --- a/src/lemon/graph_utils.h Sat May 21 21:04:57 2005 +0000
174.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
174.3 @@ -1,861 +0,0 @@
174.4 -/* -*- C++ -*-
174.5 - * src/lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library
174.6 - *
174.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
174.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
174.9 - *
174.10 - * Permission to use, modify and distribute this software is granted
174.11 - * provided that this copyright notice appears in all copies. For
174.12 - * precise terms see the accompanying LICENSE file.
174.13 - *
174.14 - * This software is provided "AS IS" with no warranty of any kind,
174.15 - * express or implied, and with no claim as to its suitability for any
174.16 - * purpose.
174.17 - *
174.18 - */
174.19 -
174.20 -#ifndef LEMON_GRAPH_UTILS_H
174.21 -#define LEMON_GRAPH_UTILS_H
174.22 -
174.23 -#include <iterator>
174.24 -#include <vector>
174.25 -#include <map>
174.26 -
174.27 -#include <lemon/invalid.h>
174.28 -#include <lemon/utility.h>
174.29 -#include <lemon/maps.h>
174.30 -
174.31 -///\ingroup gutils
174.32 -///\file
174.33 -///\brief Graph utilities.
174.34 -///
174.35 -///\todo Please
174.36 -///revise the documentation.
174.37 -///
174.38 -
174.39 -
174.40 -namespace lemon {
174.41 -
174.42 - /// \addtogroup gutils
174.43 - /// @{
174.44 -
174.45 - /// \brief Function to count the items in the graph.
174.46 - ///
174.47 - /// This function counts the items in the graph.
174.48 - /// The complexity of the function is O(n) because
174.49 - /// it iterates on all of the items.
174.50 -
174.51 - template <typename Graph, typename ItemIt>
174.52 - inline int countItems(const Graph& g) {
174.53 - int num = 0;
174.54 - for (ItemIt it(g); it != INVALID; ++it) {
174.55 - ++num;
174.56 - }
174.57 - return num;
174.58 - }
174.59 -
174.60 - // Node counting:
174.61 -
174.62 - template <typename Graph>
174.63 - inline
174.64 - typename enable_if<typename Graph::NodeNumTag, int>::type
174.65 - _countNodes(const Graph &g) {
174.66 - return g.nodeNum();
174.67 - }
174.68 -
174.69 - template <typename Graph>
174.70 - inline int _countNodes(Wrap<Graph> w) {
174.71 - return countItems<Graph, typename Graph::NodeIt>(w.value);
174.72 - }
174.73 -
174.74 - /// \brief Function to count the nodes in the graph.
174.75 - ///
174.76 - /// This function counts the nodes in the graph.
174.77 - /// The complexity of the function is O(n) but for some
174.78 - /// graph structure it is specialized to run in O(1).
174.79 - ///
174.80 - /// \todo refer how to specialize it
174.81 -
174.82 - template <typename Graph>
174.83 - inline int countNodes(const Graph& g) {
174.84 - return _countNodes<Graph>(g);
174.85 - }
174.86 -
174.87 - // Edge counting:
174.88 -
174.89 - template <typename Graph>
174.90 - inline
174.91 - typename enable_if<typename Graph::EdgeNumTag, int>::type
174.92 - _countEdges(const Graph &g) {
174.93 - return g.edgeNum();
174.94 - }
174.95 -
174.96 - template <typename Graph>
174.97 - inline int _countEdges(Wrap<Graph> w) {
174.98 - return countItems<Graph, typename Graph::EdgeIt>(w.value);
174.99 - }
174.100 -
174.101 - /// \brief Function to count the edges in the graph.
174.102 - ///
174.103 - /// This function counts the edges in the graph.
174.104 - /// The complexity of the function is O(e) but for some
174.105 - /// graph structure it is specialized to run in O(1).
174.106 -
174.107 - template <typename Graph>
174.108 - inline int countEdges(const Graph& g) {
174.109 - return _countEdges<Graph>(g);
174.110 - }
174.111 -
174.112 - // Undirected edge counting:
174.113 -
174.114 - template <typename Graph>
174.115 - inline
174.116 - typename enable_if<typename Graph::EdgeNumTag, int>::type
174.117 - _countUndirEdges(const Graph &g) {
174.118 - return g.undirEdgeNum();
174.119 - }
174.120 -
174.121 - template <typename Graph>
174.122 - inline int _countUndirEdges(Wrap<Graph> w) {
174.123 - return countItems<Graph, typename Graph::UndirEdgeIt>(w.value);
174.124 - }
174.125 -
174.126 - /// \brief Function to count the edges in the graph.
174.127 - ///
174.128 - /// This function counts the edges in the graph.
174.129 - /// The complexity of the function is O(e) but for some
174.130 - /// graph structure it is specialized to run in O(1).
174.131 -
174.132 - template <typename Graph>
174.133 - inline int countUndirEdges(const Graph& g) {
174.134 - return _countUndirEdges<Graph>(g);
174.135 - }
174.136 -
174.137 -
174.138 -
174.139 - template <typename Graph, typename DegIt>
174.140 - inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
174.141 - int num = 0;
174.142 - for (DegIt it(_g, _n); it != INVALID; ++it) {
174.143 - ++num;
174.144 - }
174.145 - return num;
174.146 - }
174.147 -
174.148 - /// Finds an edge between two nodes of a graph.
174.149 -
174.150 - /// Finds an edge from node \c u to node \c v in graph \c g.
174.151 - ///
174.152 - /// If \c prev is \ref INVALID (this is the default value), then
174.153 - /// it finds the first edge from \c u to \c v. Otherwise it looks for
174.154 - /// the next edge from \c u to \c v after \c prev.
174.155 - /// \return The found edge or \ref INVALID if there is no such an edge.
174.156 - ///
174.157 - /// Thus you can iterate through each edge from \c u to \c v as it follows.
174.158 - /// \code
174.159 - /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
174.160 - /// ...
174.161 - /// }
174.162 - /// \endcode
174.163 - /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
174.164 - /// interface here...
174.165 - /// \bug Untested ...
174.166 - template <typename Graph>
174.167 - typename Graph::Edge findEdge(const Graph &g,
174.168 - typename Graph::Node u, typename Graph::Node v,
174.169 - typename Graph::Edge prev = INVALID)
174.170 - {
174.171 - typename Graph::OutEdgeIt e(g,prev);
174.172 - // if(prev==INVALID) g.first(e,u);
174.173 - if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
174.174 - else ++e;
174.175 - while(e!=INVALID && g.target(e)!=v) ++e;
174.176 - return e;
174.177 - }
174.178 -
174.179 - ///\e
174.180 -
174.181 - ///\todo Please document.
174.182 - ///
174.183 - template <typename Graph>
174.184 - inline int countOutEdges(const Graph& _g, const typename Graph::Node& _n) {
174.185 - return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
174.186 - }
174.187 -
174.188 - ///\e
174.189 -
174.190 - ///\todo Please document.
174.191 - ///
174.192 - template <typename Graph>
174.193 - inline int countInEdges(const Graph& _g, const typename Graph::Node& _n) {
174.194 - return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
174.195 - }
174.196 -
174.197 - // graph copy
174.198 -
174.199 - template <
174.200 - typename DestinationGraph,
174.201 - typename SourceGraph,
174.202 - typename NodeBijection>
174.203 - void copyNodes(DestinationGraph& _d, const SourceGraph& _s,
174.204 - NodeBijection& _nb) {
174.205 - for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
174.206 - _nb[it] = _d.addNode();
174.207 - }
174.208 - }
174.209 -
174.210 - template <
174.211 - typename DestinationGraph,
174.212 - typename SourceGraph,
174.213 - typename NodeBijection,
174.214 - typename EdgeBijection>
174.215 - void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
174.216 - const NodeBijection& _nb, EdgeBijection& _eb) {
174.217 - for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
174.218 - _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
174.219 - }
174.220 - }
174.221 -
174.222 - template <
174.223 - typename DestinationGraph,
174.224 - typename SourceGraph,
174.225 - typename NodeBijection,
174.226 - typename EdgeBijection>
174.227 - void copyGraph(DestinationGraph& _d, const SourceGraph& _s,
174.228 - NodeBijection& _nb, EdgeBijection& _eb) {
174.229 - nodeCopy(_d, _s, _nb);
174.230 - edgeCopy(_d, _s, _nb, _eb);
174.231 - }
174.232 -
174.233 - template <
174.234 - typename _DestinationGraph,
174.235 - typename _SourceGraph,
174.236 - typename _NodeBijection
174.237 - =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
174.238 - typename _EdgeBijection
174.239 - = typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
174.240 - >
174.241 - class GraphCopy {
174.242 - public:
174.243 -
174.244 - typedef _DestinationGraph DestinationGraph;
174.245 - typedef _SourceGraph SourceGraph;
174.246 -
174.247 - typedef _NodeBijection NodeBijection;
174.248 - typedef _EdgeBijection EdgeBijection;
174.249 -
174.250 - protected:
174.251 -
174.252 - NodeBijection node_bijection;
174.253 - EdgeBijection edge_bijection;
174.254 -
174.255 - public:
174.256 -
174.257 - GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
174.258 - copyGraph(_d, _s, node_bijection, edge_bijection);
174.259 - }
174.260 -
174.261 - const NodeBijection& getNodeBijection() const {
174.262 - return node_bijection;
174.263 - }
174.264 -
174.265 - const EdgeBijection& getEdgeBijection() const {
174.266 - return edge_bijection;
174.267 - }
174.268 -
174.269 - };
174.270 -
174.271 -
174.272 - template <typename _Graph, typename _Item>
174.273 - class ItemSetTraits {};
174.274 -
174.275 - template <typename _Graph>
174.276 - class ItemSetTraits<_Graph, typename _Graph::Node> {
174.277 - public:
174.278 -
174.279 - typedef _Graph Graph;
174.280 -
174.281 - typedef typename Graph::Node Item;
174.282 - typedef typename Graph::NodeIt ItemIt;
174.283 -
174.284 - template <typename _Value>
174.285 - class Map : public Graph::template NodeMap<_Value> {
174.286 - public:
174.287 - typedef typename Graph::template NodeMap<_Value> Parent;
174.288 - typedef typename Parent::Value Value;
174.289 -
174.290 - Map(const Graph& _graph) : Parent(_graph) {}
174.291 - Map(const Graph& _graph, const Value& _value)
174.292 - : Parent(_graph, _value) {}
174.293 - };
174.294 -
174.295 - };
174.296 -
174.297 - template <typename _Graph>
174.298 - class ItemSetTraits<_Graph, typename _Graph::Edge> {
174.299 - public:
174.300 -
174.301 - typedef _Graph Graph;
174.302 -
174.303 - typedef typename Graph::Edge Item;
174.304 - typedef typename Graph::EdgeIt ItemIt;
174.305 -
174.306 - template <typename _Value>
174.307 - class Map : public Graph::template EdgeMap<_Value> {
174.308 - public:
174.309 - typedef typename Graph::template EdgeMap<_Value> Parent;
174.310 - typedef typename Parent::Value Value;
174.311 -
174.312 - Map(const Graph& _graph) : Parent(_graph) {}
174.313 - Map(const Graph& _graph, const Value& _value)
174.314 - : Parent(_graph, _value) {}
174.315 - };
174.316 -
174.317 - };
174.318 -
174.319 - template <typename _Graph>
174.320 - class ItemSetTraits<_Graph, typename _Graph::UndirEdge> {
174.321 - public:
174.322 -
174.323 - typedef _Graph Graph;
174.324 -
174.325 - typedef typename Graph::UndirEdge Item;
174.326 - typedef typename Graph::UndirEdgeIt ItemIt;
174.327 -
174.328 - template <typename _Value>
174.329 - class Map : public Graph::template UndirEdgeMap<_Value> {
174.330 - public:
174.331 - typedef typename Graph::template UndirEdgeMap<_Value> Parent;
174.332 - typedef typename Parent::Value Value;
174.333 -
174.334 - Map(const Graph& _graph) : Parent(_graph) {}
174.335 - Map(const Graph& _graph, const Value& _value)
174.336 - : Parent(_graph, _value) {}
174.337 - };
174.338 -
174.339 - };
174.340 -
174.341 - /// @}
174.342 -
174.343 - /// \addtogroup graph_maps
174.344 - /// @{
174.345 -
174.346 - template <typename Map, typename Enable = void>
174.347 - struct ReferenceMapTraits {
174.348 - typedef typename Map::Value Value;
174.349 - typedef typename Map::Value& Reference;
174.350 - typedef const typename Map::Value& ConstReference;
174.351 - typedef typename Map::Value* Pointer;
174.352 - typedef const typename Map::Value* ConstPointer;
174.353 - };
174.354 -
174.355 - template <typename Map>
174.356 - struct ReferenceMapTraits<
174.357 - Map,
174.358 - typename enable_if<typename Map::FullTypeTag, void>::type
174.359 - > {
174.360 - typedef typename Map::Value Value;
174.361 - typedef typename Map::Reference Reference;
174.362 - typedef typename Map::ConstReference ConstReference;
174.363 - typedef typename Map::Pointer Pointer;
174.364 - typedef typename Map::ConstPointer ConstPointer;
174.365 - };
174.366 -
174.367 - /// Provides an immutable and unique id for each item in the graph.
174.368 -
174.369 - /// The IdMap class provides an unique and immutable mapping for each item
174.370 - /// in the graph.
174.371 - ///
174.372 - template <typename _Graph, typename _Item>
174.373 - class IdMap {
174.374 - public:
174.375 - typedef _Graph Graph;
174.376 - typedef int Value;
174.377 - typedef _Item Item;
174.378 - typedef _Item Key;
174.379 -
174.380 - typedef True NeedCopy;
174.381 -
174.382 - /// \brief Constructor.
174.383 - ///
174.384 - /// Constructor for creating id map.
174.385 - IdMap(const Graph& _graph) : graph(&_graph) {}
174.386 -
174.387 - /// \brief Gives back the \e id of the item.
174.388 - ///
174.389 - /// Gives back the immutable and unique \e id of the map.
174.390 - int operator[](const Item& item) const { return graph->id(item);}
174.391 -
174.392 -
174.393 - private:
174.394 - const Graph* graph;
174.395 -
174.396 - public:
174.397 -
174.398 - /// \brief The class represents the inverse of the map.
174.399 - ///
174.400 - /// The class represents the inverse of the map.
174.401 - /// \see inverse()
174.402 - class InverseMap {
174.403 - public:
174.404 -
174.405 - typedef True NeedCopy;
174.406 -
174.407 - /// \brief Constructor.
174.408 - ///
174.409 - /// Constructor for creating an id-to-item map.
174.410 - InverseMap(const Graph& _graph) : graph(&_graph) {}
174.411 -
174.412 - /// \brief Constructor.
174.413 - ///
174.414 - /// Constructor for creating an id-to-item map.
174.415 - InverseMap(const IdMap& idMap) : graph(idMap.graph) {}
174.416 -
174.417 - /// \brief Gives back the given item from its id.
174.418 - ///
174.419 - /// Gives back the given item from its id.
174.420 - ///
174.421 - Item operator[](int id) const { return graph->fromId(id, Item());}
174.422 - private:
174.423 - const Graph* graph;
174.424 - };
174.425 -
174.426 - /// \brief Gives back the inverse of the map.
174.427 - ///
174.428 - /// Gives back the inverse of the map.
174.429 - InverseMap inverse() const { return InverseMap(*graph);}
174.430 -
174.431 - };
174.432 -
174.433 -
174.434 - /// \brief General inversable graph-map type.
174.435 -
174.436 - /// This type provides simple inversable map functions.
174.437 - /// The InversableMap wraps an arbitrary ReadWriteMap
174.438 - /// and if a key is setted to a new value then store it
174.439 - /// in the inverse map.
174.440 - /// \param _Graph The graph type.
174.441 - /// \param _Map The map to extend with inversable functionality.
174.442 - template <
174.443 - typename _Graph,
174.444 - typename _Item,
174.445 - typename _Value,
174.446 - typename _Map
174.447 - = typename ItemSetTraits<_Graph, _Item>::template Map<_Value>::Parent
174.448 - >
174.449 - class InvertableMap : protected _Map {
174.450 -
174.451 - public:
174.452 -
174.453 - typedef _Map Map;
174.454 - typedef _Graph Graph;
174.455 -
174.456 - /// The key type of InvertableMap (Node, Edge, UndirEdge).
174.457 - typedef typename _Map::Key Key;
174.458 - /// The value type of the InvertableMap.
174.459 - typedef typename _Map::Value Value;
174.460 -
174.461 - /// \brief Constructor.
174.462 - ///
174.463 - /// Construct a new InvertableMap for the graph.
174.464 - ///
174.465 - InvertableMap(const Graph& graph) : Map(graph) {}
174.466 -
174.467 - /// \brief The setter function of the map.
174.468 - ///
174.469 - /// Sets the mapped value.
174.470 - void set(const Key& key, const Value& val) {
174.471 - Value oldval = Map::operator[](key);
174.472 - typename Container::iterator it = invMap.find(oldval);
174.473 - if (it != invMap.end() && it->second == key) {
174.474 - invMap.erase(it);
174.475 - }
174.476 - invMap.insert(make_pair(val, key));
174.477 - Map::set(key, val);
174.478 - }
174.479 -
174.480 - /// \brief The getter function of the map.
174.481 - ///
174.482 - /// It gives back the value associated with the key.
174.483 - const Value operator[](const Key& key) const {
174.484 - return Map::operator[](key);
174.485 - }
174.486 -
174.487 - /// \brief Add a new key to the map.
174.488 - ///
174.489 - /// Add a new key to the map. It is called by the
174.490 - /// \c AlterationNotifier.
174.491 - virtual void add(const Key& key) {
174.492 - Map::add(key);
174.493 - }
174.494 -
174.495 - /// \brief Erase the key from the map.
174.496 - ///
174.497 - /// Erase the key to the map. It is called by the
174.498 - /// \c AlterationNotifier.
174.499 - virtual void erase(const Key& key) {
174.500 - Value val = Map::operator[](key);
174.501 - typename Container::iterator it = invMap.find(val);
174.502 - if (it != invMap.end() && it->second == key) {
174.503 - invMap.erase(it);
174.504 - }
174.505 - Map::erase(key);
174.506 - }
174.507 -
174.508 - /// \brief Clear the keys from the map and inverse map.
174.509 - ///
174.510 - /// Clear the keys from the map and inverse map. It is called by the
174.511 - /// \c AlterationNotifier.
174.512 - virtual void clear() {
174.513 - invMap.clear();
174.514 - Map::clear();
174.515 - }
174.516 -
174.517 - private:
174.518 -
174.519 - typedef std::map<Value, Key> Container;
174.520 - Container invMap;
174.521 -
174.522 - public:
174.523 -
174.524 - /// \brief The inverse map type.
174.525 - ///
174.526 - /// The inverse of this map. The subscript operator of the map
174.527 - /// gives back always the item what was last assigned to the value.
174.528 - class InverseMap {
174.529 - public:
174.530 - /// \brief Constructor of the InverseMap.
174.531 - ///
174.532 - /// Constructor of the InverseMap.
174.533 - InverseMap(const InvertableMap& _inverted) : inverted(_inverted) {}
174.534 -
174.535 - /// The value type of the InverseMap.
174.536 - typedef typename InvertableMap::Key Value;
174.537 - /// The key type of the InverseMap.
174.538 - typedef typename InvertableMap::Value Key;
174.539 -
174.540 - /// \brief Subscript operator.
174.541 - ///
174.542 - /// Subscript operator. It gives back always the item
174.543 - /// what was last assigned to the value.
174.544 - Value operator[](const Key& key) const {
174.545 - typename Container::const_iterator it = inverted.invMap.find(key);
174.546 - return it->second;
174.547 - }
174.548 -
174.549 - private:
174.550 - const InvertableMap& inverted;
174.551 - };
174.552 -
174.553 - /// \brief It gives back the just readeable inverse map.
174.554 - ///
174.555 - /// It gives back the just readeable inverse map.
174.556 - InverseMap inverse() const {
174.557 - return InverseMap(*this);
174.558 - }
174.559 -
174.560 -
174.561 -
174.562 - };
174.563 -
174.564 - /// \brief Provides a mutable, continuous and unique descriptor for each
174.565 - /// item in the graph.
174.566 - ///
174.567 - /// The DescriptorMap class provides a mutable, continuous and immutable
174.568 - /// mapping for each item in the graph. The value for an item may mutated
174.569 - /// on each operation when the an item erased or added to graph.
174.570 - ///
174.571 - /// \param _Graph The graph class the \c DescriptorMap belongs to.
174.572 - /// \param _Item The Item is the Key of the Map. It may be Node, Edge or
174.573 - /// UndirEdge.
174.574 - /// \param _Map A ReadWriteMap mapping from the item type to integer.
174.575 - template <
174.576 - typename _Graph,
174.577 - typename _Item,
174.578 - typename _Map
174.579 - = typename ItemSetTraits<_Graph, _Item>::template Map<int>::Parent
174.580 - >
174.581 - class DescriptorMap : protected _Map {
174.582 -
174.583 - typedef _Item Item;
174.584 - typedef _Map Map;
174.585 -
174.586 - public:
174.587 - /// The graph class of DescriptorMap.
174.588 - typedef _Graph Graph;
174.589 -
174.590 - /// The key type of DescriptorMap (Node, Edge, UndirEdge).
174.591 - typedef typename _Map::Key Key;
174.592 - /// The value type of DescriptorMap.
174.593 - typedef typename _Map::Value Value;
174.594 -
174.595 - /// \brief Constructor.
174.596 - ///
174.597 - /// Constructor for descriptor map.
174.598 - DescriptorMap(const Graph& _graph) : Map(_graph) {
174.599 - build();
174.600 - }
174.601 -
174.602 - /// \brief Add a new key to the map.
174.603 - ///
174.604 - /// Add a new key to the map. It is called by the
174.605 - /// \c AlterationNotifier.
174.606 - virtual void add(const Item& item) {
174.607 - Map::add(item);
174.608 - Map::set(item, invMap.size());
174.609 - invMap.push_back(item);
174.610 - }
174.611 -
174.612 - /// \brief Erase the key from the map.
174.613 - ///
174.614 - /// Erase the key to the map. It is called by the
174.615 - /// \c AlterationNotifier.
174.616 - virtual void erase(const Item& item) {
174.617 - Map::set(invMap.back(), Map::operator[](item));
174.618 - invMap[Map::operator[](item)] = invMap.back();
174.619 - invMap.pop_back();
174.620 - Map::erase(item);
174.621 - }
174.622 -
174.623 - /// \brief Build the unique map.
174.624 - ///
174.625 - /// Build the unique map. It is called by the
174.626 - /// \c AlterationNotifier.
174.627 - virtual void build() {
174.628 - Map::build();
174.629 - Item it;
174.630 - const typename Map::Graph* graph = Map::getGraph();
174.631 - for (graph->first(it); it != INVALID; graph->next(it)) {
174.632 - Map::set(it, invMap.size());
174.633 - invMap.push_back(it);
174.634 - }
174.635 - }
174.636 -
174.637 - /// \brief Clear the keys from the map.
174.638 - ///
174.639 - /// Clear the keys from the map. It is called by the
174.640 - /// \c AlterationNotifier.
174.641 - virtual void clear() {
174.642 - invMap.clear();
174.643 - Map::clear();
174.644 - }
174.645 -
174.646 - /// \brief Gives back the \e descriptor of the item.
174.647 - ///
174.648 - /// Gives back the mutable and unique \e descriptor of the map.
174.649 - int operator[](const Item& item) const {
174.650 - return Map::operator[](item);
174.651 - }
174.652 -
174.653 - private:
174.654 -
174.655 - typedef std::vector<Item> Container;
174.656 - Container invMap;
174.657 -
174.658 - public:
174.659 - /// \brief The inverse map type.
174.660 - ///
174.661 - /// The inverse map type.
174.662 - class InverseMap {
174.663 - public:
174.664 - /// \brief Constructor of the InverseMap.
174.665 - ///
174.666 - /// Constructor of the InverseMap.
174.667 - InverseMap(const DescriptorMap& _inverted)
174.668 - : inverted(_inverted) {}
174.669 -
174.670 -
174.671 - /// The value type of the InverseMap.
174.672 - typedef typename DescriptorMap::Key Value;
174.673 - /// The key type of the InverseMap.
174.674 - typedef typename DescriptorMap::Value Key;
174.675 -
174.676 - /// \brief Subscript operator.
174.677 - ///
174.678 - /// Subscript operator. It gives back the item
174.679 - /// that the descriptor belongs to currently.
174.680 - Value operator[](const Key& key) const {
174.681 - return inverted.invMap[key];
174.682 - }
174.683 -
174.684 - private:
174.685 - const DescriptorMap& inverted;
174.686 - };
174.687 -
174.688 - /// \brief Gives back the inverse of the map.
174.689 - ///
174.690 - /// Gives back the inverse of the map.
174.691 - const InverseMap inverse() const {
174.692 - return InverseMap(*this);
174.693 - }
174.694 - };
174.695 -
174.696 - /// \brief Returns the source of the given edge.
174.697 - ///
174.698 - /// The SourceMap gives back the source Node of the given edge.
174.699 - /// \author Balazs Dezso
174.700 - template <typename Graph>
174.701 - class SourceMap {
174.702 - public:
174.703 -
174.704 - typedef True NeedCopy;
174.705 -
174.706 - typedef typename Graph::Node Value;
174.707 - typedef typename Graph::Edge Key;
174.708 -
174.709 - /// \brief Constructor
174.710 - ///
174.711 - /// Constructor
174.712 - /// \param _graph The graph that the map belongs to.
174.713 - SourceMap(const Graph& _graph) : graph(_graph) {}
174.714 -
174.715 - /// \brief The subscript operator.
174.716 - ///
174.717 - /// The subscript operator.
174.718 - /// \param edge The edge
174.719 - /// \return The source of the edge
174.720 - Value operator[](const Key& edge) {
174.721 - return graph.source(edge);
174.722 - }
174.723 -
174.724 - private:
174.725 - const Graph& graph;
174.726 - };
174.727 -
174.728 - /// \brief Returns a \ref SourceMap class
174.729 - ///
174.730 - /// This function just returns an \ref SourceMap class.
174.731 - /// \relates SourceMap
174.732 - template <typename Graph>
174.733 - inline SourceMap<Graph> sourceMap(const Graph& graph) {
174.734 - return SourceMap<Graph>(graph);
174.735 - }
174.736 -
174.737 - /// \brief Returns the target of the given edge.
174.738 - ///
174.739 - /// The TargetMap gives back the target Node of the given edge.
174.740 - /// \author Balazs Dezso
174.741 - template <typename Graph>
174.742 - class TargetMap {
174.743 - public:
174.744 -
174.745 - typedef True NeedCopy;
174.746 -
174.747 - typedef typename Graph::Node Value;
174.748 - typedef typename Graph::Edge Key;
174.749 -
174.750 - /// \brief Constructor
174.751 - ///
174.752 - /// Constructor
174.753 - /// \param _graph The graph that the map belongs to.
174.754 - TargetMap(const Graph& _graph) : graph(_graph) {}
174.755 -
174.756 - /// \brief The subscript operator.
174.757 - ///
174.758 - /// The subscript operator.
174.759 - /// \param edge The edge
174.760 - /// \return The target of the edge
174.761 - Value operator[](const Key& key) {
174.762 - return graph.target(key);
174.763 - }
174.764 -
174.765 - private:
174.766 - const Graph& graph;
174.767 - };
174.768 -
174.769 - /// \brief Returns a \ref TargetMap class
174.770 -
174.771 - /// This function just returns an \ref TargetMap class.
174.772 - /// \relates TargetMap
174.773 - template <typename Graph>
174.774 - inline TargetMap<Graph> targetMap(const Graph& graph) {
174.775 - return TargetMap<Graph>(graph);
174.776 - }
174.777 -
174.778 - /// \brief Returns the "forward" directed edge view of undirected edge.
174.779 - ///
174.780 - /// Returns the "forward" directed edge view of undirected edge.
174.781 - /// \author Balazs Dezso
174.782 - template <typename Graph>
174.783 - class ForwardMap {
174.784 - public:
174.785 -
174.786 - typedef True NeedCopy;
174.787 -
174.788 - typedef typename Graph::Edge Value;
174.789 - typedef typename Graph::UndirEdge Key;
174.790 -
174.791 - /// \brief Constructor
174.792 - ///
174.793 - /// Constructor
174.794 - /// \param _graph The graph that the map belongs to.
174.795 - ForwardMap(const Graph& _graph) : graph(_graph) {}
174.796 -
174.797 - /// \brief The subscript operator.
174.798 - ///
174.799 - /// The subscript operator.
174.800 - /// \param key An undirected edge
174.801 - /// \return The "forward" directed edge view of undirected edge
174.802 - Value operator[](const Key& key) const {
174.803 - return graph.edgeWithSource(key, graph.source(key));
174.804 - }
174.805 -
174.806 - private:
174.807 - const Graph& graph;
174.808 - };
174.809 -
174.810 - /// \brief Returns a \ref ForwardMap class
174.811 -
174.812 - /// This function just returns an \ref ForwardMap class.
174.813 - /// \relates ForwardMap
174.814 - template <typename Graph>
174.815 - inline ForwardMap<Graph> forwardMap(const Graph& graph) {
174.816 - return ForwardMap<Graph>(graph);
174.817 - }
174.818 -
174.819 - /// \brief Returns the "backward" directed edge view of undirected edge.
174.820 - ///
174.821 - /// Returns the "backward" directed edge view of undirected edge.
174.822 - /// \author Balazs Dezso
174.823 - template <typename Graph>
174.824 - class BackwardMap {
174.825 - public:
174.826 - typedef True NeedCopy;
174.827 -
174.828 - typedef typename Graph::Edge Value;
174.829 - typedef typename Graph::UndirEdge Key;
174.830 -
174.831 - /// \brief Constructor
174.832 - ///
174.833 - /// Constructor
174.834 - /// \param _graph The graph that the map belongs to.
174.835 - BackwardMap(const Graph& _graph) : graph(_graph) {}
174.836 -
174.837 - /// \brief The subscript operator.
174.838 - ///
174.839 - /// The subscript operator.
174.840 - /// \param key An undirected edge
174.841 - /// \return The "backward" directed edge view of undirected edge
174.842 - Value operator[](const Key& key) const {
174.843 - return graph.edgeWithSource(key, graph.target(key));
174.844 - }
174.845 -
174.846 - private:
174.847 - const Graph& graph;
174.848 - };
174.849 -
174.850 - /// \brief Returns a \ref BackwardMap class
174.851 -
174.852 - /// This function just returns an \ref BackwardMap class.
174.853 - /// \relates BackwardMap
174.854 - template <typename Graph>
174.855 - inline BackwardMap<Graph> backwardMap(const Graph& graph) {
174.856 - return BackwardMap<Graph>(graph);
174.857 - }
174.858 -
174.859 -
174.860 - /// @}
174.861 -
174.862 -} //END OF NAMESPACE LEMON
174.863 -
174.864 -#endif
175.1 --- a/src/lemon/graph_writer.h Sat May 21 21:04:57 2005 +0000
175.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
175.3 @@ -1,683 +0,0 @@
175.4 -/* -*- C++ -*-
175.5 - * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
175.6 - *
175.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
175.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
175.9 - *
175.10 - * Permission to use, modify and distribute this software is granted
175.11 - * provided that this copyright notice appears in all copies. For
175.12 - * precise terms see the accompanying LICENSE file.
175.13 - *
175.14 - * This software is provided "AS IS" with no warranty of any kind,
175.15 - * express or implied, and with no claim as to its suitability for any
175.16 - * purpose.
175.17 - *
175.18 - */
175.19 -
175.20 -///\ingroup io_group
175.21 -///\file
175.22 -///\brief Lemon Graph Format writer.
175.23 -
175.24 -#ifndef LEMON_GRAPH_WRITER_H
175.25 -#define LEMON_GRAPH_WRITER_H
175.26 -
175.27 -#include <iostream>
175.28 -
175.29 -#include <lemon/error.h>
175.30 -#include <lemon/lemon_writer.h>
175.31 -
175.32 -namespace lemon {
175.33 -
175.34 - /// \addtogroup io_group
175.35 - /// @{
175.36 -
175.37 - /// \brief The graph writer class.
175.38 - ///
175.39 - /// The \c GraphWriter class provides the graph output. To write a graph
175.40 - /// you should first give writing commands for the writer. You can declare
175.41 - /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and
175.42 - /// Edge writing.
175.43 - ///
175.44 - /// \code
175.45 - /// GraphWriter<ListGraph> writer(std::cout, graph);
175.46 - /// \endcode
175.47 - ///
175.48 - /// The \c writeNodeMap() function declares a \c NodeMap writing
175.49 - /// command in the \c GraphWriter. You should give as parameter
175.50 - /// the name of the map and the map object. The NodeMap writing
175.51 - /// command with name "id" should write a unique map because it
175.52 - /// is regarded as ID map.
175.53 - ///
175.54 - /// \code
175.55 - /// IdMap<ListGraph, Node> nodeIdMap;
175.56 - /// writer.writeNodeMap("id", nodeIdMap);
175.57 - ///
175.58 - /// writer.writeNodeMap("coords", coords);
175.59 - /// writer.writeNodeMap("color", colorMap);
175.60 - /// \endcode
175.61 - ///
175.62 - /// With the \c writeEdgeMap() member function you can give an edge map
175.63 - /// writing command similar to the NodeMaps.
175.64 - ///
175.65 - /// \code
175.66 - /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
175.67 - /// edgeDescMap(graph);
175.68 - /// writer.writeEdgeMap("descriptor", edgeDescMap);
175.69 - ///
175.70 - /// writer.writeEdgeMap("weight", weightMap);
175.71 - /// writer.writeEdgeMap("label", labelMap);
175.72 - /// \endcode
175.73 - ///
175.74 - /// With \c writeNode() and \c writeEdge() functions you can
175.75 - /// point out Nodes and Edges in the graph. By example, you can
175.76 - /// write out the source and target of the graph.
175.77 - ///
175.78 - /// \code
175.79 - /// writer.writeNode("source", sourceNode);
175.80 - /// writer.writeNode("target", targetNode);
175.81 - ///
175.82 - /// writer.writeEdge("observed", edge);
175.83 - /// \endcode
175.84 - ///
175.85 - /// After you give all write commands you must call the \c run() member
175.86 - /// function, which execute all the writer commands.
175.87 - ///
175.88 - /// \code
175.89 - /// writer.run();
175.90 - /// \endcode
175.91 - ///
175.92 - /// \see DefaultWriterTraits
175.93 - /// \see QuotedStringWriter
175.94 - /// \see IdMap
175.95 - /// \see DescriptorMap
175.96 - /// \see \ref GraphReader
175.97 - /// \see \ref graph-io-page
175.98 - /// \author Balazs Dezso
175.99 - template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
175.100 - class GraphWriter {
175.101 - public:
175.102 -
175.103 - typedef _Graph Graph;
175.104 - typedef typename Graph::Node Node;
175.105 - typedef typename Graph::Edge Edge;
175.106 -
175.107 - typedef _WriterTraits WriterTraits;
175.108 -
175.109 - /// \brief Construct a new GraphWriter.
175.110 - ///
175.111 - /// Construct a new GraphWriter. It writes the given graph
175.112 - /// to the given stream.
175.113 - GraphWriter(std::ostream& _os, const Graph& _graph)
175.114 - : writer(new LemonWriter(_os)), own_writer(true),
175.115 - nodeset_writer(*writer, _graph, std::string()),
175.116 - edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.117 - node_writer(*writer, nodeset_writer, std::string()),
175.118 - edge_writer(*writer, edgeset_writer, std::string()),
175.119 - attribute_writer(*writer, std::string()) {}
175.120 -
175.121 - /// \brief Construct a new GraphWriter.
175.122 - ///
175.123 - /// Construct a new GraphWriter. It writes into the given graph
175.124 - /// to the given file.
175.125 - GraphWriter(const std::string& _filename, const Graph& _graph)
175.126 - : writer(new LemonWriter(_filename)), own_writer(true),
175.127 - nodeset_writer(*writer, _graph, std::string()),
175.128 - edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.129 - node_writer(*writer, nodeset_writer, std::string()),
175.130 - edge_writer(*writer, edgeset_writer, std::string()),
175.131 - attribute_writer(*writer, std::string()) {}
175.132 -
175.133 - /// \brief Construct a new GraphWriter.
175.134 - ///
175.135 - /// Construct a new GraphWriter. It writes into the given graph
175.136 - /// to given LemonReader.
175.137 - GraphWriter(LemonWriter& _writer, const Graph& _graph)
175.138 - : writer(_writer), own_writer(false),
175.139 - nodeset_writer(*writer, _graph, std::string()),
175.140 - edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.141 - node_writer(*writer, nodeset_writer, std::string()),
175.142 - edge_writer(*writer, edgeset_writer, std::string()),
175.143 - attribute_writer(*writer, std::string()) {}
175.144 -
175.145 - /// \brief Destruct the graph writer.
175.146 - ///
175.147 - /// Destruct the graph writer.
175.148 - ~GraphWriter() {
175.149 - if (own_writer)
175.150 - delete writer;
175.151 - }
175.152 -
175.153 - /// \brief Add a new node map writer command for the writer.
175.154 - ///
175.155 - /// Add a new node map writer command for the writer.
175.156 - template <typename Map>
175.157 - GraphWriter& writeNodeMap(std::string name, const Map& map) {
175.158 - nodeset_writer.writeNodeMap(name, map);
175.159 - return *this;
175.160 - }
175.161 -
175.162 - /// \brief Add a new node map writer command for the writer.
175.163 - ///
175.164 - /// Add a new node map writer command for the writer.
175.165 - template <typename Writer, typename Map>
175.166 - GraphWriter& writeNodeMap(std::string name, const Map& map,
175.167 - const Writer& writer = Writer()) {
175.168 - nodeset_writer.writeNodeMap(name, map, writer);
175.169 - return *this;
175.170 - }
175.171 -
175.172 -
175.173 - /// \brief Add a new edge map writer command for the writer.
175.174 - ///
175.175 - /// Add a new edge map writer command for the writer.
175.176 - template <typename Map>
175.177 - GraphWriter& writeEdgeMap(std::string name, const Map& map) {
175.178 - edgeset_writer.writeEdgeMap(name, map);
175.179 - return *this;
175.180 - }
175.181 -
175.182 -
175.183 - /// \brief Add a new edge map writer command for the writer.
175.184 - ///
175.185 - /// Add a new edge map writer command for the writer.
175.186 - template <typename Writer, typename Map>
175.187 - GraphWriter& writeEdgeMap(std::string name, const Map& map,
175.188 - const Writer& writer = Writer()) {
175.189 - edgeset_writer.writeEdgeMap(name, map, writer);
175.190 - return *this;
175.191 - }
175.192 -
175.193 - /// \brief Add a new labeled node writer for the writer.
175.194 - ///
175.195 - /// Add a new labeled node writer for the writer.
175.196 - GraphWriter& writeNode(std::string name, const Node& node) {
175.197 - node_writer.writeNode(name, node);
175.198 - return *this;
175.199 - }
175.200 -
175.201 - /// \brief Add a new labeled edge writer for the writer.
175.202 - ///
175.203 - /// Add a new labeled edge writer for the writer.
175.204 - GraphWriter& writeEdge(std::string name, const Edge& edge) {
175.205 - edge_writer.writeEdge(name, edge);
175.206 - }
175.207 -
175.208 - /// \brief Add a new attribute writer command.
175.209 - ///
175.210 - /// Add a new attribute writer command.
175.211 - template <typename Value>
175.212 - GraphWriter& writeAttribute(std::string name, const Value& value) {
175.213 - attribute_writer.writeAttribute(name, value);
175.214 - return *this;
175.215 - }
175.216 -
175.217 - /// \brief Add a new attribute writer command.
175.218 - ///
175.219 - /// Add a new attribute writer command.
175.220 - template <typename Writer, typename Value>
175.221 - GraphWriter& writeAttribute(std::string name, const Value& value,
175.222 - const Writer& writer) {
175.223 - attribute_writer.writeAttribute<Writer>(name, value, writer);
175.224 - return *this;
175.225 - }
175.226 -
175.227 - /// \brief Conversion operator to LemonWriter.
175.228 - ///
175.229 - /// Conversion operator to LemonWriter. It make possible
175.230 - /// to access the encapsulated \e LemonWriter, this way
175.231 - /// you can attach to this writer new instances of
175.232 - /// \e LemonWriter::SectionWriter.
175.233 - operator LemonWriter&() {
175.234 - return *writer;
175.235 - }
175.236 -
175.237 - /// \brief Executes the writer commands.
175.238 - ///
175.239 - /// Executes the writer commands.
175.240 - void run() {
175.241 - writer->run();
175.242 - }
175.243 -
175.244 - /// \brief Write the id of the given node.
175.245 - ///
175.246 - /// It writes the id of the given node. If there was written an "id"
175.247 - /// named node map then it will write the map value belongs to the node.
175.248 - void writeId(std::ostream& os, const Node& item) const {
175.249 - nodeset_writer.writeId(os, item);
175.250 - }
175.251 -
175.252 - /// \brief Write the id of the given edge.
175.253 - ///
175.254 - /// It writes the id of the given edge. If there was written an "id"
175.255 - /// named edge map then it will write the map value belongs to the edge.
175.256 - void writeId(std::ostream& os, const Edge& item) const {
175.257 - edgeset_writer.writeId(os, item);
175.258 - }
175.259 -
175.260 - private:
175.261 -
175.262 - LemonWriter* writer;
175.263 - bool own_writer;
175.264 -
175.265 - NodeSetWriter<Graph, WriterTraits> nodeset_writer;
175.266 - EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
175.267 -
175.268 - NodeWriter<Graph> node_writer;
175.269 - EdgeWriter<Graph> edge_writer;
175.270 -
175.271 - AttributeWriter<WriterTraits> attribute_writer;
175.272 - };
175.273 -
175.274 -
175.275 - /// \brief Write a graph to the output.
175.276 - ///
175.277 - /// Write a graph to the output.
175.278 - /// \param os The output stream.
175.279 - /// \param g The graph.
175.280 - /// \param capacity The capacity map.
175.281 - /// \param s The source node.
175.282 - /// \param t The target node.
175.283 - /// \param cost The cost map.
175.284 - template<typename Graph, typename CapacityMap, typename CostMap>
175.285 - void writeGraph(std::ostream& os, const Graph &g,
175.286 - const CapacityMap& capacity, const typename Graph::Node &s,
175.287 - const typename Graph::Node &t, const CostMap& cost) {
175.288 - GraphWriter<Graph> writer(os, g);
175.289 - IdMap<Graph, typename Graph::Node> nodeIdMap(g);
175.290 - writer.writeNodeMap("id", nodeIdMap);
175.291 - IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
175.292 - writer.writeEdgeMap("id", edgeIdMap);
175.293 - writer.writeEdgeMap("capacity", capacity);
175.294 - writer.writeEdgeMap("cost", cost);
175.295 - writer.writeNode("source", s);
175.296 - writer.writeNode("target", t);
175.297 - writer.run();
175.298 - }
175.299 -
175.300 - /// \brief Write a graph to the output.
175.301 - ///
175.302 - /// Write a graph to the output.
175.303 - /// \param os The output stream.
175.304 - /// \param g The graph.
175.305 - /// \param capacity The capacity map.
175.306 - /// \param s The source node.
175.307 - /// \param t The target node.
175.308 - template<typename Graph, typename CapacityMap>
175.309 - void writeGraph(std::ostream& os, const Graph &g,
175.310 - const CapacityMap& capacity, const typename Graph::Node &s,
175.311 - const typename Graph::Node &t) {
175.312 - GraphWriter<Graph> writer(os, g);
175.313 - IdMap<Graph, typename Graph::Node> nodeIdMap(g);
175.314 - writer.writeNodeMap("id", nodeIdMap);
175.315 - IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
175.316 - writer.writeEdgeMap("id", edgeIdMap);
175.317 - writer.writeEdgeMap("capacity", capacity);
175.318 - writer.writeNode("source", s);
175.319 - writer.writeNode("target", t);
175.320 - writer.run();
175.321 - }
175.322 -
175.323 - /// \brief Write a graph to the output.
175.324 - ///
175.325 - /// Write a graph to the output.
175.326 - /// \param os The output stream.
175.327 - /// \param g The graph.
175.328 - /// \param capacity The capacity map.
175.329 - /// \param s The source node.
175.330 - template<typename Graph, typename CapacityMap>
175.331 - void writeGraph(std::ostream& os, const Graph &g,
175.332 - const CapacityMap& capacity, const typename Graph::Node &s) {
175.333 - GraphWriter<Graph> writer(os, g);
175.334 - IdMap<Graph, typename Graph::Node> nodeIdMap(g);
175.335 - writer.writeNodeMap("id", nodeIdMap);
175.336 - IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
175.337 - writer.writeEdgeMap("id", edgeIdMap);
175.338 - writer.writeEdgeMap("capacity", capacity);
175.339 - writer.writeNode("source", s);
175.340 - writer.run();
175.341 - }
175.342 -
175.343 - /// \brief Write a graph to the output.
175.344 - ///
175.345 - /// Write a graph to the output.
175.346 - /// \param os The output stream.
175.347 - /// \param g The graph.
175.348 - /// \param capacity The capacity map.
175.349 - template<typename Graph, typename CapacityMap>
175.350 - void writeGraph(std::ostream& os, const Graph &g,
175.351 - const CapacityMap& capacity) {
175.352 - GraphWriter<Graph> writer(os, g);
175.353 - IdMap<Graph, typename Graph::Node> nodeIdMap(g);
175.354 - writer.writeNodeMap("id", nodeIdMap);
175.355 - IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
175.356 - writer.writeEdgeMap("id", edgeIdMap);
175.357 - writer.writeEdgeMap("capacity", capacity);
175.358 - writer.run();
175.359 - }
175.360 -
175.361 - /// \brief Write a graph to the output.
175.362 - ///
175.363 - /// Write a graph to the output.
175.364 - /// \param os The output stream.
175.365 - /// \param g The graph.
175.366 - template<typename Graph>
175.367 - void writeGraph(std::ostream& os, const Graph &g) {
175.368 - GraphWriter<Graph> writer(os, g);
175.369 - IdMap<Graph, typename Graph::Node> nodeIdMap(g);
175.370 - writer.writeNodeMap("id", nodeIdMap);
175.371 - IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
175.372 - writer.writeEdgeMap("id", edgeIdMap);
175.373 - writer.run();
175.374 - }
175.375 -
175.376 - /// \brief The undirected graph writer class.
175.377 - ///
175.378 - /// The \c UndirGraphWriter class provides the undir graph output. To write
175.379 - /// a graph you should first give writing commands for the writer. You can
175.380 - /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
175.381 - /// writing and labeled Node, Edge or UndirEdge writing.
175.382 - ///
175.383 - /// \code
175.384 - /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
175.385 - /// \endcode
175.386 - ///
175.387 - /// The \c writeNodeMap() function declares a \c NodeMap writing
175.388 - /// command in the \c UndirGraphWriter. You should give as parameter
175.389 - /// the name of the map and the map object. The NodeMap writing
175.390 - /// command with name "id" should write a unique map because it
175.391 - /// is regarded as ID map.
175.392 - ///
175.393 - /// \code
175.394 - /// IdMap<UndirListGraph, Node> nodeIdMap;
175.395 - /// writer.writeNodeMap("id", nodeIdMap);
175.396 - ///
175.397 - /// writer.writeNodeMap("coords", coords);
175.398 - /// writer.writeNodeMap("color", colorMap);
175.399 - /// \endcode
175.400 - ///
175.401 - /// With the \c writeUndirEdgeMap() member function you can give an
175.402 - /// undirected edge map writing command similar to the NodeMaps.
175.403 - ///
175.404 - /// \code
175.405 - /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
175.406 - /// edgeDescMap(graph);
175.407 - /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
175.408 - ///
175.409 - /// writer.writeUndirEdgeMap("weight", weightMap);
175.410 - /// writer.writeUndirEdgeMap("label", labelMap);
175.411 - /// \endcode
175.412 - ///
175.413 - /// The EdgeMap handling is just a syntactical sugar. It writes
175.414 - /// two undirected edge map with '+' and '-' prefix in the name.
175.415 - ///
175.416 - /// \code
175.417 - /// writer.writeEdgeMap("capacity", capacityMap);
175.418 - /// \endcode
175.419 - ///
175.420 - ///
175.421 - /// With \c writeNode() and \c writeUndirEdge() functions you can
175.422 - /// point out nodes and undirected edges in the graph. By example, you can
175.423 - /// write out the source and target of the graph.
175.424 - ///
175.425 - /// \code
175.426 - /// writer.writeNode("source", sourceNode);
175.427 - /// writer.writeNode("target", targetNode);
175.428 - ///
175.429 - /// writer.writeUndirEdge("observed", undirEdge);
175.430 - /// \endcode
175.431 - ///
175.432 - /// After you give all write commands you must call the \c run() member
175.433 - /// function, which execute all the writer commands.
175.434 - ///
175.435 - /// \code
175.436 - /// writer.run();
175.437 - /// \endcode
175.438 - ///
175.439 - /// \see DefaultWriterTraits
175.440 - /// \see QuotedStringWriter
175.441 - /// \see IdMap
175.442 - /// \see DescriptorMap
175.443 - /// \see \ref GraphWriter
175.444 - /// \see \ref graph-io-page
175.445 - /// \author Balazs Dezso
175.446 - template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
175.447 - class UndirGraphWriter {
175.448 - public:
175.449 -
175.450 - typedef _Graph Graph;
175.451 - typedef typename Graph::Node Node;
175.452 - typedef typename Graph::Edge Edge;
175.453 - typedef typename Graph::UndirEdge UndirEdge;
175.454 -
175.455 - typedef _WriterTraits WriterTraits;
175.456 -
175.457 - /// \brief Construct a new UndirGraphWriter.
175.458 - ///
175.459 - /// Construct a new UndirGraphWriter. It writes the given graph
175.460 - /// to the given stream.
175.461 - UndirGraphWriter(std::ostream& _os, const Graph& _graph)
175.462 - : writer(new LemonWriter(_os)), own_writer(true),
175.463 - nodeset_writer(*writer, _graph, std::string()),
175.464 - undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.465 - node_writer(*writer, nodeset_writer, std::string()),
175.466 - undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
175.467 - attribute_writer(*writer, std::string()) {}
175.468 -
175.469 - /// \brief Construct a new UndirGraphWriter.
175.470 - ///
175.471 - /// Construct a new UndirGraphWriter. It writes into the given graph
175.472 - /// to the given file.
175.473 - UndirGraphWriter(const std::string& _filename, const Graph& _graph)
175.474 - : writer(new LemonWriter(_filename)), own_writer(true),
175.475 - nodeset_writer(*writer, _graph, std::string()),
175.476 - undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.477 - node_writer(*writer, nodeset_writer, std::string()),
175.478 - undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
175.479 - attribute_writer(*writer, std::string()) {}
175.480 -
175.481 - /// \brief Construct a new UndirGraphWriter.
175.482 - ///
175.483 - /// Construct a new UndirGraphWriter. It writes into the given graph
175.484 - /// to given LemonReader.
175.485 - UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
175.486 - : writer(_writer), own_writer(false),
175.487 - nodeset_writer(*writer, _graph, std::string()),
175.488 - undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
175.489 - node_writer(*writer, nodeset_writer, std::string()),
175.490 - undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
175.491 - attribute_writer(*writer, std::string()) {}
175.492 -
175.493 - /// \brief Destruct the graph writer.
175.494 - ///
175.495 - /// Destruct the graph writer.
175.496 - ~UndirGraphWriter() {
175.497 - if (own_writer)
175.498 - delete writer;
175.499 - }
175.500 -
175.501 - /// \brief Add a new node map writer command for the writer.
175.502 - ///
175.503 - /// Add a new node map writer command for the writer.
175.504 - template <typename Map>
175.505 - UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
175.506 - nodeset_writer.writeNodeMap(name, map);
175.507 - return *this;
175.508 - }
175.509 -
175.510 - /// \brief Add a new node map writer command for the writer.
175.511 - ///
175.512 - /// Add a new node map writer command for the writer.
175.513 - template <typename Writer, typename Map>
175.514 - UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
175.515 - const Writer& writer = Writer()) {
175.516 - nodeset_writer.writeNodeMap(name, map, writer);
175.517 - return *this;
175.518 - }
175.519 -
175.520 - /// \brief Add a new edge map writer command for the writer.
175.521 - ///
175.522 - /// Add a new edge map writer command for the writer.
175.523 - template <typename Map>
175.524 - UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
175.525 - undir_edgeset_writer.writeEdgeMap(name, map);
175.526 - return *this;
175.527 - }
175.528 -
175.529 - /// \brief Add a new edge map writer command for the writer.
175.530 - ///
175.531 - /// Add a new edge map writer command for the writer.
175.532 - template <typename Writer, typename Map>
175.533 - UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
175.534 - const Writer& writer = Writer()) {
175.535 - undir_edgeset_writer.writeEdgeMap(name, map, writer);
175.536 - return *this;
175.537 - }
175.538 -
175.539 - /// \brief Add a new undirected edge map writer command for the writer.
175.540 - ///
175.541 - /// Add a new undirected edge map writer command for the writer.
175.542 - template <typename Map>
175.543 - UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
175.544 - undir_edgeset_writer.writeUndirEdgeMap(name, map);
175.545 - return *this;
175.546 - }
175.547 -
175.548 - /// \brief Add a new undirected edge map writer command for the writer.
175.549 - ///
175.550 - /// Add a new edge undirected map writer command for the writer.
175.551 - template <typename Writer, typename Map>
175.552 - UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
175.553 - const Writer& writer = Writer()) {
175.554 - undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
175.555 - return *this;
175.556 - }
175.557 -
175.558 - /// \brief Add a new labeled node writer for the writer.
175.559 - ///
175.560 - /// Add a new labeled node writer for the writer.
175.561 - UndirGraphWriter& writeNode(std::string name, const Node& node) {
175.562 - node_writer.writeNode(name, node);
175.563 - return *this;
175.564 - }
175.565 -
175.566 - /// \brief Add a new labeled edge writer for the writer.
175.567 - ///
175.568 - /// Add a new labeled edge writer for the writer.
175.569 - UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
175.570 - undir_edge_writer.writeEdge(name, edge);
175.571 - }
175.572 -
175.573 - /// \brief Add a new labeled undirected edge writer for the writer.
175.574 - ///
175.575 - /// Add a new labeled undirected edge writer for the writer.
175.576 - UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
175.577 - undir_edge_writer.writeUndirEdge(name, edge);
175.578 - }
175.579 -
175.580 - /// \brief Add a new attribute writer command.
175.581 - ///
175.582 - /// Add a new attribute writer command.
175.583 - template <typename Value>
175.584 - UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
175.585 - attribute_writer.writeAttribute(name, value);
175.586 - return *this;
175.587 - }
175.588 -
175.589 - /// \brief Add a new attribute writer command.
175.590 - ///
175.591 - /// Add a new attribute writer command.
175.592 - template <typename Writer, typename Value>
175.593 - UndirGraphWriter& writeAttribute(std::string name, const Value& value,
175.594 - const Writer& writer) {
175.595 - attribute_writer.writeAttribute<Writer>(name, value, writer);
175.596 - return *this;
175.597 - }
175.598 -
175.599 - /// \brief Conversion operator to LemonWriter.
175.600 - ///
175.601 - /// Conversion operator to LemonWriter. It make possible
175.602 - /// to access the encapsulated \e LemonWriter, this way
175.603 - /// you can attach to this writer new instances of
175.604 - /// \e LemonWriter::SectionWriter.
175.605 - operator LemonWriter&() {
175.606 - return *writer;
175.607 - }
175.608 -
175.609 - /// \brief Executes the writer commands.
175.610 - ///
175.611 - /// Executes the writer commands.
175.612 - void run() {
175.613 - writer->run();
175.614 - }
175.615 -
175.616 - /// \brief Write the id of the given node.
175.617 - ///
175.618 - /// It writes the id of the given node. If there was written an "id"
175.619 - /// named node map then it will write the map value belongs to the node.
175.620 - void writeId(std::ostream& os, const Node& item) const {
175.621 - nodeset_writer.writeId(os, item);
175.622 - }
175.623 -
175.624 - /// \brief Write the id of the given edge.
175.625 - ///
175.626 - /// It writes the id of the given edge. If there was written an "id"
175.627 - /// named edge map then it will write the map value belongs to the edge.
175.628 - void writeId(std::ostream& os, const Edge& item) const {
175.629 - undir_edgeset_writer.writeId(os, item);
175.630 - }
175.631 -
175.632 - /// \brief Write the id of the given undirected edge.
175.633 - ///
175.634 - /// It writes the id of the given undirected edge. If there was written
175.635 - /// an "id" named edge map then it will write the map value belongs to
175.636 - /// the edge.
175.637 - void writeId(std::ostream& os, const UndirEdge& item) const {
175.638 - undir_edgeset_writer.writeId(os, item);
175.639 - }
175.640 -
175.641 -
175.642 - private:
175.643 -
175.644 - LemonWriter* writer;
175.645 - bool own_writer;
175.646 -
175.647 - NodeSetWriter<Graph, WriterTraits> nodeset_writer;
175.648 - UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
175.649 -
175.650 - NodeWriter<Graph> node_writer;
175.651 - UndirEdgeWriter<Graph> undir_edge_writer;
175.652 -
175.653 - AttributeWriter<WriterTraits> attribute_writer;
175.654 - };
175.655 -
175.656 -
175.657 - /// \brief Write an undirected graph to the output.
175.658 - ///
175.659 - /// Write an undirected graph to the output.
175.660 - /// \param os The output stream.
175.661 - /// \param g The graph.
175.662 - /// \param capacity The capacity undirected map.
175.663 - template<typename Graph, typename CapacityMap>
175.664 - void writeUndirGraph(std::ostream& os, const Graph &g,
175.665 - const CapacityMap& capacity) {
175.666 - UndirGraphWriter<Graph> writer(os, g);
175.667 - writer.writeUndirEdgeMap("capacity", capacity);
175.668 - writer.run();
175.669 - }
175.670 -
175.671 - /// \brief Write an undirected graph to the output.
175.672 - ///
175.673 - /// Write an undirected graph to the output.
175.674 - /// \param os The output stream.
175.675 - /// \param g The graph.
175.676 - template<typename Graph>
175.677 - void writeUndirGraph(std::ostream& os, const Graph &g) {
175.678 - UndirGraphWriter<Graph> writer(os, g);
175.679 - writer.run();
175.680 - }
175.681 -
175.682 - /// @}
175.683 -
175.684 -}
175.685 -
175.686 -#endif
176.1 --- a/src/lemon/invalid.h Sat May 21 21:04:57 2005 +0000
176.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
176.3 @@ -1,52 +0,0 @@
176.4 -/* -*- C++ -*-
176.5 - * src/lemon/invalid.h - Part of LEMON, a generic C++ optimization library
176.6 - *
176.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
176.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
176.9 - *
176.10 - * Permission to use, modify and distribute this software is granted
176.11 - * provided that this copyright notice appears in all copies. For
176.12 - * precise terms see the accompanying LICENSE file.
176.13 - *
176.14 - * This software is provided "AS IS" with no warranty of any kind,
176.15 - * express or implied, and with no claim as to its suitability for any
176.16 - * purpose.
176.17 - *
176.18 - */
176.19 -
176.20 -#ifndef LEMON_INVALID_H
176.21 -#define LEMON_INVALID_H
176.22 -
176.23 -///\file
176.24 -///\brief Definition of INVALID.
176.25 -
176.26 -namespace lemon {
176.27 -
176.28 - /// Dummy type to make it easier to make invalid iterators.
176.29 -
176.30 - /// See \ref INVALID, how to use it.
176.31 -
176.32 - struct Invalid {
176.33 - public:
176.34 - bool operator==(Invalid) { return true; }
176.35 - bool operator!=(Invalid) { return false; }
176.36 - bool operator< (Invalid) { return false; }
176.37 - };
176.38 -
176.39 - /// Invalid iterators.
176.40 -
176.41 - /// \ref Invalid is a global type that converts to each iterator
176.42 - /// in such a way that the value of the target iterator will be invalid.
176.43 -
176.44 - // It is also used to convert the \c INVALID constant to the
176.45 - // node iterator that makes is possible to write
176.46 -
176.47 - //extern Invalid INVALID;
176.48 -
176.49 - //const Invalid &INVALID = *(Invalid *)0;
176.50 - const Invalid INVALID = Invalid();
176.51 -
176.52 -} //namespace lemon
176.53 -
176.54 -#endif
176.55 -
177.1 --- a/src/lemon/kruskal.h Sat May 21 21:04:57 2005 +0000
177.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
177.3 @@ -1,348 +0,0 @@
177.4 -/* -*- C++ -*-
177.5 - * src/lemon/kruskal.h - Part of LEMON, a generic C++ optimization library
177.6 - *
177.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
177.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
177.9 - *
177.10 - * Permission to use, modify and distribute this software is granted
177.11 - * provided that this copyright notice appears in all copies. For
177.12 - * precise terms see the accompanying LICENSE file.
177.13 - *
177.14 - * This software is provided "AS IS" with no warranty of any kind,
177.15 - * express or implied, and with no claim as to its suitability for any
177.16 - * purpose.
177.17 - *
177.18 - */
177.19 -
177.20 -#ifndef LEMON_KRUSKAL_H
177.21 -#define LEMON_KRUSKAL_H
177.22 -
177.23 -#include <algorithm>
177.24 -#include <lemon/unionfind.h>
177.25 -
177.26 -/**
177.27 -@defgroup spantree Minimum Cost Spanning Tree Algorithms
177.28 -@ingroup galgs
177.29 -\brief This group containes the algorithms for finding a minimum cost spanning
177.30 -tree in a graph
177.31 -
177.32 -This group containes the algorithms for finding a minimum cost spanning
177.33 -tree in a graph
177.34 -*/
177.35 -
177.36 -///\ingroup spantree
177.37 -///\file
177.38 -///\brief Kruskal's algorithm to compute a minimum cost tree
177.39 -///
177.40 -///Kruskal's algorithm to compute a minimum cost tree.
177.41 -
177.42 -namespace lemon {
177.43 -
177.44 - /// \addtogroup spantree
177.45 - /// @{
177.46 -
177.47 - /// Kruskal's algorithm to find a minimum cost tree of a graph.
177.48 -
177.49 - /// This function runs Kruskal's algorithm to find a minimum cost tree.
177.50 - /// \param G The graph the algorithm runs on. The algorithm considers the
177.51 - /// graph to be undirected, the direction of the edges are not used.
177.52 - ///
177.53 - /// \param in This object is used to describe the edge costs. It must
177.54 - /// be an STL compatible 'Forward Container'
177.55 - /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>,
177.56 - /// where X is the type of the costs. It must contain every edge in
177.57 - /// cost-ascending order.
177.58 - ///\par
177.59 - /// For the sake of simplicity, there is a helper class KruskalMapInput,
177.60 - /// which converts a
177.61 - /// simple edge map to an input of this form. Alternatively, you can use
177.62 - /// the function \ref kruskalEdgeMap to compute the minimum cost tree if
177.63 - /// the edge costs are given by an edge map.
177.64 - ///
177.65 - /// \retval out This must be a writable \c bool edge map.
177.66 - /// After running the algorithm
177.67 - /// this will contain the found minimum cost spanning tree: the value of an
177.68 - /// edge will be set to \c true if it belongs to the tree, otherwise it will
177.69 - /// be set to \c false. The value of each edge will be set exactly once.
177.70 - ///
177.71 - /// \return The cost of the found tree.
177.72 -
177.73 - template <class GR, class IN, class OUT>
177.74 - typename IN::value_type::second_type
177.75 - kruskal(GR const& G, IN const& in,
177.76 - OUT& out)
177.77 - {
177.78 - typedef typename IN::value_type::second_type EdgeCost;
177.79 - typedef typename GR::template NodeMap<int> NodeIntMap;
177.80 - typedef typename GR::Node Node;
177.81 -
177.82 - NodeIntMap comp(G, -1);
177.83 - UnionFind<Node,NodeIntMap> uf(comp);
177.84 -
177.85 - EdgeCost tot_cost = 0;
177.86 - for (typename IN::const_iterator p = in.begin();
177.87 - p!=in.end(); ++p ) {
177.88 - if ( uf.join(G.target((*p).first),
177.89 - G.source((*p).first)) ) {
177.90 - out.set((*p).first, true);
177.91 - tot_cost += (*p).second;
177.92 - }
177.93 - else {
177.94 - out.set((*p).first, false);
177.95 - }
177.96 - }
177.97 - return tot_cost;
177.98 - }
177.99 -
177.100 - /* A work-around for running Kruskal with const-reference bool maps... */
177.101 -
177.102 - /// Helper class for calling kruskal with "constant" output map.
177.103 -
177.104 - /// Helper class for calling kruskal with output maps constructed
177.105 - /// on-the-fly.
177.106 - ///
177.107 - /// A typical examle is the following call:
177.108 - /// <tt>kruskal(G, some_input, makeSequenceOutput(iterator))</tt>.
177.109 - /// Here, the third argument is a temporary object (which wraps around an
177.110 - /// iterator with a writable bool map interface), and thus by rules of C++
177.111 - /// is a \c const object. To enable call like this exist this class and
177.112 - /// the prototype of the \ref kruskal() function with <tt>const& OUT</tt>
177.113 - /// third argument.
177.114 - template<class Map>
177.115 - class NonConstMapWr {
177.116 - const Map &m;
177.117 - public:
177.118 - typedef typename Map::Value Value;
177.119 -
177.120 - NonConstMapWr(const Map &_m) : m(_m) {}
177.121 -
177.122 - template<class Key>
177.123 - void set(Key const& k, Value const &v) const { m.set(k,v); }
177.124 - };
177.125 -
177.126 - template <class GR, class IN, class OUT>
177.127 - inline
177.128 - typename IN::value_type::second_type
177.129 - kruskal(GR const& G, IN const& edges, OUT const& out_map)
177.130 - {
177.131 - NonConstMapWr<OUT> map_wr(out_map);
177.132 - return kruskal(G, edges, map_wr);
177.133 - }
177.134 -
177.135 - /* ** ** Input-objects ** ** */
177.136 -
177.137 - /// Kruskal's input source.
177.138 -
177.139 - /// Kruskal's input source.
177.140 - ///
177.141 - /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead.
177.142 - ///
177.143 - /// \sa makeKruskalMapInput()
177.144 - ///
177.145 - ///\param GR The type of the graph the algorithm runs on.
177.146 - ///\param Map An edge map containing the cost of the edges.
177.147 - ///\par
177.148 - ///The cost type can be any type satisfying
177.149 - ///the STL 'LessThan comparable'
177.150 - ///concept if it also has an operator+() implemented. (It is necessary for
177.151 - ///computing the total cost of the tree).
177.152 - ///
177.153 - template<class GR, class Map>
177.154 - class KruskalMapInput
177.155 - : public std::vector< std::pair<typename GR::Edge,
177.156 - typename Map::Value> > {
177.157 -
177.158 - public:
177.159 - typedef std::vector< std::pair<typename GR::Edge,
177.160 - typename Map::Value> > Parent;
177.161 - typedef typename Parent::value_type value_type;
177.162 -
177.163 - private:
177.164 - class comparePair {
177.165 - public:
177.166 - bool operator()(const value_type& a,
177.167 - const value_type& b) {
177.168 - return a.second < b.second;
177.169 - }
177.170 - };
177.171 -
177.172 - public:
177.173 -
177.174 - void sort() {
177.175 - std::sort(this->begin(), this->end(), comparePair());
177.176 - }
177.177 -
177.178 - KruskalMapInput(GR const& G, Map const& m) {
177.179 - typedef typename GR::EdgeIt EdgeIt;
177.180 -
177.181 - for(EdgeIt e(G);e!=INVALID;++e) push_back(value_type(e, m[e]));
177.182 - sort();
177.183 - }
177.184 - };
177.185 -
177.186 - /// Creates a KruskalMapInput object for \ref kruskal()
177.187 -
177.188 - /// It makes easier to use
177.189 - /// \ref KruskalMapInput by making it unnecessary
177.190 - /// to explicitly give the type of the parameters.
177.191 - ///
177.192 - /// In most cases you possibly
177.193 - /// want to use the function kruskalEdgeMap() instead.
177.194 - ///
177.195 - ///\param G The type of the graph the algorithm runs on.
177.196 - ///\param m An edge map containing the cost of the edges.
177.197 - ///\par
177.198 - ///The cost type can be any type satisfying the
177.199 - ///STL 'LessThan Comparable'
177.200 - ///concept if it also has an operator+() implemented. (It is necessary for
177.201 - ///computing the total cost of the tree).
177.202 - ///
177.203 - ///\return An appropriate input source for \ref kruskal().
177.204 - ///
177.205 - template<class GR, class Map>
177.206 - inline
177.207 - KruskalMapInput<GR,Map> makeKruskalMapInput(const GR &G,const Map &m)
177.208 - {
177.209 - return KruskalMapInput<GR,Map>(G,m);
177.210 - }
177.211 -
177.212 -
177.213 -
177.214 - /* ** ** Output-objects: simple writable bool maps ** ** */
177.215 -
177.216 -
177.217 -
177.218 - /// A writable bool-map that makes a sequence of "true" keys
177.219 -
177.220 - /// A writable bool-map that creates a sequence out of keys that receives
177.221 - /// the value "true".
177.222 - ///
177.223 - /// \sa makeKruskalSequenceOutput()
177.224 - ///
177.225 - /// Very often, when looking for a min cost spanning tree, we want as
177.226 - /// output a container containing the edges of the found tree. For this
177.227 - /// purpose exist this class that wraps around an STL iterator with a
177.228 - /// writable bool map interface. When a key gets value "true" this key
177.229 - /// is added to sequence pointed by the iterator.
177.230 - ///
177.231 - /// A typical usage:
177.232 - /// \code
177.233 - /// std::vector<Graph::Edge> v;
177.234 - /// kruskal(g, input, makeKruskalSequenceOutput(back_inserter(v)));
177.235 - /// \endcode
177.236 - ///
177.237 - /// For the most common case, when the input is given by a simple edge
177.238 - /// map and the output is a sequence of the tree edges, a special
177.239 - /// wrapper function exists: \ref kruskalEdgeMap_IteratorOut().
177.240 - ///
177.241 - /// \warning Not a regular property map, as it doesn't know its Key
177.242 -
177.243 - template<class Iterator>
177.244 - class KruskalSequenceOutput {
177.245 - mutable Iterator it;
177.246 -
177.247 - public:
177.248 - typedef bool Value;
177.249 -
177.250 - KruskalSequenceOutput(Iterator const &_it) : it(_it) {}
177.251 -
177.252 - template<typename Key>
177.253 - void set(Key const& k, bool v) const { if(v) {*it=k; ++it;} }
177.254 - };
177.255 -
177.256 - template<class Iterator>
177.257 - inline
177.258 - KruskalSequenceOutput<Iterator>
177.259 - makeKruskalSequenceOutput(Iterator it) {
177.260 - return KruskalSequenceOutput<Iterator>(it);
177.261 - }
177.262 -
177.263 -
177.264 -
177.265 - /* ** ** Wrapper funtions ** ** */
177.266 -
177.267 -
177.268 -
177.269 - /// \brief Wrapper function to kruskal().
177.270 - /// Input is from an edge map, output is a plain bool map.
177.271 - ///
177.272 - /// Wrapper function to kruskal().
177.273 - /// Input is from an edge map, output is a plain bool map.
177.274 - ///
177.275 - ///\param G The type of the graph the algorithm runs on.
177.276 - ///\param in An edge map containing the cost of the edges.
177.277 - ///\par
177.278 - ///The cost type can be any type satisfying the
177.279 - ///STL 'LessThan Comparable'
177.280 - ///concept if it also has an operator+() implemented. (It is necessary for
177.281 - ///computing the total cost of the tree).
177.282 - ///
177.283 - /// \retval out This must be a writable \c bool edge map.
177.284 - /// After running the algorithm
177.285 - /// this will contain the found minimum cost spanning tree: the value of an
177.286 - /// edge will be set to \c true if it belongs to the tree, otherwise it will
177.287 - /// be set to \c false. The value of each edge will be set exactly once.
177.288 - ///
177.289 - /// \return The cost of the found tree.
177.290 -
177.291 - template <class GR, class IN, class RET>
177.292 - inline
177.293 - typename IN::Value
177.294 - kruskalEdgeMap(GR const& G,
177.295 - IN const& in,
177.296 - RET &out) {
177.297 - return kruskal(G,
177.298 - KruskalMapInput<GR,IN>(G,in),
177.299 - out);
177.300 - }
177.301 -
177.302 - /// \brief Wrapper function to kruskal().
177.303 - /// Input is from an edge map, output is an STL Sequence.
177.304 - ///
177.305 - /// Wrapper function to kruskal().
177.306 - /// Input is from an edge map, output is an STL Sequence.
177.307 - ///
177.308 - ///\param G The type of the graph the algorithm runs on.
177.309 - ///\param in An edge map containing the cost of the edges.
177.310 - ///\par
177.311 - ///The cost type can be any type satisfying the
177.312 - ///STL 'LessThan Comparable'
177.313 - ///concept if it also has an operator+() implemented. (It is necessary for
177.314 - ///computing the total cost of the tree).
177.315 - ///
177.316 - /// \retval out This must be an iteraror of an STL Container with
177.317 - /// <tt>GR::Edge</tt> as its <tt>value_type</tt>.
177.318 - /// The algorithm copies the elements of the found tree into this sequence.
177.319 - /// For example, if we know that the spanning tree of the graph \c G has
177.320 - /// say 53 edges then
177.321 - /// we can put its edges into a STL vector \c tree with a code like this.
177.322 - /// \code
177.323 - /// std::vector<Edge> tree(53);
177.324 - /// kruskalEdgeMap_IteratorOut(G,cost,tree.begin());
177.325 - /// \endcode
177.326 - /// Or if we don't know in advance the size of the tree, we can write this.
177.327 - /// \code
177.328 - /// std::vector<Edge> tree;
177.329 - /// kruskalEdgeMap_IteratorOut(G,cost,std::back_inserter(tree));
177.330 - /// \endcode
177.331 - ///
177.332 - /// \return The cost of the found tree.
177.333 - ///
177.334 - /// \bug its name does not follow the coding style.
177.335 -
177.336 - template <class GR, class IN, class RET>
177.337 - inline
177.338 - typename IN::Value
177.339 - kruskalEdgeMap_IteratorOut(const GR& G,
177.340 - const IN& in,
177.341 - RET out)
177.342 - {
177.343 - KruskalSequenceOutput<RET> _out(out);
177.344 - return kruskal(G, KruskalMapInput<GR,IN>(G, in), _out);
177.345 - }
177.346 -
177.347 - /// @}
177.348 -
177.349 -} //namespace lemon
177.350 -
177.351 -#endif //LEMON_KRUSKAL_H
178.1 --- a/src/lemon/lemon.pc.in Sat May 21 21:04:57 2005 +0000
178.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
178.3 @@ -1,10 +0,0 @@
178.4 -prefix=@prefix@
178.5 -exec_prefix=@exec_prefix@
178.6 -libdir=@libdir@
178.7 -includedir=@includedir@
178.8 -
178.9 -Name: @PACKAGE_NAME@
178.10 -Description: a Library of Efficient Models and Optimization in Networks
178.11 -Version: @PACKAGE_VERSION@
178.12 -Libs: -L${libdir} -lemon
178.13 -Cflags: -I${includedir}
179.1 --- a/src/lemon/lemon_reader.h Sat May 21 21:04:57 2005 +0000
179.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
179.3 @@ -1,1977 +0,0 @@
179.4 -/* -*- C++ -*-
179.5 - * src/lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
179.6 - *
179.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
179.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
179.9 - *
179.10 - * Permission to use, modify and distribute this software is granted
179.11 - * provided that this copyright notice appears in all copies. For
179.12 - * precise terms see the accompanying LICENSE file.
179.13 - *
179.14 - * This software is provided "AS IS" with no warranty of any kind,
179.15 - * express or implied, and with no claim as to its suitability for any
179.16 - * purpose.
179.17 - *
179.18 - */
179.19 -
179.20 -///\ingroup io_group
179.21 -///\file
179.22 -///\brief Lemon Format reader.
179.23 -
179.24 -
179.25 -#ifndef LEMON_LEMON_READER_H
179.26 -#define LEMON_LEMON_READER_H
179.27 -
179.28 -
179.29 -#include <iostream>
179.30 -#include <fstream>
179.31 -#include <string>
179.32 -#include <vector>
179.33 -#include <algorithm>
179.34 -#include <map>
179.35 -#include <memory>
179.36 -
179.37 -#include <lemon/error.h>
179.38 -#include <lemon/graph_utils.h>
179.39 -#include <lemon/utility.h>
179.40 -#include <lemon/bits/item_reader.h>
179.41 -
179.42 -
179.43 -namespace lemon {
179.44 -
179.45 - namespace _reader_bits {
179.46 -
179.47 - template <typename T>
179.48 - bool operator<(T, T) {
179.49 - throw DataFormatError("Id is not comparable");
179.50 - }
179.51 -
179.52 - template <typename T>
179.53 - struct Less {
179.54 - bool operator()(const T& p, const T& q) const {
179.55 - return p < q;
179.56 - }
179.57 - };
179.58 -
179.59 - template <typename M1, typename M2>
179.60 - class WriteComposeMap {
179.61 - public:
179.62 - typedef True NeedCopy;
179.63 -
179.64 - typedef typename M2::Key Key;
179.65 - typedef typename M1::Value Value;
179.66 -
179.67 - WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2)
179.68 - : m1(_m1), m2(_m2) {}
179.69 -
179.70 - void set(const Key& key, const Value& value) {
179.71 - m1.set(m2[key], value);
179.72 - }
179.73 -
179.74 - private:
179.75 -
179.76 - typename SmartReference<M1>::Type m1;
179.77 - typename SmartConstReference<M2>::Type m2;
179.78 -
179.79 - };
179.80 -
179.81 - template <typename M1, typename M2>
179.82 - WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
179.83 - return WriteComposeMap<M1, M2>(m1, m2);
179.84 - }
179.85 -
179.86 - template <typename M1, typename M2>
179.87 - WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
179.88 - return WriteComposeMap<M1, M2>(m1, m2);
179.89 - }
179.90 -
179.91 - }
179.92 -
179.93 - /// \ingroup io_group
179.94 - /// \brief Lemon Format reader class.
179.95 - ///
179.96 - /// The Lemon Format contains several sections. We do not want to
179.97 - /// determine what sections are in a lemon file we give only a framework
179.98 - /// to read a section oriented format.
179.99 - ///
179.100 - /// In the Lemon Format each section starts with a line contains a \c \@
179.101 - /// character on the first not white space position. This line is the
179.102 - /// header line of the section. Each next lines belong to this section
179.103 - /// while it does not starts with \c \@ character. This line can start a
179.104 - /// new section or if it can close the file with the \c \@end line.
179.105 - /// The file format ignore the empty and comment lines. The line is
179.106 - /// comment line if it starts with a \c # character.
179.107 - ///
179.108 - /// The framework provides an abstract LemonReader::SectionReader class
179.109 - /// what defines the interface of a SectionReader. The SectionReader
179.110 - /// has the \c header() member function what get a header line string and
179.111 - /// decides if it want to process the next section. Several SectionReaders
179.112 - /// can be attached to an LemonReader and the first attached what can
179.113 - /// process the section will be used. Its \c read() member will called
179.114 - /// with a stream contains the section. From this stream the empty and
179.115 - /// comment lines are filtered out.
179.116 - ///
179.117 - /// \relates GraphReader
179.118 - /// \relates NodeSetReader
179.119 - /// \relates EdgeSetReader
179.120 - /// \relates NodesReader
179.121 - /// \relates EdgesReader
179.122 - /// \relates AttributeReader
179.123 - class LemonReader {
179.124 - private:
179.125 -
179.126 - class FilterStreamBuf : public std::streambuf {
179.127 - public:
179.128 -
179.129 - typedef std::streambuf Parent;
179.130 - typedef Parent::char_type char_type;
179.131 - FilterStreamBuf(std::istream& is, int& num)
179.132 - : _is(is), _base(0), _eptr(0),
179.133 - _num(num), skip_state(after_endl) {}
179.134 -
179.135 - protected:
179.136 -
179.137 - enum skip_state_type {
179.138 - no_skip,
179.139 - after_endl,
179.140 - comment_line
179.141 - };
179.142 -
179.143 - char_type small_buf[1];
179.144 -
179.145 -
179.146 - std::istream& _is;
179.147 -
179.148 - char_type* _base;
179.149 - char_type* _eptr;
179.150 -
179.151 - int& _num;
179.152 -
179.153 - skip_state_type skip_state;
179.154 -
179.155 -
179.156 - char_type* base() { return _base; }
179.157 -
179.158 - char_type* eptr() { return _eptr; }
179.159 -
179.160 - int blen() { return _eptr - _base; }
179.161 -
179.162 - void setb(char_type* buf, int len) {
179.163 - _base = buf;
179.164 - _eptr = buf + len;
179.165 - }
179.166 -
179.167 - virtual std::streambuf* setbuf(char *buf, int len) {
179.168 - if (base()) return 0;
179.169 - if (buf != 0 && len >= (int)sizeof(small_buf)) {
179.170 - setb(buf, len);
179.171 - } else {
179.172 - setb(small_buf, sizeof(small_buf));
179.173 - }
179.174 - setg(0, 0, 0);
179.175 - return this;
179.176 - }
179.177 -
179.178 - bool put_char(char c) {
179.179 - switch (skip_state) {
179.180 - case no_skip:
179.181 - switch (c) {
179.182 - case '\n':
179.183 - skip_state = after_endl;
179.184 - return true;
179.185 - default:
179.186 - return true;
179.187 - }
179.188 - case after_endl:
179.189 - switch (c) {
179.190 - case '@':
179.191 - return false;
179.192 - case '\n':
179.193 - return false;
179.194 - case '#':
179.195 - skip_state = comment_line;
179.196 - return false;
179.197 - default:
179.198 - if (!isspace(c)) {
179.199 - skip_state = no_skip;
179.200 - return true;
179.201 - } else {
179.202 - return false;
179.203 - }
179.204 - }
179.205 - break;
179.206 - case comment_line:
179.207 - switch (c) {
179.208 - case '\n':
179.209 - skip_state = after_endl;
179.210 - return false;
179.211 - default:
179.212 - return false;
179.213 - }
179.214 - }
179.215 - return false;
179.216 - }
179.217 -
179.218 - virtual int underflow() {
179.219 - char c;
179.220 - if (_is.read(&c, 1)) {
179.221 - _is.putback(c);
179.222 - if (c == '@') {
179.223 - return EOF;
179.224 - }
179.225 - } else {
179.226 - return EOF;
179.227 - }
179.228 - char_type *ptr;
179.229 - for (ptr = base(); ptr != eptr(); ++ptr) {
179.230 - if (_is.read(&c, 1)) {
179.231 - if (c == '\n') ++_num;
179.232 - if (put_char(c)) {
179.233 - *ptr = c;
179.234 - } else {
179.235 - if (skip_state == after_endl && c == '@') {
179.236 - _is.putback('@');
179.237 - break;
179.238 - }
179.239 - --ptr;
179.240 - }
179.241 - } else {
179.242 - break;
179.243 - }
179.244 - }
179.245 - setg(base(), base(), ptr);
179.246 - return *base();
179.247 - }
179.248 -
179.249 - virtual int sync() {
179.250 - return EOF;
179.251 - }
179.252 - };
179.253 -
179.254 - public:
179.255 -
179.256 - /// \brief Abstract base class for reading a section.
179.257 - ///
179.258 - /// This class has an \c header() member function what get a
179.259 - /// header line string and decides if it want to process the next
179.260 - /// section. Several SectionReaders can be attached to an LemonReader
179.261 - /// and the first attached what can process the section will be used.
179.262 - /// Its \c read() member will called with a stream contains the section.
179.263 - /// From this stream the empty lines and comments are filtered out.
179.264 - class SectionReader {
179.265 - friend class LemonReader;
179.266 - protected:
179.267 - /// \brief Constructor for SectionReader.
179.268 - ///
179.269 - /// Constructor for SectionReader. It attach this reader to
179.270 - /// the given LemonReader.
179.271 - SectionReader(LemonReader& reader) {
179.272 - reader.attach(*this);
179.273 - }
179.274 -
179.275 - /// \brief Gives back true when the SectionReader can process
179.276 - /// the section with the given header line.
179.277 - ///
179.278 - /// It gives back true when the SectionReader can process
179.279 - /// the section with the given header line.
179.280 - virtual bool header(const std::string& line) = 0;
179.281 -
179.282 - /// \brief Reader function of the section.
179.283 - ///
179.284 - /// It reads the content of the section.
179.285 - virtual void read(std::istream& is) = 0;
179.286 - };
179.287 -
179.288 - /// \brief Constructor for LemonReader.
179.289 - ///
179.290 - /// Constructor for LemonReader which reads from the given stream.
179.291 - LemonReader(std::istream& _is)
179.292 - : is(&_is), own_is(false) {}
179.293 -
179.294 - /// \brief Constructor for LemonReader.
179.295 - ///
179.296 - /// Constructor for LemonReader which reads from the given file.
179.297 - LemonReader(const std::string& filename)
179.298 - : is(0), own_is(true) {
179.299 - is = new std::ifstream(filename.c_str());
179.300 - }
179.301 -
179.302 - /// \brief Desctructor for LemonReader.
179.303 - ///
179.304 - /// Desctructor for LemonReader.
179.305 - ~LemonReader() {
179.306 - if (own_is) {
179.307 - delete is;
179.308 - }
179.309 - }
179.310 -
179.311 - private:
179.312 - LemonReader(const LemonReader&);
179.313 - void operator=(const LemonReader&);
179.314 -
179.315 - void attach(SectionReader& reader) {
179.316 - readers.push_back(&reader);
179.317 - }
179.318 -
179.319 - public:
179.320 - /// \brief Executes the LemonReader.
179.321 - ///
179.322 - /// It executes the LemonReader.
179.323 - void run() {
179.324 - int line_num = 0;
179.325 - std::string line;
179.326 - try {
179.327 - while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
179.328 - SectionReaders::iterator it;
179.329 - for (it = readers.begin(); it != readers.end(); ++it) {
179.330 - if ((*it)->header(line)) {
179.331 - char buf[2048];
179.332 - FilterStreamBuf buffer(*is, line_num);
179.333 - buffer.pubsetbuf(buf, sizeof(buf));
179.334 - std::istream is(&buffer);
179.335 - (*it)->read(is);
179.336 - break;
179.337 - }
179.338 - }
179.339 - }
179.340 - } catch (DataFormatError& error) {
179.341 - error.line(line_num);
179.342 - throw error;
179.343 - }
179.344 - }
179.345 -
179.346 -
179.347 - private:
179.348 -
179.349 - std::istream* is;
179.350 - bool own_is;
179.351 -
179.352 - typedef std::vector<SectionReader*> SectionReaders;
179.353 - SectionReaders readers;
179.354 -
179.355 - };
179.356 -
179.357 - /// \brief Helper class for implementing the common SectionReaders.
179.358 - ///
179.359 - /// Helper class for implementing the common SectionReaders.
179.360 - class CommonSectionReaderBase : public LemonReader::SectionReader {
179.361 - typedef LemonReader::SectionReader Parent;
179.362 - protected:
179.363 -
179.364 - /// \brief Constructor for CommonSectionReaderBase.
179.365 - ///
179.366 - /// Constructor for CommonSectionReaderBase. It attach this reader to
179.367 - /// the given LemonReader.
179.368 - CommonSectionReaderBase(LemonReader& _reader)
179.369 - : Parent(_reader) {}
179.370 -
179.371 - template <typename _Item>
179.372 - class ReaderBase;
179.373 -
179.374 - template <typename _Item>
179.375 - class InverterBase : public ReaderBase<_Item> {
179.376 - public:
179.377 - typedef _Item Item;
179.378 - virtual void read(std::istream&, const Item&) = 0;
179.379 - virtual Item read(std::istream&) const = 0;
179.380 -
179.381 - virtual InverterBase<_Item>* getInverter() {
179.382 - return this;
179.383 - }
179.384 - };
179.385 -
179.386 - template <typename _Item, typename _Map, typename _Reader>
179.387 - class MapReaderInverter : public InverterBase<_Item> {
179.388 - public:
179.389 - typedef _Item Item;
179.390 - typedef _Reader Reader;
179.391 - typedef typename Reader::Value Value;
179.392 - typedef _Map Map;
179.393 - typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
179.394 -
179.395 - typename SmartReference<Map>::Type map;
179.396 - Reader reader;
179.397 - Inverse inverse;
179.398 -
179.399 - MapReaderInverter(typename SmartParameter<Map>::Type _map,
179.400 - const Reader& _reader)
179.401 - : map(_map), reader(_reader) {}
179.402 -
179.403 - virtual ~MapReaderInverter() {}
179.404 -
179.405 - virtual void read(std::istream& is, const Item& item) {
179.406 - Value value;
179.407 - reader.read(is, value);
179.408 - map.set(item, value);
179.409 - typename Inverse::iterator it = inverse.find(value);
179.410 - if (it == inverse.end()) {
179.411 - inverse.insert(std::make_pair(value, item));
179.412 - } else {
179.413 - throw DataFormatError("Multiple ID occurence");
179.414 - }
179.415 - }
179.416 -
179.417 - virtual Item read(std::istream& is) const {
179.418 - Value value;
179.419 - reader.read(is, value);
179.420 - typename Inverse::const_iterator it = inverse.find(value);
179.421 - if (it != inverse.end()) {
179.422 - return it->second;
179.423 - } else {
179.424 - throw DataFormatError("Invalid ID error");
179.425 - }
179.426 - }
179.427 - };
179.428 -
179.429 - template <typename _Item, typename _Reader>
179.430 - class SkipReaderInverter : public InverterBase<_Item> {
179.431 - public:
179.432 - typedef _Item Item;
179.433 - typedef _Reader Reader;
179.434 - typedef typename Reader::Value Value;
179.435 - typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
179.436 -
179.437 - Reader reader;
179.438 -
179.439 - SkipReaderInverter(const Reader& _reader)
179.440 - : reader(_reader) {}
179.441 -
179.442 - virtual ~SkipReaderInverter() {}
179.443 -
179.444 - virtual void read(std::istream& is, const Item& item) {
179.445 - Value value;
179.446 - reader.read(is, value);
179.447 - typename Inverse::iterator it = inverse.find(value);
179.448 - if (it == inverse.end()) {
179.449 - inverse.insert(std::make_pair(value, item));
179.450 - } else {
179.451 - throw DataFormatError("Multiple ID occurence error");
179.452 - }
179.453 - }
179.454 -
179.455 - virtual Item read(std::istream& is) const {
179.456 - Value value;
179.457 - reader.read(is, value);
179.458 - typename Inverse::const_iterator it = inverse.find(value);
179.459 - if (it != inverse.end()) {
179.460 - return it->second;
179.461 - } else {
179.462 - throw DataFormatError("Invalid ID error");
179.463 - }
179.464 - }
179.465 -
179.466 - private:
179.467 - Inverse inverse;
179.468 - };
179.469 -
179.470 - template <typename _Item>
179.471 - class ReaderBase {
179.472 - public:
179.473 - typedef _Item Item;
179.474 -
179.475 - virtual ~ReaderBase() {}
179.476 -
179.477 - virtual void read(std::istream& is, const Item& item) = 0;
179.478 - virtual InverterBase<_Item>* getInverter() = 0;
179.479 - };
179.480 -
179.481 - template <typename _Item, typename _Map, typename _Reader>
179.482 - class MapReader : public ReaderBase<_Item> {
179.483 - public:
179.484 - typedef _Map Map;
179.485 - typedef _Reader Reader;
179.486 - typedef typename Reader::Value Value;
179.487 - typedef _Item Item;
179.488 -
179.489 - typename SmartReference<Map>::Type map;
179.490 - Reader reader;
179.491 -
179.492 - MapReader(typename SmartParameter<Map>::Type _map,
179.493 - const Reader& _reader)
179.494 - : map(_map), reader(_reader) {}
179.495 -
179.496 - virtual ~MapReader() {}
179.497 -
179.498 - virtual void read(std::istream& is, const Item& item) {
179.499 - Value value;
179.500 - reader.read(is, value);
179.501 - map.set(item, value);
179.502 - }
179.503 -
179.504 - virtual InverterBase<_Item>* getInverter() {
179.505 - return new MapReaderInverter<Item, Map, Reader>(map, reader);
179.506 - }
179.507 - };
179.508 -
179.509 -
179.510 - template <typename _Item, typename _Reader>
179.511 - class SkipReader : public ReaderBase<_Item> {
179.512 - public:
179.513 - typedef _Reader Reader;
179.514 - typedef typename Reader::Value Value;
179.515 - typedef _Item Item;
179.516 -
179.517 - Reader reader;
179.518 - SkipReader(const Reader& _reader) : reader(_reader) {}
179.519 -
179.520 - virtual ~SkipReader() {}
179.521 -
179.522 - virtual void read(std::istream& is, const Item&) {
179.523 - Value value;
179.524 - reader.read(is, value);
179.525 - }
179.526 -
179.527 - virtual InverterBase<Item>* getInverter() {
179.528 - return new SkipReaderInverter<Item, Reader>(reader);
179.529 - }
179.530 - };
179.531 -
179.532 - template <typename _Item>
179.533 - class IdReaderBase {
179.534 - public:
179.535 - typedef _Item Item;
179.536 - virtual Item read(std::istream& is) const = 0;
179.537 - };
179.538 -
179.539 - template <typename _Item, typename _BoxedIdReader>
179.540 - class IdReader : public IdReaderBase<_Item> {
179.541 - public:
179.542 - typedef _Item Item;
179.543 - typedef _BoxedIdReader BoxedIdReader;
179.544 -
179.545 - const BoxedIdReader& boxedIdReader;
179.546 -
179.547 - IdReader(const BoxedIdReader& _boxedIdReader)
179.548 - : boxedIdReader(_boxedIdReader) {}
179.549 -
179.550 - virtual Item read(std::istream& is) const {
179.551 - return boxedIdReader.readId(is, Item());
179.552 - }
179.553 - };
179.554 -
179.555 - class ValueReaderBase {
179.556 - public:
179.557 - virtual void read(std::istream&) {};
179.558 - };
179.559 -
179.560 - template <typename _Value, typename _Reader>
179.561 - class ValueReader : public ValueReaderBase {
179.562 - public:
179.563 - typedef _Value Value;
179.564 - typedef _Reader Reader;
179.565 -
179.566 - ValueReader(Value& _value, const Reader& _reader)
179.567 - : value(_value), reader(_reader) {}
179.568 -
179.569 - virtual void read(std::istream& is) {
179.570 - reader.read(is, value);
179.571 - }
179.572 - private:
179.573 - Value& value;
179.574 - Reader reader;
179.575 - };
179.576 -
179.577 - };
179.578 -
179.579 - /// \ingroup io_group
179.580 - /// \brief SectionReader for reading a graph's nodeset.
179.581 - ///
179.582 - /// The lemon format can store multiple graph nodesets with several maps.
179.583 - /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
179.584 - /// \c nodeset_id may be empty.
179.585 - ///
179.586 - /// The first line of the section contains the names of the maps separated
179.587 - /// with white spaces. Each next lines describes a node in the nodeset, and
179.588 - /// contains the mapped values for each map.
179.589 - ///
179.590 - /// If the nodeset contains an \c "id" named map then it will be regarded
179.591 - /// as id map. This map should contain only unique values and when the
179.592 - /// \c readId() member will read a value from the given stream it will
179.593 - /// give back that node which is mapped to this value.
179.594 - ///
179.595 - /// \relates LemonReader
179.596 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
179.597 - class NodeSetReader : public CommonSectionReaderBase {
179.598 - typedef CommonSectionReaderBase Parent;
179.599 - public:
179.600 -
179.601 - typedef _Graph Graph;
179.602 - typedef _Traits Traits;
179.603 - typedef typename Graph::Node Node;
179.604 - typedef typename Traits::Skipper DefaultSkipper;
179.605 -
179.606 - /// \brief Constructor.
179.607 - ///
179.608 - /// Constructor for NodeSetReader. It creates the NodeSetReader and
179.609 - /// attach it into the given LemonReader. The nodeset reader will
179.610 - /// add the readed nodes to the given Graph. The reader will read
179.611 - /// the section when the \c section_id and the \c _id are the same.
179.612 - NodeSetReader(LemonReader& _reader,
179.613 - typename SmartParameter<Graph>::Type _graph,
179.614 - const std::string& _id = std::string(),
179.615 - const DefaultSkipper& _skipper = DefaultSkipper())
179.616 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {}
179.617 -
179.618 -
179.619 - /// \brief Destructor.
179.620 - ///
179.621 - /// Destructor for NodeSetReader.
179.622 - virtual ~NodeSetReader() {
179.623 - for (typename MapReaders::iterator it = readers.begin();
179.624 - it != readers.end(); ++it) {
179.625 - delete it->second;
179.626 - }
179.627 - }
179.628 -
179.629 - private:
179.630 - NodeSetReader(const NodeSetReader&);
179.631 - void operator=(const NodeSetReader&);
179.632 -
179.633 - public:
179.634 -
179.635 - /// \brief Add a new node map reader command for the reader.
179.636 - ///
179.637 - /// Add a new node map reader command for the reader.
179.638 - template <typename Map>
179.639 - NodeSetReader& readNodeMap(std::string name, Map& map) {
179.640 - return _readMap<
179.641 - typename Traits::template Reader<typename Map::Value>, Map,
179.642 - typename SmartParameter<Map>::Type>(name, map);
179.643 - }
179.644 -
179.645 - template <typename Map>
179.646 - NodeSetReader& readNodeMap(std::string name, const Map& map) {
179.647 - return _readMap<
179.648 - typename Traits::template Reader<typename Map::Value>, Map,
179.649 - typename SmartParameter<Map>::Type>(name, map);
179.650 - }
179.651 -
179.652 - /// \brief Add a new node map reader command for the reader.
179.653 - ///
179.654 - /// Add a new node map reader command for the reader.
179.655 - template <typename Reader, typename Map>
179.656 - NodeSetReader& readNodeMap(std::string name, Map& map,
179.657 - const Reader& reader = Reader()) {
179.658 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
179.659 - (name, map, reader);
179.660 - }
179.661 -
179.662 - template <typename Reader, typename Map>
179.663 - NodeSetReader& readNodeMap(std::string name, const Map& map,
179.664 - const Reader& reader = Reader()) {
179.665 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
179.666 - (name, map, reader);
179.667 - }
179.668 -
179.669 - private:
179.670 -
179.671 - template <typename Reader, typename Map, typename MapParameter>
179.672 - NodeSetReader& _readMap(std::string name, MapParameter map,
179.673 - const Reader& reader = Reader()) {
179.674 - if (readers.find(name) != readers.end()) {
179.675 - ErrorMessage msg;
179.676 - msg << "Multiple read rule for node map: " << name;
179.677 - throw IOParameterError(msg.message());
179.678 - }
179.679 - readers.insert(
179.680 - make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
179.681 - return *this;
179.682 - }
179.683 -
179.684 - public:
179.685 -
179.686 - /// \brief Add a new node map skipper command for the reader.
179.687 - ///
179.688 - /// Add a new node map skipper command for the reader.
179.689 - template <typename Reader>
179.690 - NodeSetReader& skipNodeMap(std::string name,
179.691 - const Reader& reader = Reader()) {
179.692 - if (readers.find(name) != readers.end()) {
179.693 - ErrorMessage msg;
179.694 - msg << "Multiple read rule for node map: " << name;
179.695 - throw IOParameterError(msg.message());
179.696 - }
179.697 - readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
179.698 - return *this;
179.699 - }
179.700 -
179.701 - protected:
179.702 -
179.703 - /// \brief Gives back true when the SectionReader can process
179.704 - /// the section with the given header line.
179.705 - ///
179.706 - /// It gives back true when the header line starts with \c \@nodeset,
179.707 - /// and the header line's id and the nodeset's id are the same.
179.708 - virtual bool header(const std::string& line) {
179.709 - std::istringstream ls(line);
179.710 - std::string command;
179.711 - std::string name;
179.712 - ls >> command >> name;
179.713 - return command == "@nodeset" && name == id;
179.714 - }
179.715 -
179.716 - /// \brief Reader function of the section.
179.717 - ///
179.718 - /// It reads the content of the section.
179.719 - virtual void read(std::istream& is) {
179.720 - std::vector<ReaderBase<Node>* > index;
179.721 - std::string line;
179.722 -
179.723 - getline(is, line);
179.724 - std::istringstream ls(line);
179.725 - while (ls >> id) {
179.726 - typename MapReaders::iterator it = readers.find(id);
179.727 - if (it != readers.end()) {
179.728 - index.push_back(it->second);
179.729 - } else {
179.730 - index.push_back(&skipper);
179.731 - }
179.732 - if (id == "id" && inverter.get() == 0) {
179.733 - inverter.reset(index.back()->getInverter());
179.734 - index.back() = inverter.get();
179.735 - }
179.736 - }
179.737 - while (getline(is, line)) {
179.738 - Node node = graph.addNode();
179.739 - std::istringstream ls(line);
179.740 - for (int i = 0; i < (int)index.size(); ++i) {
179.741 - index[i]->read(ls, node);
179.742 - }
179.743 - }
179.744 - }
179.745 -
179.746 - public:
179.747 -
179.748 - /// \brief Returns true if the nodeset can give back the node by its id.
179.749 - ///
179.750 - /// Returns true if the nodeset can give back the node by its id.
179.751 - /// It is possible only if an "id" named map was read.
179.752 - bool isIdReader() const {
179.753 - return inverter.get() != 0;
179.754 - }
179.755 -
179.756 - /// \brief Gives back the node by its id.
179.757 - ///
179.758 - /// It reads an id from the stream and gives back which node belongs to
179.759 - /// it. It is possible only if there was read an "id" named map.
179.760 - Node readId(std::istream& is, Node = Node()) const {
179.761 - return inverter->read(is);
179.762 - }
179.763 -
179.764 - private:
179.765 -
179.766 - typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
179.767 - MapReaders readers;
179.768 -
179.769 - typename SmartReference<Graph>::Type graph;
179.770 - std::string id;
179.771 - SkipReader<Node, DefaultSkipper> skipper;
179.772 -
179.773 - std::auto_ptr<InverterBase<Node> > inverter;
179.774 - };
179.775 -
179.776 - /// \ingroup io_group
179.777 - /// \brief SectionReader for reading a graph's edgeset.
179.778 - ///
179.779 - /// The lemon format can store multiple graph edgesets with several maps.
179.780 - /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
179.781 - /// \c edgeset_id may be empty.
179.782 - ///
179.783 - /// The first line of the section contains the names of the maps separated
179.784 - /// with white spaces. Each next lines describes an edge in the edgeset. The
179.785 - /// line contains the source and the target nodes' id and the mapped
179.786 - /// values for each map.
179.787 - ///
179.788 - /// If the edgeset contains an \c "id" named map then it will be regarded
179.789 - /// as id map. This map should contain only unique values and when the
179.790 - /// \c readId() member will read a value from the given stream it will
179.791 - /// give back that edge which is mapped to this value.
179.792 - ///
179.793 - /// The edgeset reader needs a node id reader to identify which nodes
179.794 - /// have to be connected. If a NodeSetReader reads an "id" named map,
179.795 - /// it will be able to resolve the nodes by ids.
179.796 - ///
179.797 - /// \relates LemonReader
179.798 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
179.799 - class EdgeSetReader : public CommonSectionReaderBase {
179.800 - typedef CommonSectionReaderBase Parent;
179.801 - public:
179.802 -
179.803 - typedef _Graph Graph;
179.804 - typedef _Traits Traits;
179.805 - typedef typename Graph::Node Node;
179.806 - typedef typename Graph::Edge Edge;
179.807 - typedef typename Traits::Skipper DefaultSkipper;
179.808 -
179.809 - /// \brief Constructor.
179.810 - ///
179.811 - /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
179.812 - /// attach it into the given LemonReader. The edgeset reader will
179.813 - /// add the readed edges to the given Graph. It will use the given
179.814 - /// node id reader to read the source and target nodes of the edges.
179.815 - /// The reader will read the section only if the \c _id and the
179.816 - /// \c edgset_id are the same.
179.817 - template <typename NodeIdReader>
179.818 - EdgeSetReader(LemonReader& _reader,
179.819 - typename SmartParameter<Graph>::Type _graph,
179.820 - const NodeIdReader& _nodeIdReader,
179.821 - const std::string& _id = std::string(),
179.822 - const DefaultSkipper& _skipper = DefaultSkipper())
179.823 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
179.824 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
179.825 -
179.826 - /// \brief Destructor.
179.827 - ///
179.828 - /// Destructor for EdgeSetReader.
179.829 - virtual ~EdgeSetReader() {
179.830 - for (typename MapReaders::iterator it = readers.begin();
179.831 - it != readers.end(); ++it) {
179.832 - delete it->second;
179.833 - }
179.834 - }
179.835 -
179.836 - private:
179.837 - EdgeSetReader(const EdgeSetReader&);
179.838 - void operator=(const EdgeSetReader&);
179.839 -
179.840 - public:
179.841 -
179.842 - /// \brief Add a new edge map reader command for the reader.
179.843 - ///
179.844 - /// Add a new edge map reader command for the reader.
179.845 - template <typename Map>
179.846 - EdgeSetReader& readEdgeMap(std::string name, Map& map) {
179.847 - return _readMap<
179.848 - typename Traits::template Reader<typename Map::Value>, Map,
179.849 - typename SmartParameter<Map>::Type>(name, map);
179.850 - }
179.851 -
179.852 - template <typename Map>
179.853 - EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
179.854 - return _readMap<
179.855 - typename Traits::template Reader<typename Map::Value>, Map,
179.856 - typename SmartParameter<Map>::Type>(name, map);
179.857 - }
179.858 -
179.859 - /// \brief Add a new edge map reader command for the reader.
179.860 - ///
179.861 - /// Add a new edge map reader command for the reader.
179.862 - template <typename Reader, typename Map>
179.863 - EdgeSetReader& readEdgeMap(std::string name, Map& map,
179.864 - const Reader& reader = Reader()) {
179.865 - return _readMap<Reader, Map,
179.866 - typename SmartParameter<Map>::Type>(name, map, reader);
179.867 - }
179.868 -
179.869 - template <typename Reader, typename Map>
179.870 - EdgeSetReader& readEdgeMap(std::string name, const Map& map,
179.871 - const Reader& reader = Reader()) {
179.872 - return _readMap<Reader, Map,
179.873 - typename SmartParameter<Map>::Type>(name, map, reader);
179.874 - }
179.875 -
179.876 - private:
179.877 -
179.878 - template <typename Reader, typename Map, typename MapParameter>
179.879 - EdgeSetReader& _readMap(std::string name, MapParameter map,
179.880 - const Reader& reader = Reader()) {
179.881 - if (readers.find(name) != readers.end()) {
179.882 - ErrorMessage msg;
179.883 - msg << "Multiple read rule for edge map: " << name;
179.884 - throw IOParameterError(msg.message());
179.885 - }
179.886 - readers.insert(
179.887 - make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
179.888 - return *this;
179.889 - }
179.890 -
179.891 - public:
179.892 -
179.893 - /// \brief Add a new edge map skipper command for the reader.
179.894 - ///
179.895 - /// Add a new edge map skipper command for the reader.
179.896 - template <typename Reader>
179.897 - EdgeSetReader& skipEdgeMap(std::string name,
179.898 - const Reader& reader = Reader()) {
179.899 - if (readers.find(name) != readers.end()) {
179.900 - ErrorMessage msg;
179.901 - msg << "Multiple read rule for edge map: " << name;
179.902 - throw IOParameterError(msg.message());
179.903 - }
179.904 - readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
179.905 - return *this;
179.906 - }
179.907 -
179.908 - protected:
179.909 -
179.910 - /// \brief Gives back true when the SectionReader can process
179.911 - /// the section with the given header line.
179.912 - ///
179.913 - /// It gives back true when the header line starts with \c \@edgeset,
179.914 - /// and the header line's id and the edgeset's id are the same.
179.915 - virtual bool header(const std::string& line) {
179.916 - std::istringstream ls(line);
179.917 - std::string command;
179.918 - std::string name;
179.919 - ls >> command >> name;
179.920 - return command == "@edgeset" && name == id;
179.921 - }
179.922 -
179.923 - /// \brief Reader function of the section.
179.924 - ///
179.925 - /// It reads the content of the section.
179.926 - virtual void read(std::istream& is) {
179.927 - std::vector<ReaderBase<Edge>* > index;
179.928 - std::string line;
179.929 -
179.930 - getline(is, line);
179.931 - std::istringstream ls(line);
179.932 - while (ls >> id) {
179.933 - typename MapReaders::iterator it = readers.find(id);
179.934 - if (it != readers.end()) {
179.935 - index.push_back(it->second);
179.936 - } else {
179.937 - index.push_back(&skipper);
179.938 - }
179.939 - if (id == "id" && inverter.get() == 0) {
179.940 - inverter.reset(index.back()->getInverter());
179.941 - index.back() = inverter.get();
179.942 - }
179.943 - }
179.944 - while (getline(is, line)) {
179.945 - std::istringstream ls(line);
179.946 - Node from = nodeIdReader->read(ls);
179.947 - Node to = nodeIdReader->read(ls);
179.948 - Edge edge = graph.addEdge(from, to);
179.949 - for (int i = 0; i < (int)index.size(); ++i) {
179.950 - index[i]->read(ls, edge);
179.951 - }
179.952 - }
179.953 - }
179.954 -
179.955 - public:
179.956 -
179.957 - /// \brief Returns true if the edgeset can give back the edge by its id.
179.958 - ///
179.959 - /// Returns true if the edgeset can give back the edge by its id.
179.960 - /// It is possible only if an "id" named map was read.
179.961 - bool isIdReader() const {
179.962 - return inverter.get() != 0;
179.963 - }
179.964 -
179.965 - /// \brief Gives back the edge by its id.
179.966 - ///
179.967 - /// It reads an id from the stream and gives back which edge belongs to
179.968 - /// it. It is possible only if there was read an "id" named map.
179.969 - Edge readId(std::istream& is, Edge = Edge()) const {
179.970 - return inverter->read(is);
179.971 - }
179.972 -
179.973 - private:
179.974 -
179.975 - typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
179.976 - MapReaders readers;
179.977 -
179.978 - typename SmartReference<Graph>::Type graph;
179.979 - std::string id;
179.980 - SkipReader<Edge, DefaultSkipper> skipper;
179.981 -
179.982 - std::auto_ptr<InverterBase<Edge> > inverter;
179.983 - std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
179.984 - };
179.985 -
179.986 - /// \ingroup io_group
179.987 - /// \brief SectionReader for reading a undirected graph's edgeset.
179.988 - ///
179.989 - /// The lemon format can store multiple undirected edgesets with several
179.990 - /// maps. The undirected edgeset section's header line is \c \@undiredgeset
179.991 - /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
179.992 - ///
179.993 - /// The first line of the section contains the names of the maps separated
179.994 - /// with white spaces. Each next lines describes an edge in the edgeset. The
179.995 - /// line contains the connected nodes' id and the mapped values for each map.
179.996 - ///
179.997 - /// The section can handle the directed as a syntactical sugar. Two
179.998 - /// undirected edge map describes one directed edge map. This two maps
179.999 - /// are the forward map and the backward map and the names of this map
179.1000 - /// is near the same just with a prefix \c '+' or \c '-' character
179.1001 - /// difference.
179.1002 - ///
179.1003 - /// If the edgeset contains an \c "id" named map then it will be regarded
179.1004 - /// as id map. This map should contain only unique values and when the
179.1005 - /// \c readId() member will read a value from the given stream it will
179.1006 - /// give back that undiricted edge which is mapped to this value.
179.1007 - ///
179.1008 - /// The undirected edgeset reader needs a node id reader to identify which
179.1009 - /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
179.1010 - /// it will be able to resolve the nodes by ids.
179.1011 - ///
179.1012 - /// \relates LemonReader
179.1013 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
179.1014 - class UndirEdgeSetReader : public CommonSectionReaderBase {
179.1015 - typedef CommonSectionReaderBase Parent;
179.1016 - public:
179.1017 -
179.1018 - typedef _Graph Graph;
179.1019 - typedef _Traits Traits;
179.1020 - typedef typename Graph::Node Node;
179.1021 - typedef typename Graph::Edge Edge;
179.1022 - typedef typename Graph::UndirEdge UndirEdge;
179.1023 - typedef typename Traits::Skipper DefaultSkipper;
179.1024 -
179.1025 - /// \brief Constructor.
179.1026 - ///
179.1027 - /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader
179.1028 - /// and attach it into the given LemonReader. The undirected edgeset
179.1029 - /// reader will add the readed undirected edges to the given Graph. It
179.1030 - /// will use the given node id reader to read the source and target
179.1031 - /// nodes of the edges. The reader will read the section only if the
179.1032 - /// \c _id and the \c undiredgset_id are the same.
179.1033 - template <typename NodeIdReader>
179.1034 - UndirEdgeSetReader(LemonReader& _reader,
179.1035 - typename SmartParameter<Graph>::Type _graph,
179.1036 - const NodeIdReader& _nodeIdReader,
179.1037 - const std::string& _id = std::string(),
179.1038 - const DefaultSkipper& _skipper = DefaultSkipper())
179.1039 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
179.1040 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
179.1041 -
179.1042 - /// \brief Destructor.
179.1043 - ///
179.1044 - /// Destructor for UndirEdgeSetReader.
179.1045 - virtual ~UndirEdgeSetReader() {
179.1046 - for (typename MapReaders::iterator it = readers.begin();
179.1047 - it != readers.end(); ++it) {
179.1048 - delete it->second;
179.1049 - }
179.1050 - }
179.1051 -
179.1052 - private:
179.1053 - UndirEdgeSetReader(const UndirEdgeSetReader&);
179.1054 - void operator=(const UndirEdgeSetReader&);
179.1055 -
179.1056 - public:
179.1057 -
179.1058 - /// \brief Add a new undirected edge map reader command for the reader.
179.1059 - ///
179.1060 - /// Add a new edge undirected map reader command for the reader.
179.1061 - template <typename Map>
179.1062 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
179.1063 - return _readMap<
179.1064 - typename Traits::template Reader<typename Map::Value>, Map,
179.1065 - typename SmartParameter<Map>::Type>(name, map);
179.1066 - }
179.1067 -
179.1068 - template <typename Map>
179.1069 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
179.1070 - return _readMap<
179.1071 - typename Traits::template Reader<typename Map::Value>, Map,
179.1072 - typename SmartParameter<Map>::Type>(name, map);
179.1073 - }
179.1074 -
179.1075 - /// \brief Add a new undirected edge map reader command for the reader.
179.1076 - ///
179.1077 - /// Add a new edge undirected map reader command for the reader.
179.1078 - template <typename Reader, typename Map>
179.1079 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map,
179.1080 - const Reader& reader = Reader()) {
179.1081 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
179.1082 - (name, map, reader);
179.1083 - }
179.1084 -
179.1085 - template <typename Reader, typename Map>
179.1086 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map,
179.1087 - const Reader& reader = Reader()) {
179.1088 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
179.1089 - (name, map, reader);
179.1090 - }
179.1091 -
179.1092 - private:
179.1093 -
179.1094 - template <typename Reader, typename Map, typename MapParameter>
179.1095 - UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
179.1096 - const Reader& reader = Reader()) {
179.1097 - if (readers.find(name) != readers.end()) {
179.1098 - ErrorMessage msg;
179.1099 - msg << "Multiple read rule for edge map: " << name;
179.1100 - throw IOParameterError(msg.message());
179.1101 - }
179.1102 - readers.insert(
179.1103 - make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
179.1104 - return *this;
179.1105 - }
179.1106 -
179.1107 - public:
179.1108 -
179.1109 - /// \brief Add a new undirected edge map skipper command for the reader.
179.1110 - ///
179.1111 - /// Add a new undirected edge map skipper command for the reader.
179.1112 - template <typename Reader>
179.1113 - UndirEdgeSetReader& skipUndirEdgeMap(std::string name,
179.1114 - const Reader& reader = Reader()) {
179.1115 - if (readers.find(name) != readers.end()) {
179.1116 - ErrorMessage msg;
179.1117 - msg << "Multiple read rule for node map: " << name;
179.1118 - throw IOParameterError(msg.message());
179.1119 - }
179.1120 - readers.insert(make_pair(name,
179.1121 - new SkipReader<UndirEdge, Reader>(reader)));
179.1122 - return *this;
179.1123 - }
179.1124 -
179.1125 - /// \brief Add a new directed edge map reader command for the reader.
179.1126 - ///
179.1127 - /// Add a new directed edge map reader command for the reader.
179.1128 - template <typename Map>
179.1129 - UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
179.1130 - return _readDirMap<
179.1131 - typename Traits::template Reader<typename Map::Value>, Map,
179.1132 - typename SmartParameter<Map>::Type>(name, map);
179.1133 - }
179.1134 -
179.1135 - template <typename Map>
179.1136 - UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
179.1137 - return _readDirMap<
179.1138 - typename Traits::template Reader<typename Map::Value>, Map,
179.1139 - typename SmartParameter<Map>::Type>(name, map);
179.1140 - }
179.1141 -
179.1142 - /// \brief Add a new directed edge map reader command for the reader.
179.1143 - ///
179.1144 - /// Add a new directed edge map reader command for the reader.
179.1145 - template <typename Reader, typename Map>
179.1146 - UndirEdgeSetReader& readEdgeMap(std::string name, Map& map,
179.1147 - const Reader& reader = Reader()) {
179.1148 - return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
179.1149 - (name, map, reader);
179.1150 - }
179.1151 -
179.1152 - template <typename Reader, typename Map>
179.1153 - UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map,
179.1154 - const Reader& reader = Reader()) {
179.1155 - return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
179.1156 - (name, map, reader);
179.1157 - }
179.1158 -
179.1159 - private:
179.1160 -
179.1161 - template <typename Reader, typename Map, typename MapParameter>
179.1162 - UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
179.1163 - const Reader& reader = Reader()) {
179.1164 - readMap("+" + name,
179.1165 - _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
179.1166 - readMap("-" + name,
179.1167 - _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
179.1168 - return *this;
179.1169 - }
179.1170 -
179.1171 - public:
179.1172 -
179.1173 - /// \brief Add a new directed edge map skipper command for the reader.
179.1174 - ///
179.1175 - /// Add a new directed edge map skipper command for the reader.
179.1176 - template <typename Reader>
179.1177 - UndirEdgeSetReader& skipEdgeMap(std::string name,
179.1178 - const Reader& reader = Reader()) {
179.1179 - skipMap("+" + name, reader);
179.1180 - skipMap("-" + name, reader);
179.1181 - return *this;
179.1182 - }
179.1183 -
179.1184 - protected:
179.1185 -
179.1186 - /// \brief Gives back true when the SectionReader can process
179.1187 - /// the section with the given header line.
179.1188 - ///
179.1189 - /// It gives back true when the header line starts with \c \@undiredgeset,
179.1190 - /// and the header line's id and the edgeset's id are the same.
179.1191 - virtual bool header(const std::string& line) {
179.1192 - std::istringstream ls(line);
179.1193 - std::string command;
179.1194 - std::string name;
179.1195 - ls >> command >> name;
179.1196 - return command == "@undiredgeset" && name == id;
179.1197 - }
179.1198 -
179.1199 - /// \brief Reader function of the section.
179.1200 - ///
179.1201 - /// It reads the content of the section.
179.1202 - virtual void read(std::istream& is) {
179.1203 - std::vector<ReaderBase<UndirEdge>* > index;
179.1204 - std::string line;
179.1205 -
179.1206 - getline(is, line);
179.1207 - std::istringstream ls(line);
179.1208 - while (ls >> id) {
179.1209 - typename MapReaders::iterator it = readers.find(id);
179.1210 - if (it != readers.end()) {
179.1211 - index.push_back(it->second);
179.1212 - } else {
179.1213 - index.push_back(&skipper);
179.1214 - }
179.1215 - if (id == "id" && inverter.get() == 0) {
179.1216 - inverter.reset(index.back()->getInverter());
179.1217 - index.back() = inverter.get();
179.1218 - }
179.1219 - }
179.1220 - while (getline(is, line)) {
179.1221 - std::istringstream ls(line);
179.1222 - Node from = nodeIdReader->read(ls);
179.1223 - Node to = nodeIdReader->read(ls);
179.1224 - UndirEdge edge = graph.addEdge(from, to);
179.1225 - for (int i = 0; i < (int)index.size(); ++i) {
179.1226 - index[i]->read(ls, edge);
179.1227 - }
179.1228 - }
179.1229 - }
179.1230 -
179.1231 - public:
179.1232 -
179.1233 - /// \brief Returns true if the edgeset can give back the edge by its id.
179.1234 - ///
179.1235 - /// Returns true if the edgeset can give back the undirected edge by its
179.1236 - /// id. It is possible only if an "id" named map was read.
179.1237 - bool isIdReader() const {
179.1238 - return inverter.get() != 0;
179.1239 - }
179.1240 -
179.1241 - /// \brief Gives back the undirected edge by its id.
179.1242 - ///
179.1243 - /// It reads an id from the stream and gives back which undirected edge
179.1244 - /// belongs to it. It is possible only if there was read an "id" named map.
179.1245 - UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const {
179.1246 - return inverter->read(is);
179.1247 - }
179.1248 -
179.1249 - /// \brief Gives back the directed edge by its id.
179.1250 - ///
179.1251 - /// It reads an id from the stream and gives back which directed edge
179.1252 - /// belongs to it. The directed edge id is the \c '+' or \c '-' character
179.1253 - /// and the undirected edge id. It is possible only if there was read
179.1254 - /// an "id" named map.
179.1255 - Edge readId(std::istream& is, Edge = Edge()) const {
179.1256 - char c;
179.1257 - is >> c;
179.1258 - UndirEdge undirEdge = inverter->read(is);
179.1259 - if (c == '+') {
179.1260 - return graph.edgeWithSource(undirEdge, graph.source(undirEdge));
179.1261 - } else if (c == '-') {
179.1262 - return graph.edgeWithSource(undirEdge, graph.target(undirEdge));
179.1263 - } else {
179.1264 - throw DataFormatError("Wrong id format for edge "
179.1265 - "in undirected edgeset");
179.1266 - }
179.1267 - }
179.1268 -
179.1269 - private:
179.1270 -
179.1271 - typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
179.1272 - MapReaders readers;
179.1273 -
179.1274 - typename SmartReference<Graph>::Type graph;
179.1275 - std::string id;
179.1276 - SkipReader<UndirEdge, DefaultSkipper> skipper;
179.1277 -
179.1278 - std::auto_ptr<InverterBase<UndirEdge> > inverter;
179.1279 - std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
179.1280 - };
179.1281 -
179.1282 - /// \ingroup io_group
179.1283 - /// \brief SectionReader for reading labeled nodes.
179.1284 - ///
179.1285 - /// The nodes section's header line is \c \@nodes \c nodes_id, but the
179.1286 - /// \c nodes_id may be empty.
179.1287 - ///
179.1288 - /// Each line in the section contains the name of the node
179.1289 - /// and then the node id.
179.1290 - ///
179.1291 - /// \relates LemonReader
179.1292 - template <typename _Graph>
179.1293 - class NodeReader : public CommonSectionReaderBase {
179.1294 - typedef CommonSectionReaderBase Parent;
179.1295 - typedef _Graph Graph;
179.1296 - typedef typename Graph::Node Node;
179.1297 - public:
179.1298 -
179.1299 - /// \brief Constructor.
179.1300 - ///
179.1301 - /// Constructor for NodeReader. It creates the NodeReader and
179.1302 - /// attach it into the given LemonReader. It will use the given
179.1303 - /// node id reader to give back the nodes. The reader will read the
179.1304 - /// section only if the \c _id and the \c nodes_id are the same.
179.1305 - template <typename _IdReader>
179.1306 - NodeReader(LemonReader& _reader, const _IdReader& _idReader,
179.1307 - const std::string& _id = std::string())
179.1308 - : Parent(_reader), id(_id),
179.1309 - idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {}
179.1310 -
179.1311 - /// \brief Destructor.
179.1312 - ///
179.1313 - /// Destructor for NodeReader.
179.1314 - virtual ~NodeReader() {}
179.1315 -
179.1316 - private:
179.1317 - NodeReader(const NodeReader&);
179.1318 - void operator=(const NodeReader&);
179.1319 -
179.1320 - public:
179.1321 -
179.1322 - /// \brief Add a node reader command for the NodeReader.
179.1323 - ///
179.1324 - /// Add a node reader command for the NodeReader.
179.1325 - void readNode(const std::string& name, Node& item) {
179.1326 - if (readers.find(name) != readers.end()) {
179.1327 - ErrorMessage msg;
179.1328 - msg << "Multiple read rule for node: " << name;
179.1329 - throw IOParameterError(msg.message());
179.1330 - }
179.1331 - readers.insert(make_pair(name, &item));
179.1332 - }
179.1333 -
179.1334 - protected:
179.1335 -
179.1336 - /// \brief Gives back true when the SectionReader can process
179.1337 - /// the section with the given header line.
179.1338 - ///
179.1339 - /// It gives back true when the header line start with \c \@nodes,
179.1340 - /// and the header line's id and the reader's id are the same.
179.1341 - virtual bool header(const std::string& line) {
179.1342 - std::istringstream ls(line);
179.1343 - std::string command;
179.1344 - std::string name;
179.1345 - ls >> command >> name;
179.1346 - return command == "@nodes" && name == id;
179.1347 - }
179.1348 -
179.1349 - /// \brief Reader function of the section.
179.1350 - ///
179.1351 - /// It reads the content of the section.
179.1352 - virtual void read(std::istream& is) {
179.1353 - std::string line;
179.1354 - while (getline(is, line)) {
179.1355 - std::istringstream ls(line);
179.1356 - std::string id;
179.1357 - ls >> id;
179.1358 - typename NodeReaders::iterator it = readers.find(id);
179.1359 - if (it != readers.end()) {
179.1360 - *(it->second) = idReader->read(ls);
179.1361 - }
179.1362 - }
179.1363 - }
179.1364 -
179.1365 - private:
179.1366 -
179.1367 - std::string id;
179.1368 -
179.1369 - typedef std::map<std::string, Node*> NodeReaders;
179.1370 - NodeReaders readers;
179.1371 - std::auto_ptr<IdReaderBase<Node> > idReader;
179.1372 - };
179.1373 -
179.1374 - /// \ingroup io_group
179.1375 - /// \brief SectionReader for reading labeled edges.
179.1376 - ///
179.1377 - /// The edges section's header line is \c \@edges \c edges_id, but the
179.1378 - /// \c edges_id may be empty.
179.1379 - ///
179.1380 - /// Each line in the section contains the name of the edge
179.1381 - /// and then the edge id.
179.1382 - ///
179.1383 - /// \relates LemonReader
179.1384 - template <typename _Graph>
179.1385 - class EdgeReader : public CommonSectionReaderBase {
179.1386 - typedef CommonSectionReaderBase Parent;
179.1387 - typedef _Graph Graph;
179.1388 - typedef typename Graph::Edge Edge;
179.1389 - public:
179.1390 -
179.1391 - /// \brief Constructor.
179.1392 - ///
179.1393 - /// Constructor for EdgeReader. It creates the EdgeReader and
179.1394 - /// attach it into the given LemonReader. It will use the given
179.1395 - /// edge id reader to give back the edges. The reader will read the
179.1396 - /// section only if the \c _id and the \c edges_id are the same.
179.1397 - template <typename _IdReader>
179.1398 - EdgeReader(LemonReader& _reader, const _IdReader& _idReader,
179.1399 - const std::string& _id = std::string())
179.1400 - : Parent(_reader), id(_id),
179.1401 - idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {}
179.1402 -
179.1403 - /// \brief Destructor.
179.1404 - ///
179.1405 - /// Destructor for EdgeReader.
179.1406 - virtual ~EdgeReader() {}
179.1407 - private:
179.1408 - EdgeReader(const EdgeReader&);
179.1409 - void operator=(const EdgeReader&);
179.1410 -
179.1411 - public:
179.1412 -
179.1413 - /// \brief Add an edge reader command for the EdgeReader.
179.1414 - ///
179.1415 - /// Add an edge reader command for the EdgeReader.
179.1416 - void readEdge(const std::string& name, Edge& item) {
179.1417 - if (readers.find(name) != readers.end()) {
179.1418 - ErrorMessage msg;
179.1419 - msg << "Multiple read rule for edge: " << name;
179.1420 - throw IOParameterError(msg.message());
179.1421 - }
179.1422 - readers.insert(make_pair(name, &item));
179.1423 - }
179.1424 -
179.1425 - protected:
179.1426 -
179.1427 - /// \brief Gives back true when the SectionReader can process
179.1428 - /// the section with the given header line.
179.1429 - ///
179.1430 - /// It gives back true when the header line start with \c \@edges,
179.1431 - /// and the header line's id and the reader's id are the same.
179.1432 - virtual bool header(const std::string& line) {
179.1433 - std::istringstream ls(line);
179.1434 - std::string command;
179.1435 - std::string name;
179.1436 - ls >> command >> name;
179.1437 - return command == "@edges" && name == id;
179.1438 - }
179.1439 -
179.1440 - /// \brief Reader function of the section.
179.1441 - ///
179.1442 - /// It reads the content of the section.
179.1443 - virtual void read(std::istream& is) {
179.1444 - std::string line;
179.1445 - while (getline(is, line)) {
179.1446 - std::istringstream ls(line);
179.1447 - std::string id;
179.1448 - ls >> id;
179.1449 - typename EdgeReaders::iterator it = readers.find(id);
179.1450 - if (it != readers.end()) {
179.1451 - *(it->second) = idReader->read(ls);
179.1452 - }
179.1453 - }
179.1454 - }
179.1455 -
179.1456 - private:
179.1457 -
179.1458 - std::string id;
179.1459 -
179.1460 - typedef std::map<std::string, Edge*> EdgeReaders;
179.1461 - EdgeReaders readers;
179.1462 - std::auto_ptr<IdReaderBase<Edge> > idReader;
179.1463 - };
179.1464 -
179.1465 - /// \ingroup io_group
179.1466 - /// \brief SectionReader for reading labeled undirected edges.
179.1467 - ///
179.1468 - /// The undirected edges section's header line is \c \@undiredges
179.1469 - /// \c undiredges_id, but the \c undiredges_id may be empty.
179.1470 - ///
179.1471 - /// Each line in the section contains the name of the undirected edge
179.1472 - /// and then the undirected edge id.
179.1473 - ///
179.1474 - /// \relates LemonReader
179.1475 - template <typename _Graph>
179.1476 - class UndirEdgeReader : public CommonSectionReaderBase {
179.1477 - typedef CommonSectionReaderBase Parent;
179.1478 - typedef _Graph Graph;
179.1479 - typedef typename Graph::Edge Edge;
179.1480 - typedef typename Graph::UndirEdge UndirEdge;
179.1481 - public:
179.1482 -
179.1483 - /// \brief Constructor.
179.1484 - ///
179.1485 - /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
179.1486 - /// attach it into the given LemonReader. It will use the given
179.1487 - /// undirected edge id reader to give back the edges. The reader will
179.1488 - /// read the section only if the \c _id and the \c undiredges_id are
179.1489 - /// the same.
179.1490 - template <typename _IdReader>
179.1491 - UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader,
179.1492 - const std::string& _id = std::string())
179.1493 - : Parent(_reader), id(_id),
179.1494 - undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
179.1495 - edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
179.1496 - {}
179.1497 -
179.1498 - /// \brief Destructor.
179.1499 - ///
179.1500 - /// Destructor for UndirEdgeReader.
179.1501 - virtual ~UndirEdgeReader() {}
179.1502 - private:
179.1503 - UndirEdgeReader(const UndirEdgeReader&);
179.1504 - void operator=(const UndirEdgeReader&);
179.1505 -
179.1506 - public:
179.1507 -
179.1508 - /// \brief Add an undirected edge reader command for the UndirEdgeReader.
179.1509 - ///
179.1510 - /// Add an undirected edge reader command for the UndirEdgeReader.
179.1511 - void readUndirEdge(const std::string& name, UndirEdge& item) {
179.1512 - if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) {
179.1513 - ErrorMessage msg;
179.1514 - msg << "Multiple read rule for undirected edge: " << name;
179.1515 - throw IOParameterError(msg.message());
179.1516 - }
179.1517 - undirEdgeReaders.insert(make_pair(name, &item));
179.1518 - }
179.1519 -
179.1520 - /// \brief Add an edge reader command for the UndirEdgeReader.
179.1521 - ///
179.1522 - /// Add an edge reader command for the UndirEdgeReader.
179.1523 - void readEdge(const std::string& name, Edge& item) {
179.1524 - if (edgeReaders.find(name) != edgeReaders.end()) {
179.1525 - ErrorMessage msg;
179.1526 - msg << "Multiple read rule for edge: " << name;
179.1527 - throw IOParameterError(msg.message());
179.1528 - }
179.1529 - edgeReaders.insert(make_pair(name, &item));
179.1530 - }
179.1531 -
179.1532 - protected:
179.1533 -
179.1534 - /// \brief Gives back true when the SectionReader can process
179.1535 - /// the section with the given header line.
179.1536 - ///
179.1537 - /// It gives back true when the header line start with \c \@edges,
179.1538 - /// and the header line's id and the reader's id are the same.
179.1539 - virtual bool header(const std::string& line) {
179.1540 - std::istringstream ls(line);
179.1541 - std::string command;
179.1542 - std::string name;
179.1543 - ls >> command >> name;
179.1544 - return command == "@undiredges" && name == id;
179.1545 - }
179.1546 -
179.1547 - /// \brief Reader function of the section.
179.1548 - ///
179.1549 - /// It reads the content of the section.
179.1550 - virtual void read(std::istream& is) {
179.1551 - std::string line;
179.1552 - while (getline(is, line)) {
179.1553 - std::istringstream ls(line);
179.1554 - std::string id;
179.1555 - ls >> id;
179.1556 - {
179.1557 - typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
179.1558 - if (it != undirEdgeReaders.end()) {
179.1559 - *(it->second) = undirEdgeIdReader->read(ls);
179.1560 - break;
179.1561 - }
179.1562 - } {
179.1563 - typename EdgeReaders::iterator it = edgeReaders.find(id);
179.1564 - if (it != edgeReaders.end()) {
179.1565 - *(it->second) = edgeIdReader->read(ls);
179.1566 - break;
179.1567 - }
179.1568 - }
179.1569 - }
179.1570 - }
179.1571 -
179.1572 - private:
179.1573 -
179.1574 - std::string id;
179.1575 -
179.1576 - typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
179.1577 - UndirEdgeReaders undirEdgeReaders;
179.1578 - std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
179.1579 -
179.1580 - typedef std::map<std::string, Edge*> EdgeReaders;
179.1581 - EdgeReaders edgeReaders;
179.1582 - std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
179.1583 - };
179.1584 -
179.1585 - /// \ingroup io_group
179.1586 - /// \brief SectionReader for attributes.
179.1587 - ///
179.1588 - /// The lemon format can store multiple attribute set. Each set has
179.1589 - /// the header line \c \@attributes \c attributeset_id, but the
179.1590 - /// attributeset_id may be empty.
179.1591 - ///
179.1592 - /// The attributeset section contains several lines. Each of them starts
179.1593 - /// with an attribute and then a the value for the id.
179.1594 - ///
179.1595 - /// \relates LemonReader
179.1596 - template <typename _Traits = DefaultReaderTraits>
179.1597 - class AttributeReader : public CommonSectionReaderBase {
179.1598 - typedef CommonSectionReaderBase Parent;
179.1599 - typedef _Traits Traits;
179.1600 - public:
179.1601 - /// \brief Constructor.
179.1602 - ///
179.1603 - /// Constructor for AttributeReader. It creates the AttributeReader and
179.1604 - /// attach it into the given LemonReader. The reader process a section
179.1605 - /// only if the \c section_id and the \c _id are the same.
179.1606 - AttributeReader(LemonReader& _reader,
179.1607 - const std::string& _id = std::string())
179.1608 - : Parent(_reader), id(_id) {}
179.1609 -
179.1610 - /// \brief Destructor.
179.1611 - ///
179.1612 - /// Destructor for AttributeReader.
179.1613 - virtual ~AttributeReader() {
179.1614 - for (typename Readers::iterator it = readers.begin();
179.1615 - it != readers.end(); ++it) {
179.1616 - delete it->second;
179.1617 - }
179.1618 - }
179.1619 -
179.1620 - private:
179.1621 - AttributeReader(const AttributeReader&);
179.1622 - void operator=(AttributeReader&);
179.1623 -
179.1624 - public:
179.1625 - /// \brief Add an attribute reader command for the reader.
179.1626 - ///
179.1627 - /// Add an attribute reader command for the reader.
179.1628 - template <typename Value>
179.1629 - AttributeReader& readAttribute(const std::string& id, Value& value) {
179.1630 - return readAttribute<typename Traits::template Reader<Value> >
179.1631 - (id, value);
179.1632 - }
179.1633 -
179.1634 - /// \brief Add an attribute reader command for the reader.
179.1635 - ///
179.1636 - /// Add an attribute reader command for the reader.
179.1637 - template <typename Reader, typename Value>
179.1638 - AttributeReader& readAttribute(const std::string& name, Value& value,
179.1639 - const Reader& reader = Reader()) {
179.1640 - if (readers.find(name) != readers.end()) {
179.1641 - ErrorMessage msg;
179.1642 - msg << "Multiple read rule for attribute: " << name;
179.1643 - throw IOParameterError(msg.message());
179.1644 - }
179.1645 - readers.insert(make_pair(name, new ValueReader<Value, Reader>
179.1646 - (value, reader)));
179.1647 - return *this;
179.1648 - }
179.1649 -
179.1650 - protected:
179.1651 -
179.1652 - /// \brief Gives back true when the SectionReader can process
179.1653 - /// the section with the given header line.
179.1654 - ///
179.1655 - /// It gives back true when the header line start with \c \@attributes,
179.1656 - /// and the header line's id and the attributeset's id are the same.
179.1657 - bool header(const std::string& line) {
179.1658 - std::istringstream ls(line);
179.1659 - std::string command;
179.1660 - std::string name;
179.1661 - ls >> command >> name;
179.1662 - return command == "@attributes" && name == id;
179.1663 - }
179.1664 -
179.1665 - /// \brief Reader function of the section.
179.1666 - ///
179.1667 - /// It reads the content of the section.
179.1668 - void read(std::istream& is) {
179.1669 - std::string line;
179.1670 - while (getline(is, line)) {
179.1671 - std::istringstream ls(line);
179.1672 - std::string id;
179.1673 - ls >> id;
179.1674 - typename Readers::iterator it = readers.find(id);
179.1675 - if (it != readers.end()) {
179.1676 - it->second->read(ls);
179.1677 - }
179.1678 - }
179.1679 - }
179.1680 -
179.1681 - private:
179.1682 - std::string id;
179.1683 -
179.1684 - typedef std::map<std::string, ValueReaderBase*> Readers;
179.1685 - Readers readers;
179.1686 - };
179.1687 -
179.1688 - /// \ingroup io_group
179.1689 - /// \brief SectionReader for retrieve what is in the file.
179.1690 - ///
179.1691 - /// SectionReader for retrieve what is in the file. If you want
179.1692 - /// to know which sections, maps and items are in the file
179.1693 - /// use the next code:
179.1694 - /// \code
179.1695 - /// LemonReader reader("input.lgf");
179.1696 - /// ContentReader content(reader);
179.1697 - /// reader.run();
179.1698 - /// \endcode
179.1699 - class ContentReader : public LemonReader::SectionReader {
179.1700 - typedef LemonReader::SectionReader Parent;
179.1701 - public:
179.1702 - /// \brief Constructor.
179.1703 - ///
179.1704 - /// Constructor for
179.1705 - ContentReader(LemonReader& _reader) : Parent(_reader) {}
179.1706 -
179.1707 - /// \brief Desctructor.
179.1708 - ///
179.1709 - /// Desctructor.
179.1710 - virtual ~ContentReader() {}
179.1711 -
179.1712 - /// \brief Gives back how many nodesets are in the file.
179.1713 - ///
179.1714 - /// Gives back how many nodesets are in the file.
179.1715 - int nodeSetNum() const {
179.1716 - return nodesets.size();
179.1717 - }
179.1718 -
179.1719 - /// \brief Gives back the name of nodeset on the indiced position.
179.1720 - ///
179.1721 - /// Gives back the name of nodeset on the indiced position.
179.1722 - std::string nodeSetName(int index) const {
179.1723 - return nodesets[index].name;
179.1724 - }
179.1725 -
179.1726 - /// \brief Gives back the map names of nodeset on the indiced position.
179.1727 - ///
179.1728 - /// Gives back the map names of nodeset on the indiced position.
179.1729 - const std::vector<std::string>& nodeSetMaps(int index) const {
179.1730 - return nodesets[index].items;
179.1731 - }
179.1732 -
179.1733 - /// \brief Gives back how many edgesets are in the file.
179.1734 - ///
179.1735 - /// Gives back how many edgesets are in the file.
179.1736 - int edgeSetNum() const {
179.1737 - return edgesets.size();
179.1738 - }
179.1739 -
179.1740 - /// \brief Gives back the name of edgeset on the indiced position.
179.1741 - ///
179.1742 - /// Gives back the name of edgeset on the indiced position.
179.1743 - std::string edgeSetName(int index) const {
179.1744 - return edgesets[index].name;
179.1745 - }
179.1746 -
179.1747 - /// \brief Gives back the map names of edgeset on the indiced position.
179.1748 - ///
179.1749 - /// Gives back the map names of edgeset on the indiced position.
179.1750 - const std::vector<std::string>& edgeSetMaps(int index) const {
179.1751 - return edgesets[index].items;
179.1752 - }
179.1753 -
179.1754 - /// \brief Gives back how many undirected edgesets are in the file.
179.1755 - ///
179.1756 - /// Gives back how many undirected edgesets are in the file.
179.1757 - int undirEdgeSetNum() const {
179.1758 - return undiredgesets.size();
179.1759 - }
179.1760 -
179.1761 - /// \brief Gives back the name of undirected edgeset on the indiced
179.1762 - /// position.
179.1763 - ///
179.1764 - /// Gives back the name of undirected edgeset on the indiced position.
179.1765 - std::string undirEdgeSetName(int index) const {
179.1766 - return undiredgesets[index].name;
179.1767 - }
179.1768 -
179.1769 - /// \brief Gives back the map names of undirected edgeset on the indiced
179.1770 - /// position.
179.1771 - ///
179.1772 - /// Gives back the map names of undirected edgeset on the indiced position.
179.1773 - const std::vector<std::string>& undirEdgeSetMaps(int index) const {
179.1774 - return undiredgesets[index].items;
179.1775 - }
179.1776 -
179.1777 - /// \brief Gives back how many labeled nodes section are in the file.
179.1778 - ///
179.1779 - /// Gives back how many labeled nodes section are in the file.
179.1780 - int nodesNum() const {
179.1781 - return nodes.size();
179.1782 - }
179.1783 -
179.1784 - /// \brief Gives back the name of labeled nodes section on the indiced
179.1785 - /// position.
179.1786 - ///
179.1787 - /// Gives back the name of labeled nodes section on the indiced position.
179.1788 - std::string nodesName(int index) const {
179.1789 - return nodes[index].name;
179.1790 - }
179.1791 -
179.1792 - /// \brief Gives back the names of the labeled nodes in the indiced
179.1793 - /// section.
179.1794 - ///
179.1795 - /// Gives back the names of the labeled nodes in the indiced section.
179.1796 - const std::vector<std::string>& nodesItems(int index) const {
179.1797 - return nodes[index].items;
179.1798 - }
179.1799 -
179.1800 - /// \brief Gives back how many labeled edges section are in the file.
179.1801 - ///
179.1802 - /// Gives back how many labeled edges section are in the file.
179.1803 - int edgesNum() const {
179.1804 - return edges.size();
179.1805 - }
179.1806 -
179.1807 - /// \brief Gives back the name of labeled edges section on the indiced
179.1808 - /// position.
179.1809 - ///
179.1810 - /// Gives back the name of labeled edges section on the indiced position.
179.1811 - std::string edgesName(int index) const {
179.1812 - return edges[index].name;
179.1813 - }
179.1814 -
179.1815 - /// \brief Gives back the names of the labeled edges in the indiced
179.1816 - /// section.
179.1817 - ///
179.1818 - /// Gives back the names of the labeled edges in the indiced section.
179.1819 - const std::vector<std::string>& edgesItems(int index) const {
179.1820 - return edges[index].items;
179.1821 - }
179.1822 -
179.1823 - /// \brief Gives back how many labeled undirected edges section are
179.1824 - /// in the file.
179.1825 - ///
179.1826 - /// Gives back how many labeled undirected edges section are in the file.
179.1827 - int undirEdgesNum() const {
179.1828 - return undiredges.size();
179.1829 - }
179.1830 -
179.1831 - /// \brief Gives back the name of labeled undirected edges section
179.1832 - /// on the indiced position.
179.1833 - ///
179.1834 - /// Gives back the name of labeled undirected edges section on the
179.1835 - /// indiced position.
179.1836 - std::string undirEdgesName(int index) const {
179.1837 - return undiredges[index].name;
179.1838 - }
179.1839 -
179.1840 - /// \brief Gives back the names of the labeled undirected edges in
179.1841 - /// the indiced section.
179.1842 - ///
179.1843 - /// Gives back the names of the labeled undirected edges in the
179.1844 - /// indiced section.
179.1845 - const std::vector<std::string>& undirEdgesItems(int index) const {
179.1846 - return undiredges[index].items;
179.1847 - }
179.1848 -
179.1849 -
179.1850 - /// \brief Gives back how many attributes section are in the file.
179.1851 - ///
179.1852 - /// Gives back how many attributes section are in the file.
179.1853 - int attributesNum() const {
179.1854 - return attributes.size();
179.1855 - }
179.1856 -
179.1857 - /// \brief Gives back the name of attributes section on the indiced
179.1858 - /// position.
179.1859 - ///
179.1860 - /// Gives back the name of attributes section on the indiced position.
179.1861 - std::string attributesName(int index) const {
179.1862 - return attributes[index].name;
179.1863 - }
179.1864 -
179.1865 - /// \brief Gives back the names of the attributes in the indiced section.
179.1866 - ///
179.1867 - /// Gives back the names of the attributes in the indiced section.
179.1868 - const std::vector<std::string>& attributesItems(int index) const {
179.1869 - return attributes[index].items;
179.1870 - }
179.1871 -
179.1872 - const std::vector<std::string>& otherSections() const {
179.1873 - return sections;
179.1874 - }
179.1875 -
179.1876 - protected:
179.1877 -
179.1878 - /// \brief Gives back true when the SectionReader can process
179.1879 - /// the section with the given header line.
179.1880 - ///
179.1881 - /// It gives back true when the section is common section.
179.1882 - bool header(const std::string& line) {
179.1883 - std::istringstream ls(line);
179.1884 - std::string command, name;
179.1885 - ls >> command >> name;
179.1886 - if (command == "@nodeset") {
179.1887 - current = command;
179.1888 - nodesets.push_back(SectionInfo(name));
179.1889 - } else if (command == "@edgeset") {
179.1890 - current = command;
179.1891 - edgesets.push_back(SectionInfo(name));
179.1892 - } else if (command == "@undiredgeset") {
179.1893 - current = command;
179.1894 - undiredgesets.push_back(SectionInfo(name));
179.1895 - } else if (command == "@nodes") {
179.1896 - current = command;
179.1897 - nodes.push_back(SectionInfo(name));
179.1898 - } else if (command == "@edges") {
179.1899 - current = command;
179.1900 - edges.push_back(SectionInfo(name));
179.1901 - } else if (command == "@undiredges") {
179.1902 - current = command;
179.1903 - undiredges.push_back(SectionInfo(name));
179.1904 - } else if (command == "@attributes") {
179.1905 - current = command;
179.1906 - attributes.push_back(SectionInfo(name));
179.1907 - } else {
179.1908 - sections.push_back(line);
179.1909 - return false;
179.1910 - }
179.1911 - return true;
179.1912 - }
179.1913 -
179.1914 - /// \brief Retrieve the items from various sections.
179.1915 - ///
179.1916 - /// Retrieve the items from various sections.
179.1917 - void read(std::istream& is) {
179.1918 - if (current == "@nodeset") {
179.1919 - readMapNames(is, nodesets.back().items);
179.1920 - } else if (current == "@edgeset") {
179.1921 - readMapNames(is, edgesets.back().items);
179.1922 - } else if (current == "@undiredgeset") {
179.1923 - readMapNames(is, undiredgesets.back().items);
179.1924 - } else if (current == "@nodes") {
179.1925 - readItemNames(is, nodes.back().items);
179.1926 - } else if (current == "@edges") {
179.1927 - readItemNames(is, edges.back().items);
179.1928 - } else if (current == "@undiredges") {
179.1929 - readItemNames(is, undiredges.back().items);
179.1930 - } else if (current == "@attributes") {
179.1931 - readItemNames(is, attributes.back().items);
179.1932 - }
179.1933 - }
179.1934 -
179.1935 - private:
179.1936 -
179.1937 - void readMapNames(std::istream& is, std::vector<std::string>& maps) {
179.1938 - std::string line, id;
179.1939 - std::getline(is, line);
179.1940 - std::istringstream ls(line);
179.1941 - while (ls >> id) {
179.1942 - maps.push_back(id);
179.1943 - }
179.1944 - while (getline(is, line));
179.1945 - }
179.1946 -
179.1947 - void readItemNames(std::istream& is, std::vector<std::string>& maps) {
179.1948 - std::string line, id;
179.1949 - while (std::getline(is, line)) {
179.1950 - std::istringstream ls(line);
179.1951 - ls >> id;
179.1952 - maps.push_back(id);
179.1953 - }
179.1954 - }
179.1955 -
179.1956 - struct SectionInfo {
179.1957 - std::string name;
179.1958 - std::vector<std::string> items;
179.1959 -
179.1960 - SectionInfo(const std::string& _name) : name(_name) {}
179.1961 - };
179.1962 -
179.1963 - std::vector<SectionInfo> nodesets;
179.1964 - std::vector<SectionInfo> edgesets;
179.1965 - std::vector<SectionInfo> undiredgesets;
179.1966 -
179.1967 - std::vector<SectionInfo> nodes;
179.1968 - std::vector<SectionInfo> edges;
179.1969 - std::vector<SectionInfo> undiredges;
179.1970 -
179.1971 - std::vector<SectionInfo> attributes;
179.1972 -
179.1973 - std::vector<std::string> sections;
179.1974 -
179.1975 - std::string current;
179.1976 -
179.1977 - };
179.1978 -
179.1979 -}
179.1980 -#endif
180.1 --- a/src/lemon/lemon_writer.h Sat May 21 21:04:57 2005 +0000
180.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
180.3 @@ -1,1129 +0,0 @@
180.4 -/* -*- C++ -*-
180.5 - * src/lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
180.6 - *
180.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
180.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
180.9 - *
180.10 - * Permission to use, modify and distribute this software is granted
180.11 - * provided that this copyright notice appears in all copies. For
180.12 - * precise terms see the accompanying LICENSE file.
180.13 - *
180.14 - * This software is provided "AS IS" with no warranty of any kind,
180.15 - * express or implied, and with no claim as to its suitability for any
180.16 - * purpose.
180.17 - *
180.18 - */
180.19 -
180.20 -///\ingroup io_group
180.21 -///\file
180.22 -///\brief Lemon Format writer.
180.23 -
180.24 -#ifndef LEMON_LEMON_WRITER_H
180.25 -#define LEMON_LEMON_WRITER_H
180.26 -
180.27 -#include <iostream>
180.28 -#include <fstream>
180.29 -#include <string>
180.30 -#include <vector>
180.31 -#include <algorithm>
180.32 -#include <map>
180.33 -#include <memory>
180.34 -
180.35 -#include <lemon/error.h>
180.36 -#include <lemon/invalid.h>
180.37 -#include <lemon/graph_utils.h>
180.38 -#include <lemon/bits/item_writer.h>
180.39 -#include <lemon/utility.h>
180.40 -#include <lemon/maps.h>
180.41 -
180.42 -
180.43 -namespace lemon {
180.44 -
180.45 - /// \ingroup io_group
180.46 - /// \brief Lemon Format writer class.
180.47 - ///
180.48 - /// The Lemon Format contains several sections. We do not want to
180.49 - /// determine what sections are in a lemon file we give only a framework
180.50 - /// to write a section oriented format.
180.51 - ///
180.52 - /// In the Lemon Format each section starts with a line contains a \c \@
180.53 - /// character on the first not white space position. This line is the
180.54 - /// header line of the section. Each next lines belong to this section
180.55 - /// while it does not starts with \c \@ character. This line can start a
180.56 - /// new section or if it can close the file with the \c \@end line.
180.57 - /// The file format ignore the empty lines and it may contain comments
180.58 - /// started with a \c # character to the end of the line.
180.59 - ///
180.60 - /// The framework provides an abstract LemonWriter::SectionWriter class
180.61 - /// what defines the interface of a SectionWriter. The SectionWriter
180.62 - /// has the \c header() member function what gives back the header of the
180.63 - /// section. After that it will be called the \c write() member which
180.64 - /// should write the content of the section.
180.65 - ///
180.66 - /// \relates GraphWriter
180.67 - /// \relates NodeSetWriter
180.68 - /// \relates EdgeSetWriter
180.69 - /// \relates NodesWriter
180.70 - /// \relates EdgesWriter
180.71 - /// \relates AttributeWriter
180.72 - class LemonWriter {
180.73 - public:
180.74 -
180.75 - /// \brief Abstract base class for writing a section.
180.76 - ///
180.77 - /// This class has an \c header() member function what gives back
180.78 - /// the header line of the section. The \c write() member should
180.79 - /// write the content of the section to the stream.
180.80 - class SectionWriter {
180.81 - friend class LemonWriter;
180.82 - protected:
180.83 - /// \brief Constructor for SectionWriter.
180.84 - ///
180.85 - /// Constructor for SectionWriter. It attach this writer to
180.86 - /// the given LemonWriter.
180.87 - SectionWriter(LemonWriter& writer) {
180.88 - writer.attach(*this);
180.89 - }
180.90 -
180.91 - /// \brief The header of section.
180.92 - ///
180.93 - /// It gives back the header of the section.
180.94 - virtual std::string header() = 0;
180.95 -
180.96 - /// \brief Writer function of the section.
180.97 - ///
180.98 - /// Write the content of the section.
180.99 - virtual void write(std::ostream& os) = 0;
180.100 - };
180.101 -
180.102 - /// \brief Constructor for LemonWriter.
180.103 - ///
180.104 - /// Constructor for LemonWriter which writes to the given stream.
180.105 - LemonWriter(std::ostream& _os)
180.106 - : os(&_os), own_os(false) {}
180.107 -
180.108 - /// \brief Constructor for LemonWriter.
180.109 - ///
180.110 - /// Constructor for LemonWriter which writes to the given file.
180.111 - LemonWriter(const std::string& filename)
180.112 - : os(0), own_os(true) {
180.113 - os = new std::ofstream(filename.c_str());
180.114 - }
180.115 -
180.116 - /// \brief Desctructor for LemonWriter.
180.117 - ///
180.118 - /// Desctructor for LemonWriter.
180.119 - ~LemonWriter() {
180.120 - if (own_os) {
180.121 - delete os;
180.122 - }
180.123 - }
180.124 -
180.125 - private:
180.126 - LemonWriter(const LemonWriter&);
180.127 - void operator=(const LemonWriter&);
180.128 -
180.129 - void attach(SectionWriter& writer) {
180.130 - writers.push_back(&writer);
180.131 - }
180.132 -
180.133 - public:
180.134 -
180.135 - /// \brief Executes the LemonWriter.
180.136 - ///
180.137 - /// It executes the LemonWriter.
180.138 - void run() {
180.139 - SectionWriters::iterator it;
180.140 - for (it = writers.begin(); it != writers.end(); ++it) {
180.141 - *os << (*it)->header() << std::endl;
180.142 - (*it)->write(*os);
180.143 - }
180.144 - *os << "@end" << std::endl;
180.145 - }
180.146 -
180.147 -
180.148 - private:
180.149 -
180.150 - std::ostream* os;
180.151 - bool own_os;
180.152 -
180.153 - typedef std::vector<SectionWriter*> SectionWriters;
180.154 - SectionWriters writers;
180.155 -
180.156 - };
180.157 -
180.158 - /// \brief Helper class for implementing the common SectionWriters.
180.159 - ///
180.160 - /// Helper class for implementing the common SectionWriters.
180.161 - class CommonSectionWriterBase : public LemonWriter::SectionWriter {
180.162 - typedef LemonWriter::SectionWriter Parent;
180.163 - protected:
180.164 -
180.165 - /// \brief Constructor for CommonSectionWriterBase.
180.166 - ///
180.167 - /// Constructor for CommonSectionWriterBase. It attach this writer to
180.168 - /// the given LemonWriter.
180.169 - CommonSectionWriterBase(LemonWriter& _writer)
180.170 - : Parent(_writer) {}
180.171 -
180.172 - template <typename _Item>
180.173 - class WriterBase {
180.174 - public:
180.175 - typedef _Item Item;
180.176 -
180.177 - virtual ~WriterBase() {}
180.178 -
180.179 - virtual void write(std::ostream& os, const Item& item) = 0;
180.180 - };
180.181 -
180.182 -
180.183 - template <typename _Item, typename _Map, typename _Writer>
180.184 - class MapWriter : public WriterBase<_Item> {
180.185 - public:
180.186 - typedef _Map Map;
180.187 - typedef _Writer Writer;
180.188 - typedef typename Writer::Value Value;
180.189 - typedef _Item Item;
180.190 -
180.191 - typename SmartConstReference<Map>::Type map;
180.192 - Writer writer;
180.193 -
180.194 - MapWriter(const Map& _map, const Writer& _writer)
180.195 - : map(_map), writer(_writer) {}
180.196 -
180.197 - virtual ~MapWriter() {}
180.198 -
180.199 - virtual void write(std::ostream& os, const Item& item) {
180.200 - Value value = map[item];
180.201 - writer.write(os, value);
180.202 - }
180.203 -
180.204 - };
180.205 -
180.206 -
180.207 - class ValueWriterBase {
180.208 - public:
180.209 - virtual void write(std::ostream&) = 0;
180.210 - };
180.211 -
180.212 - template <typename _Value, typename _Writer>
180.213 - class ValueWriter : public ValueWriterBase {
180.214 - public:
180.215 - typedef _Value Value;
180.216 - typedef _Writer Writer;
180.217 -
180.218 - ValueWriter(const Value& _value, const Writer& _writer)
180.219 - : value(_value), writer(_writer) {}
180.220 -
180.221 - virtual void write(std::ostream& os) {
180.222 - writer.write(os, value);
180.223 - }
180.224 - private:
180.225 - const Value& value;
180.226 - Writer writer;
180.227 - };
180.228 -
180.229 -
180.230 - template <typename _Item>
180.231 - class IdWriterBase {
180.232 - public:
180.233 - typedef _Item Item;
180.234 - virtual void write(std::ostream&, const Item&) const = 0;
180.235 - };
180.236 -
180.237 - template <typename _Item, typename _BoxedIdWriter>
180.238 - class IdWriter : public IdWriterBase<_Item> {
180.239 - public:
180.240 - typedef _Item Item;
180.241 - typedef _BoxedIdWriter BoxedIdWriter;
180.242 -
180.243 - const BoxedIdWriter& idWriter;
180.244 -
180.245 - IdWriter(const BoxedIdWriter& _idWriter)
180.246 - : idWriter(_idWriter) {}
180.247 -
180.248 - virtual void write(std::ostream& os, const Item& item) const {
180.249 - idWriter.writeId(os, item);
180.250 - }
180.251 - };
180.252 - };
180.253 -
180.254 - /// \ingroup io_group
180.255 - /// \brief SectionWriter for writing a graph's nodeset.
180.256 - ///
180.257 - /// The lemon format can store multiple graph nodesets with several maps.
180.258 - /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
180.259 - /// \c nodeset_id may be empty.
180.260 - ///
180.261 - /// The first line of the section contains the names of the maps separated
180.262 - /// with white spaces. Each next lines describes a node in the nodeset, and
180.263 - /// contains the mapped values for each map.
180.264 - ///
180.265 - /// If the nodeset contains an \c "id" named map then it will be regarded
180.266 - /// as id map. This map should contain only unique values and when the
180.267 - /// \c writeId() member will be called with a node it will write it's id.
180.268 - /// Otherwise if the \c _forceIdMap constructor parameter is true then
180.269 - /// the id map will be the id in the graph.
180.270 - ///
180.271 - /// \relates LemonWriter
180.272 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
180.273 - class NodeSetWriter : public CommonSectionWriterBase {
180.274 - typedef CommonSectionWriterBase Parent;
180.275 - public:
180.276 -
180.277 - typedef _Graph Graph;
180.278 - typedef _Traits Traits;
180.279 - typedef typename Graph::Node Node;
180.280 -
180.281 - /// \brief Constructor.
180.282 - ///
180.283 - /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
180.284 - /// attach it into the given LemonWriter. If the \c _forceIdMap
180.285 - /// parameter is true then the writer will write own id map when
180.286 - /// the user does not give "id" named map.
180.287 - NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
180.288 - const std::string& _id = std::string(),
180.289 - bool _forceIdMap = true)
180.290 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
180.291 - graph(_graph), id(_id) {}
180.292 -
180.293 - /// \brief Destructor.
180.294 - ///
180.295 - /// Destructor for NodeSetWriter.
180.296 - virtual ~NodeSetWriter() {
180.297 - typename MapWriters::iterator it;
180.298 - for (it = writers.begin(); it != writers.end(); ++it) {
180.299 - delete it->second;
180.300 - }
180.301 - }
180.302 -
180.303 - private:
180.304 - NodeSetWriter(const NodeSetWriter&);
180.305 - void operator=(const NodeSetWriter&);
180.306 -
180.307 - public:
180.308 -
180.309 - /// \brief Add a new node map writer command for the writer.
180.310 - ///
180.311 - /// Add a new node map writer command for the writer.
180.312 - template <typename Map>
180.313 - NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
180.314 - return writeNodeMap<typename Traits::
180.315 - template Writer<typename Map::Value>, Map>(name, map);
180.316 - }
180.317 -
180.318 - /// \brief Add a new node map writer command for the writer.
180.319 - ///
180.320 - /// Add a new node map writer command for the writer.
180.321 - template <typename Writer, typename Map>
180.322 - NodeSetWriter& writeNodeMap(std::string name, const Map& map,
180.323 - const Writer& writer = Writer()) {
180.324 - writers.push_back(
180.325 - make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
180.326 - return *this;
180.327 - }
180.328 -
180.329 - protected:
180.330 -
180.331 - /// \brief The header of the section.
180.332 - ///
180.333 - /// It gives back the header of the section.
180.334 - virtual std::string header() {
180.335 - return "@nodeset " + id;
180.336 - }
180.337 -
180.338 - /// \brief Writer function of the section.
180.339 - ///
180.340 - /// Write the content of the section.
180.341 - virtual void write(std::ostream& os) {
180.342 - for (int i = 0; i < (int)writers.size(); ++i) {
180.343 - if (writers[i].first == "id") {
180.344 - idMap = writers[i].second;
180.345 - forceIdMap = false;
180.346 - break;
180.347 - }
180.348 - }
180.349 - if (forceIdMap) {
180.350 - os << "id\t";
180.351 - }
180.352 - for (int i = 0; i < (int)writers.size(); ++i) {
180.353 - os << writers[i].first << '\t';
180.354 - }
180.355 - os << std::endl;
180.356 - for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
180.357 - if (forceIdMap) {
180.358 - os << graph.id(it) << '\t';
180.359 - }
180.360 - for (int i = 0; i < (int)writers.size(); ++i) {
180.361 - writers[i].second->write(os, it);
180.362 - os << '\t';
180.363 - }
180.364 - os << std::endl;
180.365 - }
180.366 - }
180.367 -
180.368 - public:
180.369 -
180.370 - /// \brief Returns true if the nodeset can write the ids of the nodes.
180.371 - ///
180.372 - /// Returns true if the nodeset can write the ids of the nodes.
180.373 - /// It is possible only if an "id" named map was written or the
180.374 - /// \c _forceIdMap constructor parameter was true.
180.375 - bool isIdWriter() const {
180.376 - return idMap != 0 || forceIdMap;
180.377 - }
180.378 -
180.379 - /// \brief Write the id of the given node.
180.380 - ///
180.381 - /// It writes the id of the given node. If there was written an "id"
180.382 - /// named map then it will write the map value belongs to the node.
180.383 - /// Otherwise if the \c forceId parameter was true it will write
180.384 - /// its id in the graph.
180.385 - void writeId(std::ostream& os, const Node& item) const {
180.386 - if (forceIdMap) {
180.387 - os << graph.id(item);
180.388 - } else {
180.389 - idMap->write(os, item);
180.390 - }
180.391 - }
180.392 -
180.393 - private:
180.394 -
180.395 - typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
180.396 - MapWriters writers;
180.397 -
180.398 - WriterBase<Node>* idMap;
180.399 - bool forceIdMap;
180.400 -
180.401 - typename SmartConstReference<Graph>::Type graph;
180.402 - std::string id;
180.403 -
180.404 - };
180.405 -
180.406 - /// \ingroup io_group
180.407 - /// \brief SectionWriter for writing a graph's edgesets.
180.408 - ///
180.409 - /// The lemon format can store multiple graph edgesets with several maps.
180.410 - /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
180.411 - /// \c edgeset_id may be empty.
180.412 - ///
180.413 - /// The first line of the section contains the names of the maps separated
180.414 - /// with white spaces. Each next lines describes a edge in the edgeset. The
180.415 - /// line contains the source and the target nodes' id and the mapped
180.416 - /// values for each map.
180.417 - ///
180.418 - /// If the edgeset contains an \c "id" named map then it will be regarded
180.419 - /// as id map. This map should contain only unique values and when the
180.420 - /// \c writeId() member will be called with an edge it will write it's id.
180.421 - /// Otherwise if the \c _forceIdMap constructor parameter is true then
180.422 - /// the id map will be the id in the graph.
180.423 - ///
180.424 - /// The edgeset writer needs a node id writer to identify which nodes
180.425 - /// have to be connected. If a NodeSetWriter can write the nodes' id,
180.426 - /// it will be able to use with this class.
180.427 - ///
180.428 - /// \relates LemonWriter
180.429 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
180.430 - class EdgeSetWriter : public CommonSectionWriterBase {
180.431 - typedef CommonSectionWriterBase Parent;
180.432 - public:
180.433 -
180.434 - typedef _Graph Graph;
180.435 - typedef _Traits Traits;
180.436 - typedef typename Graph::Node Node;
180.437 - typedef typename Graph::Edge Edge;
180.438 -
180.439 - /// \brief Constructor.
180.440 - ///
180.441 - /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
180.442 - /// attach it into the given LemonWriter. It will write node ids by
180.443 - /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
180.444 - /// then the writer will write own id map if the user does not give
180.445 - /// "id" named map.
180.446 - template <typename NodeIdWriter>
180.447 - EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
180.448 - const NodeIdWriter& _nodeIdWriter,
180.449 - const std::string& _id = std::string(),
180.450 - bool _forceIdMap = true)
180.451 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
180.452 - graph(_graph), id(_id),
180.453 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
180.454 -
180.455 - /// \brief Destructor.
180.456 - ///
180.457 - /// Destructor for EdgeSetWriter.
180.458 - virtual ~EdgeSetWriter() {
180.459 - typename MapWriters::iterator it;
180.460 - for (it = writers.begin(); it != writers.end(); ++it) {
180.461 - delete it->second;
180.462 - }
180.463 - }
180.464 -
180.465 - private:
180.466 - EdgeSetWriter(const EdgeSetWriter&);
180.467 - void operator=(const EdgeSetWriter&);
180.468 -
180.469 - public:
180.470 -
180.471 - /// \brief Add a new edge map writer command for the writer.
180.472 - ///
180.473 - /// Add a new edge map writer command for the writer.
180.474 - template <typename Map>
180.475 - EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
180.476 - return writeEdgeMap<typename Traits::
180.477 - template Writer<typename Map::Value>, Map>(name, map);
180.478 - }
180.479 -
180.480 - /// \brief Add a new edge map writer command for the writer.
180.481 - ///
180.482 - /// Add a new edge map writer command for the writer.
180.483 - template <typename Writer, typename Map>
180.484 - EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
180.485 - const Writer& writer = Writer()) {
180.486 - writers.push_back(
180.487 - make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
180.488 - return *this;
180.489 - }
180.490 -
180.491 - protected:
180.492 -
180.493 - /// \brief The header of the section.
180.494 - ///
180.495 - /// It gives back the header of the section.
180.496 - virtual std::string header() {
180.497 - return "@edgeset " + id;
180.498 - }
180.499 -
180.500 - /// \brief Writer function of the section.
180.501 - ///
180.502 - /// Write the content of the section.
180.503 - virtual void write(std::ostream& os) {
180.504 - for (int i = 0; i < (int)writers.size(); ++i) {
180.505 - if (writers[i].first == "id") {
180.506 - idMap = writers[i].second;
180.507 - forceIdMap = false;
180.508 - break;
180.509 - }
180.510 - }
180.511 - os << "\t\t";
180.512 - if (forceIdMap) {
180.513 - os << "id\t";
180.514 - }
180.515 - for (int i = 0; i < (int)writers.size(); ++i) {
180.516 - os << writers[i].first << '\t';
180.517 - }
180.518 - os << std::endl;
180.519 - for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
180.520 - nodeIdWriter->write(os, graph.source(it));
180.521 - os << '\t';
180.522 - nodeIdWriter->write(os, graph.target(it));
180.523 - os << '\t';
180.524 - if (forceIdMap) {
180.525 - os << graph.id(it) << '\t';
180.526 - }
180.527 - for (int i = 0; i < (int)writers.size(); ++i) {
180.528 - writers[i].second->write(os, it);
180.529 - os << '\t';
180.530 - }
180.531 - os << std::endl;
180.532 - }
180.533 - }
180.534 -
180.535 - public:
180.536 -
180.537 - /// \brief Returns true if the edgeset can write the ids of the edges.
180.538 - ///
180.539 - /// Returns true if the edgeset can write the ids of the edges.
180.540 - /// It is possible only if an "id" named map was written or the
180.541 - /// \c _forceIdMap constructor parameter was true.
180.542 - bool isIdWriter() const {
180.543 - return forceIdMap || idMap != 0;
180.544 - }
180.545 -
180.546 - /// \brief Write the id of the given edge.
180.547 - ///
180.548 - /// It writes the id of the given edge. If there was written an "id"
180.549 - /// named map then it will write the map value belongs to the edge.
180.550 - /// Otherwise if the \c forceId parameter was true it will write
180.551 - /// its id in the graph.
180.552 - void writeId(std::ostream& os, const Edge& item) const {
180.553 - if (forceIdMap) {
180.554 - os << graph.id(item);
180.555 - } else {
180.556 - idMap->write(os, item);
180.557 - }
180.558 - }
180.559 -
180.560 - private:
180.561 -
180.562 - typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
180.563 - MapWriters writers;
180.564 -
180.565 - WriterBase<Edge>* idMap;
180.566 - bool forceIdMap;
180.567 -
180.568 - typename SmartConstReference<Graph>::Type graph;
180.569 - std::string id;
180.570 -
180.571 - std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
180.572 - };
180.573 -
180.574 - /// \ingroup io_group
180.575 - /// \brief SectionWriter for writing a undirected edgeset.
180.576 - ///
180.577 - /// The lemon format can store multiple undirected edgesets with several
180.578 - /// maps. The undirected edgeset section's header line is \c \@undiredgeset
180.579 - /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
180.580 - ///
180.581 - /// The first line of the section contains the names of the maps separated
180.582 - /// with white spaces. Each next lines describes an undirected edge in the
180.583 - /// edgeset. The line contains the two connected nodes' id and the mapped
180.584 - /// values for each undirected map.
180.585 - ///
180.586 - /// The section can handle the directed as a syntactical sugar. Two
180.587 - /// undirected edge map describes one directed edge map. This two maps
180.588 - /// are the forward map and the backward map and the names of this map
180.589 - /// is near the same just with a prefix \c '+' or \c '-' character
180.590 - /// difference.
180.591 - ///
180.592 - /// If the edgeset contains an \c "id" named map then it will be regarded
180.593 - /// as id map. This map should contain only unique values and when the
180.594 - /// \c writeId() member will be called with an undirected edge it will
180.595 - /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
180.596 - /// is true then the id map will be the id in the graph.
180.597 - ///
180.598 - /// The undirected edgeset writer needs a node id writer to identify
180.599 - /// which nodes have to be connected. If a NodeSetWriter can write the
180.600 - /// nodes' id, it will be able to use with this class.
180.601 - ///
180.602 - /// \relates LemonWriter
180.603 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
180.604 - class UndirEdgeSetWriter : public CommonSectionWriterBase {
180.605 - typedef CommonSectionWriterBase Parent;
180.606 - public:
180.607 -
180.608 - typedef _Graph Graph;
180.609 - typedef _Traits Traits;
180.610 - typedef typename Graph::Node Node;
180.611 - typedef typename Graph::Edge Edge;
180.612 - typedef typename Graph::UndirEdge UndirEdge;
180.613 -
180.614 - /// \brief Constructor.
180.615 - ///
180.616 - /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
180.617 - /// and attach it into the given LemonWriter. It will write node ids by
180.618 - /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
180.619 - /// then the writer will write own id map if the user does not give
180.620 - /// "id" named map.
180.621 - template <typename NodeIdWriter>
180.622 - UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
180.623 - const NodeIdWriter& _nodeIdWriter,
180.624 - const std::string& _id = std::string(),
180.625 - bool _forceIdMap = true)
180.626 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
180.627 - graph(_graph), id(_id),
180.628 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
180.629 -
180.630 - /// \brief Destructor.
180.631 - ///
180.632 - /// Destructor for UndirEdgeSetWriter.
180.633 - virtual ~UndirEdgeSetWriter() {
180.634 - typename MapWriters::iterator it;
180.635 - for (it = writers.begin(); it != writers.end(); ++it) {
180.636 - delete it->second;
180.637 - }
180.638 - }
180.639 -
180.640 - private:
180.641 - UndirEdgeSetWriter(const UndirEdgeSetWriter&);
180.642 - void operator=(const UndirEdgeSetWriter&);
180.643 -
180.644 - public:
180.645 -
180.646 - /// \brief Add a new undirected edge map writer command for the writer.
180.647 - ///
180.648 - /// Add a new undirected map writer command for the writer.
180.649 - template <typename Map>
180.650 - UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
180.651 - return writeUndirEdgeMap<typename Traits::
180.652 - template Writer<typename Map::Value>, Map>(name, map);
180.653 - }
180.654 -
180.655 - /// \brief Add a new undirected map writer command for the writer.
180.656 - ///
180.657 - /// Add a new undirected map writer command for the writer.
180.658 - template <typename Writer, typename Map>
180.659 - UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
180.660 - const Writer& writer = Writer()) {
180.661 - writers.push_back(
180.662 - make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
180.663 - return *this;
180.664 - }
180.665 -
180.666 - /// \brief Add a new directed edge map writer command for the writer.
180.667 - ///
180.668 - /// Add a new directed map writer command for the writer.
180.669 - template <typename Map>
180.670 - UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
180.671 - writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
180.672 - writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
180.673 - return *this;
180.674 - }
180.675 -
180.676 - /// \brief Add a new directed map writer command for the writer.
180.677 - ///
180.678 - /// Add a new directed map writer command for the writer.
180.679 - template <typename Writer, typename Map>
180.680 - UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
180.681 - const Writer& writer = Writer()) {
180.682 - writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
180.683 - writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
180.684 - return *this;
180.685 - }
180.686 -
180.687 - protected:
180.688 -
180.689 - /// \brief The header of the section.
180.690 - ///
180.691 - /// It gives back the header of the section.
180.692 - virtual std::string header() {
180.693 - return "@undiredgeset " + id;
180.694 - }
180.695 -
180.696 - /// \brief Writer function of the section.
180.697 - ///
180.698 - /// Write the content of the section.
180.699 - virtual void write(std::ostream& os) {
180.700 - for (int i = 0; i < (int)writers.size(); ++i) {
180.701 - if (writers[i].first == "id") {
180.702 - idMap = writers[i].second;
180.703 - forceIdMap = false;
180.704 - break;
180.705 - }
180.706 - }
180.707 - os << "\t\t";
180.708 - if (forceIdMap) {
180.709 - os << "id\t";
180.710 - }
180.711 - for (int i = 0; i < (int)writers.size(); ++i) {
180.712 - os << writers[i].first << '\t';
180.713 - }
180.714 - os << std::endl;
180.715 - for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
180.716 - nodeIdWriter->write(os, graph.source(it));
180.717 - os << '\t';
180.718 - nodeIdWriter->write(os, graph.target(it));
180.719 - os << '\t';
180.720 - if (forceIdMap) {
180.721 - os << graph.id(it) << '\t';
180.722 - }
180.723 - for (int i = 0; i < (int)writers.size(); ++i) {
180.724 - writers[i].second->write(os, it);
180.725 - os << '\t';
180.726 - }
180.727 - os << std::endl;
180.728 - }
180.729 - }
180.730 -
180.731 - public:
180.732 -
180.733 - /// \brief Returns true if the undirected edgeset can write the ids of
180.734 - /// the edges.
180.735 - ///
180.736 - /// Returns true if the undirected edgeset can write the ids of the
180.737 - /// undirected edges. It is possible only if an "id" named map was
180.738 - /// written or the \c _forceIdMap constructor parameter was true.
180.739 - bool isIdWriter() const {
180.740 - return forceIdMap || idMap != 0;
180.741 - }
180.742 -
180.743 - /// \brief Write the id of the given undirected edge.
180.744 - ///
180.745 - /// It writes the id of the given undirected edge. If there was written
180.746 - /// an "id" named map then it will write the map value belongs to the
180.747 - /// undirected edge. Otherwise if the \c forceId parameter was true it
180.748 - /// will write its id in the graph.
180.749 - void writeId(std::ostream& os, const UndirEdge& item) const {
180.750 - if (forceIdMap) {
180.751 - os << graph.id(item);
180.752 - } else {
180.753 - idMap->write(os, item);
180.754 - }
180.755 - }
180.756 -
180.757 - /// \brief Write the id of the given edge.
180.758 - ///
180.759 - /// It writes the id of the given edge. If there was written
180.760 - /// an "id" named map then it will write the map value belongs to the
180.761 - /// edge. Otherwise if the \c forceId parameter was true it
180.762 - /// will write its id in the graph. If the edge is forward map
180.763 - /// then its prefix character is \c '+' elsewhere \c '-'.
180.764 - void writeId(std::ostream& os, const Edge& item) const {
180.765 - if (graph.forward(item)) {
180.766 - os << "+ ";
180.767 - } else {
180.768 - os << "- ";
180.769 - }
180.770 - if (forceIdMap) {
180.771 - os << graph.id(item);
180.772 - } else {
180.773 - idMap->write(os, item);
180.774 - }
180.775 - }
180.776 -
180.777 - private:
180.778 -
180.779 - typedef std::vector<std::pair<std::string,
180.780 - WriterBase<UndirEdge>*> > MapWriters;
180.781 - MapWriters writers;
180.782 -
180.783 - WriterBase<UndirEdge>* idMap;
180.784 - bool forceIdMap;
180.785 -
180.786 - typename SmartConstReference<Graph>::Type graph;
180.787 - std::string id;
180.788 -
180.789 - std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
180.790 - };
180.791 -
180.792 - /// \ingroup io_group
180.793 - /// \brief SectionWriter for writing labeled nodes.
180.794 - ///
180.795 - /// The nodes section's header line is \c \@nodes \c nodes_id, but the
180.796 - /// \c nodes_id may be empty.
180.797 - ///
180.798 - /// Each line in the section contains the label of the node and
180.799 - /// then the node id.
180.800 - ///
180.801 - /// \relates LemonWriter
180.802 - template <typename _Graph>
180.803 - class NodeWriter : public CommonSectionWriterBase {
180.804 - typedef CommonSectionWriterBase Parent;
180.805 - typedef _Graph Graph;
180.806 - typedef typename Graph::Node Node;
180.807 - public:
180.808 -
180.809 - /// \brief Constructor.
180.810 - ///
180.811 - /// Constructor for NodeWriter. It creates the NodeWriter and
180.812 - /// attach it into the given LemonWriter. The given \c _IdWriter
180.813 - /// will write the nodes' id what can be a nodeset writer.
180.814 - template <typename _IdWriter>
180.815 - NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
180.816 - const std::string& _id = std::string())
180.817 - : Parent(_writer), id(_id),
180.818 - idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
180.819 -
180.820 - /// \brief Destructor.
180.821 - ///
180.822 - /// Destructor for NodeWriter.
180.823 - virtual ~NodeWriter() {}
180.824 -
180.825 - private:
180.826 - NodeWriter(const NodeWriter&);
180.827 - void operator=(const NodeWriter&);
180.828 -
180.829 - public:
180.830 -
180.831 - /// \brief Add a node writer command for the NodeWriter.
180.832 - ///
180.833 - /// Add a node writer command for the NodeWriter.
180.834 - void writeNode(const std::string& name, const Node& item) {
180.835 - writers.push_back(make_pair(name, &item));
180.836 - }
180.837 -
180.838 - protected:
180.839 -
180.840 - /// \brief Header checking function.
180.841 - ///
180.842 - /// It gives back true when the header line start with \c \@nodes,
180.843 - /// and the header line's id and the writer's id are the same.
180.844 - virtual std::string header() {
180.845 - return "@nodes " + id;
180.846 - }
180.847 -
180.848 - /// \brief Writer function of the section.
180.849 - ///
180.850 - /// Write the content of the section.
180.851 - virtual void write(std::ostream& os) {
180.852 - for (int i = 0; i < (int)writers.size(); ++i) {
180.853 - os << writers[i].first << ' ';
180.854 - idWriter->write(os, *(writers[i].second));
180.855 - os << std::endl;
180.856 - }
180.857 - }
180.858 -
180.859 - private:
180.860 -
180.861 - std::string id;
180.862 -
180.863 - typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
180.864 - NodeWriters writers;
180.865 - std::auto_ptr<IdWriterBase<Node> > idWriter;
180.866 - };
180.867 -
180.868 - /// \ingroup io_group
180.869 - /// \brief SectionWriter for writing labeled edges.
180.870 - ///
180.871 - /// The edges section's header line is \c \@edges \c edges_id, but the
180.872 - /// \c edges_id may be empty.
180.873 - ///
180.874 - /// Each line in the section contains the label of the edge and
180.875 - /// then the edge id.
180.876 - ///
180.877 - /// \relates LemonWriter
180.878 - template <typename _Graph>
180.879 - class EdgeWriter : public CommonSectionWriterBase {
180.880 - typedef CommonSectionWriterBase Parent;
180.881 - typedef _Graph Graph;
180.882 - typedef typename Graph::Edge Edge;
180.883 - public:
180.884 -
180.885 - /// \brief Constructor.
180.886 - ///
180.887 - /// Constructor for EdgeWriter. It creates the EdgeWriter and
180.888 - /// attach it into the given LemonWriter. The given \c _IdWriter
180.889 - /// will write the edges' id what can be a edgeset writer.
180.890 - template <typename _IdWriter>
180.891 - EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
180.892 - const std::string& _id = std::string())
180.893 - : Parent(_writer), id(_id),
180.894 - idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
180.895 -
180.896 - /// \brief Destructor.
180.897 - ///
180.898 - /// Destructor for EdgeWriter.
180.899 - virtual ~EdgeWriter() {}
180.900 - private:
180.901 - EdgeWriter(const EdgeWriter&);
180.902 - void operator=(const EdgeWriter&);
180.903 -
180.904 - public:
180.905 -
180.906 - /// \brief Add an edge writer command for the EdgeWriter.
180.907 - ///
180.908 - /// Add an edge writer command for the EdgeWriter.
180.909 - void writeEdge(const std::string& name, const Edge& item) {
180.910 - writers.push_back(make_pair(name, &item));
180.911 - }
180.912 -
180.913 - protected:
180.914 -
180.915 - /// \brief Header checking function.
180.916 - ///
180.917 - /// It gives back true when the header line start with \c \@edges,
180.918 - /// and the header line's id and the writer's id are the same.
180.919 - virtual std::string header() {
180.920 - return "@edges " + id;
180.921 - }
180.922 -
180.923 - /// \brief Writer function of the section.
180.924 - ///
180.925 - /// Write the content of the section.
180.926 - virtual void write(std::ostream& os) {
180.927 - for (int i = 0; i < (int)writers.size(); ++i) {
180.928 - os << writers[i].first << ' ';
180.929 - idWriter->write(os, *(writers[i].second));
180.930 - os << std::endl;
180.931 - }
180.932 - }
180.933 -
180.934 - private:
180.935 -
180.936 - std::string id;
180.937 -
180.938 - typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
180.939 - EdgeWriters writers;
180.940 -
180.941 - std::auto_ptr<IdWriterBase<Edge> > idWriter;
180.942 - };
180.943 -
180.944 - /// \ingroup io_group
180.945 - /// \brief SectionWriter for writing labeled undirected edges.
180.946 - ///
180.947 - /// The undirected edges section's header line is \c \@undiredges
180.948 - /// \c undiredges_id, but the \c undiredges_id may be empty.
180.949 - ///
180.950 - /// Each line in the section contains the label of the undirected edge and
180.951 - /// then the undirected edge id.
180.952 - ///
180.953 - /// \relates LemonWriter
180.954 - template <typename _Graph>
180.955 - class UndirEdgeWriter : public CommonSectionWriterBase {
180.956 - typedef CommonSectionWriterBase Parent;
180.957 - typedef _Graph Graph;
180.958 - typedef typename Graph::Node Node;
180.959 - typedef typename Graph::Edge Edge;
180.960 - typedef typename Graph::UndirEdge UndirEdge;
180.961 - public:
180.962 -
180.963 - /// \brief Constructor.
180.964 - ///
180.965 - /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
180.966 - /// attach it into the given LemonWriter. The given \c _IdWriter
180.967 - /// will write the undirected edges' id what can be an undirected
180.968 - /// edgeset writer.
180.969 - template <typename _IdWriter>
180.970 - UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
180.971 - const std::string& _id = std::string())
180.972 - : Parent(_writer), id(_id),
180.973 - undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
180.974 - edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
180.975 -
180.976 - /// \brief Destructor.
180.977 - ///
180.978 - /// Destructor for UndirEdgeWriter.
180.979 - virtual ~UndirEdgeWriter() {}
180.980 - private:
180.981 - UndirEdgeWriter(const UndirEdgeWriter&);
180.982 - void operator=(const UndirEdgeWriter&);
180.983 -
180.984 - public:
180.985 -
180.986 - /// \brief Add an edge writer command for the UndirEdgeWriter.
180.987 - ///
180.988 - /// Add an edge writer command for the UndirEdgeWriter.
180.989 - void writeEdge(const std::string& name, const Edge& item) {
180.990 - edgeWriters.push_back(make_pair(name, &item));
180.991 - }
180.992 -
180.993 - /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
180.994 - ///
180.995 - /// Add an undirected edge writer command for the UndirEdgeWriter.
180.996 - void writeUndirEdge(const std::string& name, const UndirEdge& item) {
180.997 - undirEdgeWriters.push_back(make_pair(name, &item));
180.998 - }
180.999 -
180.1000 - protected:
180.1001 -
180.1002 - /// \brief Header checking function.
180.1003 - ///
180.1004 - /// It gives back true when the header line start with \c \@undiredges,
180.1005 - /// and the header line's id and the writer's id are the same.
180.1006 - virtual std::string header() {
180.1007 - return "@undiredges " + id;
180.1008 - }
180.1009 -
180.1010 - /// \brief Writer function of the section.
180.1011 - ///
180.1012 - /// Write the content of the section.
180.1013 - virtual void write(std::ostream& os) {
180.1014 - for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
180.1015 - os << undirEdgeWriters[i].first << ' ';
180.1016 - undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
180.1017 - os << std::endl;
180.1018 - }
180.1019 - for (int i = 0; i < (int)edgeWriters.size(); ++i) {
180.1020 - os << edgeWriters[i].first << ' ';
180.1021 - edgeIdWriter->write(os, *(edgeWriters[i].second));
180.1022 - os << std::endl;
180.1023 - }
180.1024 - }
180.1025 -
180.1026 - private:
180.1027 -
180.1028 - std::string id;
180.1029 -
180.1030 - typedef std::vector<std::pair<std::string,
180.1031 - const UndirEdge*> > UndirEdgeWriters;
180.1032 - UndirEdgeWriters undirEdgeWriters;
180.1033 - std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
180.1034 -
180.1035 - typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
180.1036 - EdgeWriters edgeWriters;
180.1037 - std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
180.1038 -
180.1039 - };
180.1040 -
180.1041 - /// \ingroup io_group
180.1042 - /// \brief SectionWriter for attributes.
180.1043 - ///
180.1044 - /// The lemon format can store multiple attribute set. Each set has
180.1045 - /// the header line \c \@attributes \c attributeset_id, but the
180.1046 - /// attributeset_id may be empty.
180.1047 - ///
180.1048 - /// The attributeset section contains several lines. Each of them starts
180.1049 - /// with the name of attribute and then the value.
180.1050 - ///
180.1051 - /// \relates LemonWriter
180.1052 - template <typename _Traits = DefaultWriterTraits>
180.1053 - class AttributeWriter : public CommonSectionWriterBase {
180.1054 - typedef CommonSectionWriterBase Parent;
180.1055 - typedef _Traits Traits;
180.1056 - public:
180.1057 - /// \brief Constructor.
180.1058 - ///
180.1059 - /// Constructor for AttributeWriter. It creates the AttributeWriter and
180.1060 - /// attach it into the given LemonWriter.
180.1061 - AttributeWriter(LemonWriter& _writer,
180.1062 - const std::string& _id = std::string())
180.1063 - : Parent(_writer), id(_id) {}
180.1064 -
180.1065 - /// \brief Destructor.
180.1066 - ///
180.1067 - /// Destructor for AttributeWriter.
180.1068 - virtual ~AttributeWriter() {
180.1069 - typename Writers::iterator it;
180.1070 - for (it = writers.begin(); it != writers.end(); ++it) {
180.1071 - delete it->second;
180.1072 - }
180.1073 - }
180.1074 -
180.1075 - private:
180.1076 - AttributeWriter(const AttributeWriter&);
180.1077 - void operator=(AttributeWriter&);
180.1078 -
180.1079 - public:
180.1080 - /// \brief Add an attribute writer command for the writer.
180.1081 - ///
180.1082 - /// Add an attribute writer command for the writer.
180.1083 - template <typename Value>
180.1084 - AttributeWriter& writeAttribute(const std::string& id,
180.1085 - const Value& value) {
180.1086 - return
180.1087 - writeAttribute<typename Traits::template Writer<Value> >(id, value);
180.1088 - }
180.1089 -
180.1090 - /// \brief Add an attribute writer command for the writer.
180.1091 - ///
180.1092 - /// Add an attribute writer command for the writer.
180.1093 - template <typename Writer, typename Value>
180.1094 - AttributeWriter& writeAttribute(const std::string& name,
180.1095 - const Value& value,
180.1096 - const Writer& writer = Writer()) {
180.1097 - writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
180.1098 - (value, writer)));
180.1099 - return *this;
180.1100 - }
180.1101 -
180.1102 - protected:
180.1103 -
180.1104 - /// \brief The header of section.
180.1105 - ///
180.1106 - /// It gives back the header of the section.
180.1107 - std::string header() {
180.1108 - return "@attributes " + id;
180.1109 - }
180.1110 -
180.1111 - /// \brief Writer function of the section.
180.1112 - ///
180.1113 - /// Write the content of the section.
180.1114 - void write(std::ostream& os) {
180.1115 - typename Writers::iterator it;
180.1116 - for (it = writers.begin(); it != writers.end(); ++it) {
180.1117 - os << it->first << ' ';
180.1118 - it->second->write(os);
180.1119 - os << std::endl;
180.1120 - }
180.1121 - }
180.1122 -
180.1123 - private:
180.1124 - std::string id;
180.1125 -
180.1126 - typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;
180.1127 - Writers writers;
180.1128 - };
180.1129 -
180.1130 -
180.1131 -}
180.1132 -#endif
181.1 --- a/src/lemon/list_graph.h Sat May 21 21:04:57 2005 +0000
181.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
181.3 @@ -1,565 +0,0 @@
181.4 -/* -*- C++ -*-
181.5 - * src/lemon/list_graph.h - Part of LEMON, a generic C++ optimization library
181.6 - *
181.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
181.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
181.9 - *
181.10 - * Permission to use, modify and distribute this software is granted
181.11 - * provided that this copyright notice appears in all copies. For
181.12 - * precise terms see the accompanying LICENSE file.
181.13 - *
181.14 - * This software is provided "AS IS" with no warranty of any kind,
181.15 - * express or implied, and with no claim as to its suitability for any
181.16 - * purpose.
181.17 - *
181.18 - */
181.19 -
181.20 -#ifndef LEMON_LIST_GRAPH_H
181.21 -#define LEMON_LIST_GRAPH_H
181.22 -
181.23 -///\ingroup graphs
181.24 -///\file
181.25 -///\brief ListGraph, SymListGraph classes.
181.26 -
181.27 -#include <lemon/bits/erasable_graph_extender.h>
181.28 -#include <lemon/bits/clearable_graph_extender.h>
181.29 -#include <lemon/bits/extendable_graph_extender.h>
181.30 -#include <lemon/bits/iterable_graph_extender.h>
181.31 -#include <lemon/bits/alteration_notifier.h>
181.32 -#include <lemon/bits/default_map.h>
181.33 -
181.34 -#include <lemon/bits/undir_graph_extender.h>
181.35 -
181.36 -#include <list>
181.37 -
181.38 -namespace lemon {
181.39 -
181.40 - class ListGraphBase {
181.41 -
181.42 - protected:
181.43 - struct NodeT {
181.44 - int first_in,first_out;
181.45 - int prev, next;
181.46 - };
181.47 -
181.48 - struct EdgeT {
181.49 - int target, source;
181.50 - int prev_in, prev_out;
181.51 - int next_in, next_out;
181.52 - };
181.53 -
181.54 - std::vector<NodeT> nodes;
181.55 -
181.56 - int first_node;
181.57 -
181.58 - int first_free_node;
181.59 -
181.60 - std::vector<EdgeT> edges;
181.61 -
181.62 - int first_free_edge;
181.63 -
181.64 - public:
181.65 -
181.66 - typedef ListGraphBase Graph;
181.67 -
181.68 - class Node {
181.69 - friend class ListGraphBase;
181.70 - protected:
181.71 -
181.72 - int id;
181.73 - Node(int pid) { id = pid;}
181.74 -
181.75 - public:
181.76 - Node() {}
181.77 - Node (Invalid) { id = -1; }
181.78 - bool operator==(const Node& node) const {return id == node.id;}
181.79 - bool operator!=(const Node& node) const {return id != node.id;}
181.80 - bool operator<(const Node& node) const {return id < node.id;}
181.81 - };
181.82 -
181.83 - class Edge {
181.84 - friend class ListGraphBase;
181.85 - protected:
181.86 -
181.87 - int id;
181.88 - Edge(int pid) { id = pid;}
181.89 -
181.90 - public:
181.91 - Edge() {}
181.92 - Edge (Invalid) { id = -1; }
181.93 - bool operator==(const Edge& edge) const {return id == edge.id;}
181.94 - bool operator!=(const Edge& edge) const {return id != edge.id;}
181.95 - bool operator<(const Edge& edge) const {return id < edge.id;}
181.96 - };
181.97 -
181.98 -
181.99 -
181.100 - ListGraphBase()
181.101 - : nodes(), first_node(-1),
181.102 - first_free_node(-1), edges(), first_free_edge(-1) {}
181.103 -
181.104 -
181.105 - /// Maximum node ID.
181.106 -
181.107 - /// Maximum node ID.
181.108 - ///\sa id(Node)
181.109 - int maxId(Node = INVALID) const { return nodes.size()-1; }
181.110 -
181.111 - /// Maximum edge ID.
181.112 -
181.113 - /// Maximum edge ID.
181.114 - ///\sa id(Edge)
181.115 - int maxId(Edge = INVALID) const { return edges.size()-1; }
181.116 -
181.117 - Node source(Edge e) const { return edges[e.id].source; }
181.118 - Node target(Edge e) const { return edges[e.id].target; }
181.119 -
181.120 -
181.121 - void first(Node& node) const {
181.122 - node.id = first_node;
181.123 - }
181.124 -
181.125 - void next(Node& node) const {
181.126 - node.id = nodes[node.id].next;
181.127 - }
181.128 -
181.129 -
181.130 - void first(Edge& e) const {
181.131 - int n;
181.132 - for(n = first_node;
181.133 - n!=-1 && nodes[n].first_in == -1;
181.134 - n = nodes[n].next);
181.135 - e.id = (n == -1) ? -1 : nodes[n].first_in;
181.136 - }
181.137 -
181.138 - void next(Edge& edge) const {
181.139 - if (edges[edge.id].next_in != -1) {
181.140 - edge.id = edges[edge.id].next_in;
181.141 - } else {
181.142 - int n;
181.143 - for(n = nodes[edges[edge.id].target].next;
181.144 - n!=-1 && nodes[n].first_in == -1;
181.145 - n = nodes[n].next);
181.146 - edge.id = (n == -1) ? -1 : nodes[n].first_in;
181.147 - }
181.148 - }
181.149 -
181.150 - void firstOut(Edge &e, const Node& v) const {
181.151 - e.id = nodes[v.id].first_out;
181.152 - }
181.153 - void nextOut(Edge &e) const {
181.154 - e.id=edges[e.id].next_out;
181.155 - }
181.156 -
181.157 - void firstIn(Edge &e, const Node& v) const {
181.158 - e.id = nodes[v.id].first_in;
181.159 - }
181.160 - void nextIn(Edge &e) const {
181.161 - e.id=edges[e.id].next_in;
181.162 - }
181.163 -
181.164 -
181.165 - static int id(Node v) { return v.id; }
181.166 - static int id(Edge e) { return e.id; }
181.167 -
181.168 - static Node fromId(int id, Node) { return Node(id);}
181.169 - static Edge fromId(int id, Edge) { return Edge(id);}
181.170 -
181.171 - /// Adds a new node to the graph.
181.172 -
181.173 - /// \warning It adds the new node to the front of the list.
181.174 - /// (i.e. the lastly added node becomes the first.)
181.175 - Node addNode() {
181.176 - int n;
181.177 -
181.178 - if(first_free_node==-1) {
181.179 - n = nodes.size();
181.180 - nodes.push_back(NodeT());
181.181 - } else {
181.182 - n = first_free_node;
181.183 - first_free_node = nodes[n].next;
181.184 - }
181.185 -
181.186 - nodes[n].next = first_node;
181.187 - if(first_node != -1) nodes[first_node].prev = n;
181.188 - first_node = n;
181.189 - nodes[n].prev = -1;
181.190 -
181.191 - nodes[n].first_in = nodes[n].first_out = -1;
181.192 -
181.193 - return Node(n);
181.194 - }
181.195 -
181.196 - Edge addEdge(Node u, Node v) {
181.197 - int n;
181.198 -
181.199 - if (first_free_edge == -1) {
181.200 - n = edges.size();
181.201 - edges.push_back(EdgeT());
181.202 - } else {
181.203 - n = first_free_edge;
181.204 - first_free_edge = edges[n].next_in;
181.205 - }
181.206 -
181.207 - edges[n].source = u.id;
181.208 - edges[n].target = v.id;
181.209 -
181.210 - edges[n].next_out = nodes[u.id].first_out;
181.211 - if(nodes[u.id].first_out != -1) {
181.212 - edges[nodes[u.id].first_out].prev_out = n;
181.213 - }
181.214 -
181.215 - edges[n].next_in = nodes[v.id].first_in;
181.216 - if(nodes[v.id].first_in != -1) {
181.217 - edges[nodes[v.id].first_in].prev_in = n;
181.218 - }
181.219 -
181.220 - edges[n].prev_in = edges[n].prev_out = -1;
181.221 -
181.222 - nodes[u.id].first_out = nodes[v.id].first_in = n;
181.223 -
181.224 - return Edge(n);
181.225 - }
181.226 -
181.227 - void erase(const Node& node) {
181.228 - int n = node.id;
181.229 -
181.230 - if(nodes[n].next != -1) {
181.231 - nodes[nodes[n].next].prev = nodes[n].prev;
181.232 - }
181.233 -
181.234 - if(nodes[n].prev != -1) {
181.235 - nodes[nodes[n].prev].next = nodes[n].next;
181.236 - } else {
181.237 - first_node = nodes[n].next;
181.238 - }
181.239 -
181.240 - nodes[n].next = first_free_node;
181.241 - first_free_node = n;
181.242 -
181.243 - }
181.244 -
181.245 - void erase(const Edge& edge) {
181.246 - int n = edge.id;
181.247 -
181.248 - if(edges[n].next_in!=-1) {
181.249 - edges[edges[n].next_in].prev_in = edges[n].prev_in;
181.250 - }
181.251 -
181.252 - if(edges[n].prev_in!=-1) {
181.253 - edges[edges[n].prev_in].next_in = edges[n].next_in;
181.254 - } else {
181.255 - nodes[edges[n].target].first_in = edges[n].next_in;
181.256 - }
181.257 -
181.258 -
181.259 - if(edges[n].next_out!=-1) {
181.260 - edges[edges[n].next_out].prev_out = edges[n].prev_out;
181.261 - }
181.262 -
181.263 - if(edges[n].prev_out!=-1) {
181.264 - edges[edges[n].prev_out].next_out = edges[n].next_out;
181.265 - } else {
181.266 - nodes[edges[n].source].first_out = edges[n].next_out;
181.267 - }
181.268 -
181.269 - edges[n].next_in = first_free_edge;
181.270 - first_free_edge = n;
181.271 -
181.272 - }
181.273 -
181.274 - void clear() {
181.275 - edges.clear();
181.276 - nodes.clear();
181.277 - first_node = first_free_node = first_free_edge = -1;
181.278 - }
181.279 -
181.280 - protected:
181.281 - void _moveTarget(Edge e, Node n)
181.282 - {
181.283 - if(edges[e.id].next_in != -1)
181.284 - edges[edges[e.id].next_in].prev_in = edges[e.id].prev_in;
181.285 - if(edges[e.id].prev_in != -1)
181.286 - edges[edges[e.id].prev_in].next_in = edges[e.id].next_in;
181.287 - else nodes[edges[e.id].target].first_in = edges[e.id].next_in;
181.288 - edges[e.id].target = n.id;
181.289 - edges[e.id].prev_in = -1;
181.290 - edges[e.id].next_in = nodes[n.id].first_in;
181.291 - nodes[n.id].first_in = e.id;
181.292 - }
181.293 - void _moveSource(Edge e, Node n)
181.294 - {
181.295 - if(edges[e.id].next_out != -1)
181.296 - edges[edges[e.id].next_out].prev_out = edges[e.id].prev_out;
181.297 - if(edges[e.id].prev_out != -1)
181.298 - edges[edges[e.id].prev_out].next_out = edges[e.id].next_out;
181.299 - else nodes[edges[e.id].source].first_out = edges[e.id].next_out;
181.300 - edges[e.id].source = n.id;
181.301 - edges[e.id].prev_out = -1;
181.302 - edges[e.id].next_out = nodes[n.id].first_out;
181.303 - nodes[n.id].first_out = e.id;
181.304 - }
181.305 -
181.306 - };
181.307 -
181.308 - typedef AlterableGraphExtender<ListGraphBase> AlterableListGraphBase;
181.309 - typedef IterableGraphExtender<AlterableListGraphBase> IterableListGraphBase;
181.310 - typedef DefaultMappableGraphExtender<IterableListGraphBase> MappableListGraphBase;
181.311 - typedef ExtendableGraphExtender<MappableListGraphBase> ExtendableListGraphBase;
181.312 - typedef ClearableGraphExtender<ExtendableListGraphBase> ClearableListGraphBase;
181.313 - typedef ErasableGraphExtender<ClearableListGraphBase> ErasableListGraphBase;
181.314 -
181.315 -/// \addtogroup graphs
181.316 -/// @{
181.317 -
181.318 - ///A list graph class.
181.319 -
181.320 - ///This is a simple and fast erasable graph implementation.
181.321 - ///
181.322 - ///It addition that it conforms to the
181.323 - ///\ref concept::ErasableGraph "ErasableGraph" concept,
181.324 - ///it also provides several additional useful extra functionalities.
181.325 - ///\sa concept::ErasableGraph.
181.326 -
181.327 - class ListGraph : public ErasableListGraphBase
181.328 - {
181.329 - public:
181.330 - /// Moves the target of \c e to \c n
181.331 -
181.332 - /// Moves the target of \c e to \c n
181.333 - ///
181.334 - ///\note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
181.335 - ///referencing the moved edge remain
181.336 - ///valid. However <tt>InEdge</tt>'s are invalidated.
181.337 - void moveTarget(Edge e, Node n) { _moveTarget(e,n); }
181.338 - /// Moves the source of \c e to \c n
181.339 -
181.340 - /// Moves the source of \c e to \c n
181.341 - ///
181.342 - ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
181.343 - ///referencing the moved edge remain
181.344 - ///valid. However <tt>OutEdge</tt>'s are invalidated.
181.345 - void moveSource(Edge e, Node n) { _moveSource(e,n); }
181.346 -
181.347 - /// Invert the direction of an edge.
181.348 -
181.349 - ///\note The <tt>Edge</tt>'s
181.350 - ///referencing the moved edge remain
181.351 - ///valid. However <tt>OutEdge</tt>'s and <tt>InEdge</tt>'s are invalidated.
181.352 - void reverseEdge(Edge e) {
181.353 - Node t=target(e);
181.354 - _moveTarget(e,source(e));
181.355 - _moveSource(e,t);
181.356 - }
181.357 -
181.358 - ///Using this it possible to avoid the superfluous memory allocation.
181.359 -
181.360 - ///Using this it possible to avoid the superfluous memory allocation.
181.361 - ///\todo more docs...
181.362 - void reserveEdge(int n) { edges.reserve(n); };
181.363 -
181.364 - ///Contract two nodes.
181.365 -
181.366 - ///This function contracts two nodes.
181.367 - ///
181.368 - ///Node \p b will be removed but instead of deleting
181.369 - ///its neighboring edges, they will be joined to \p a.
181.370 - ///The last parameter \p r controls whether to remove loops. \c true
181.371 - ///means that loops will be removed.
181.372 - ///
181.373 - ///\note The <tt>Edge</tt>s
181.374 - ///referencing a moved edge remain
181.375 - ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
181.376 - ///may be invalidated.
181.377 - void contract(Node a,Node b,bool r=true)
181.378 - {
181.379 - for(OutEdgeIt e(*this,b);e!=INVALID;) {
181.380 - OutEdgeIt f=e;
181.381 - ++f;
181.382 - if(r && target(e)==a) erase(e);
181.383 - else moveSource(e,a);
181.384 - e=f;
181.385 - }
181.386 - for(InEdgeIt e(*this,b);e!=INVALID;) {
181.387 - InEdgeIt f=e;
181.388 - ++f;
181.389 - if(r && source(e)==a) erase(e);
181.390 - else moveTarget(e,a);
181.391 - e=f;
181.392 - }
181.393 - erase(b);
181.394 - }
181.395 -
181.396 - ///Split a node.
181.397 -
181.398 - ///This function splits a node. First a new node is added to the graph,
181.399 - ///then the source of each outgoing edge of \c n is moved to this new node.
181.400 - ///If \c connect is \c true (this is the default value), then a new edge
181.401 - ///from \c n to the newly created node is also added.
181.402 - ///\return The newly created node.
181.403 - ///
181.404 - ///\note The <tt>Edge</tt>s
181.405 - ///referencing a moved edge remain
181.406 - ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
181.407 - ///may be invalidated.
181.408 - ///\warning This functionality cannot be used together with the SnapShot
181.409 - ///feature.
181.410 - ///\todo It could be implemented in a bit faster way.
181.411 - Node split(Node n, bool connect = true)
181.412 - {
181.413 - Node b = addNode();
181.414 - for(OutEdgeIt e(*this,n);e!=INVALID;) {
181.415 - OutEdgeIt f=e;
181.416 - ++f;
181.417 - moveSource(e,b);
181.418 - e=f;
181.419 - }
181.420 - if(connect) addEdge(n,b);
181.421 - return b;
181.422 - }
181.423 -
181.424 - ///Class to make a snapshot of the graph and to restrore to it later.
181.425 -
181.426 - ///Class to make a snapshot of the graph and to restrore to it later.
181.427 - ///
181.428 - ///The newly added nodes and edges can be removed using the
181.429 - ///restore() function.
181.430 - ///
181.431 - ///\warning Edge and node deletions cannot be restored.
181.432 - ///\warning SnapShots cannot be nested.
181.433 - ///\todo \c SnapShot or \c Snapshot?
181.434 - class SnapShot : protected AlterationNotifier<Node>::ObserverBase,
181.435 - protected AlterationNotifier<Edge>::ObserverBase
181.436 - {
181.437 - protected:
181.438 -
181.439 - ListGraph *g;
181.440 - std::list<Node> added_nodes;
181.441 - std::list<Edge> added_edges;
181.442 -
181.443 - bool active;
181.444 - virtual void add(const Node& n) {
181.445 - added_nodes.push_back(n);
181.446 - };
181.447 - ///\bug Exception...
181.448 - ///
181.449 - virtual void erase(const Node&)
181.450 - {
181.451 - exit(1);
181.452 - }
181.453 - virtual void add(const Edge& n) {
181.454 - added_edges.push_back(n);
181.455 - };
181.456 - ///\bug Exception...
181.457 - ///
181.458 - virtual void erase(const Edge&)
181.459 - {
181.460 - exit(1);
181.461 - }
181.462 -
181.463 - void regist(ListGraph &_g) {
181.464 - g=&_g;
181.465 - AlterationNotifier<Node>::ObserverBase::
181.466 - attach(g->getNotifier(Node()));
181.467 - AlterationNotifier<Edge>::ObserverBase::
181.468 - attach(g->getNotifier(Edge()));
181.469 - }
181.470 -
181.471 - void deregist() {
181.472 - AlterationNotifier<Node>::ObserverBase::
181.473 - detach();
181.474 - AlterationNotifier<Edge>::ObserverBase::
181.475 - detach();
181.476 - g=0;
181.477 - }
181.478 -
181.479 - public:
181.480 - ///Default constructur.
181.481 -
181.482 - ///Default constructur.
181.483 - ///To actually make a snapshot you must call save().
181.484 - ///
181.485 - SnapShot() : g(0) {}
181.486 - ///Constructor that immediately makes a snapshot.
181.487 -
181.488 - ///This constructor immediately makes a snapshot of the graph.
181.489 - ///\param _g The graph we make a snapshot of.
181.490 - SnapShot(ListGraph &_g) {
181.491 - regist(_g);
181.492 - }
181.493 - ///\bug Is it necessary?
181.494 - ///
181.495 - ~SnapShot()
181.496 - {
181.497 - if(g) deregist();
181.498 - }
181.499 -
181.500 - ///Make a snapshot.
181.501 -
181.502 - ///Make a snapshot of the graph.
181.503 - ///
181.504 - ///This function can be called more than once. In case of a repeated
181.505 - ///call, the previous snapshot gets lost.
181.506 - ///\param _g The graph we make the snapshot of.
181.507 - void save(ListGraph &_g)
181.508 - {
181.509 - if(g!=&_g) {
181.510 - if(g) deregist();
181.511 - regist(_g);
181.512 - }
181.513 - added_nodes.clear();
181.514 - added_edges.clear();
181.515 - }
181.516 -
181.517 - ///Undo the changes until the last snapshot.
181.518 -
181.519 - ///Undo the changes until last snapshot created by save().
181.520 - ///
181.521 - ///\todo This function might be called undo().
181.522 - void restore() {
181.523 - deregist();
181.524 - while(!added_edges.empty()) {
181.525 - g->erase(added_edges.front());
181.526 - added_edges.pop_front();
181.527 - }
181.528 - while(!added_nodes.empty()) {
181.529 - g->erase(added_nodes.front());
181.530 - added_nodes.pop_front();
181.531 - }
181.532 - }
181.533 - };
181.534 -
181.535 - };
181.536 -
181.537 -
181.538 - /**************** Undirected List Graph ****************/
181.539 -
181.540 - typedef ErasableUndirGraphExtender<
181.541 - ClearableUndirGraphExtender<
181.542 - ExtendableUndirGraphExtender<
181.543 - MappableUndirGraphExtender<
181.544 - IterableUndirGraphExtender<
181.545 - AlterableUndirGraphExtender<
181.546 - UndirGraphExtender<ListGraphBase> > > > > > > ErasableUndirListGraphBase;
181.547 -
181.548 - ///An undirected list graph class.
181.549 -
181.550 - ///This is a simple and fast erasable undirected graph implementation.
181.551 - ///
181.552 - ///It conforms to the
181.553 - ///\ref concept::UndirGraph "UndirGraph" concept.
181.554 - ///
181.555 - ///\sa concept::UndirGraph.
181.556 - ///
181.557 - ///\todo SnapShot, reverseEdge(), moveTarget(), moveSource(), contract()
181.558 - ///haven't been implemented yet.
181.559 - ///
181.560 - class UndirListGraph : public ErasableUndirListGraphBase {
181.561 - };
181.562 -
181.563 -
181.564 - /// @}
181.565 -} //namespace lemon
181.566 -
181.567 -
181.568 -#endif
182.1 --- a/src/lemon/lp_base.cc Sat May 21 21:04:57 2005 +0000
182.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
182.3 @@ -1,33 +0,0 @@
182.4 -/* -*- C++ -*-
182.5 - * src/lib/lp_base.cc - Part of LEMON, a generic C++ optimization library
182.6 - *
182.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
182.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
182.9 - *
182.10 - * Permission to use, modify and distribute this software is granted
182.11 - * provided that this copyright notice appears in all copies. For
182.12 - * precise terms see the accompanying LICENSE file.
182.13 - *
182.14 - * This software is provided "AS IS" with no warranty of any kind,
182.15 - * express or implied, and with no claim as to its suitability for any
182.16 - * purpose.
182.17 - *
182.18 - */
182.19 -
182.20 -///\file
182.21 -///\brief The implementation of the LP solver interface.
182.22 -
182.23 -#include <lemon/lp_base.h>
182.24 -namespace lemon {
182.25 -
182.26 - const LpSolverBase::Value
182.27 - LpSolverBase::INF = std::numeric_limits<Value>::infinity();
182.28 - const LpSolverBase::Value
182.29 - LpSolverBase::NaN = std::numeric_limits<Value>::quiet_NaN();
182.30 -
182.31 -// const LpSolverBase::Constr::Value
182.32 -// LpSolverBase::Constr::INF = std::numeric_limits<Value>::infinity();
182.33 -// const LpSolverBase::Constr::Value
182.34 -// LpSolverBase::Constr::NaN = std::numeric_limits<Value>::quiet_NaN();
182.35 -
182.36 -} //namespace lemon
183.1 --- a/src/lemon/lp_base.h Sat May 21 21:04:57 2005 +0000
183.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
183.3 @@ -1,907 +0,0 @@
183.4 -/* -*- C++ -*-
183.5 - * src/lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
183.6 - *
183.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
183.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
183.9 - *
183.10 - * Permission to use, modify and distribute this software is granted
183.11 - * provided that this copyright notice appears in all copies. For
183.12 - * precise terms see the accompanying LICENSE file.
183.13 - *
183.14 - * This software is provided "AS IS" with no warranty of any kind,
183.15 - * express or implied, and with no claim as to its suitability for any
183.16 - * purpose.
183.17 - *
183.18 - */
183.19 -
183.20 -#ifndef LEMON_LP_BASE_H
183.21 -#define LEMON_LP_BASE_H
183.22 -
183.23 -#include<vector>
183.24 -#include<map>
183.25 -#include<limits>
183.26 -#include<cmath>
183.27 -
183.28 -#include<lemon/utility.h>
183.29 -#include<lemon/error.h>
183.30 -#include<lemon/invalid.h>
183.31 -
183.32 -//#include"lin_expr.h"
183.33 -
183.34 -///\file
183.35 -///\brief The interface of the LP solver interface.
183.36 -///\ingroup gen_opt_group
183.37 -namespace lemon {
183.38 -
183.39 - ///Internal data structure to convert floating id's to fix one's
183.40 -
183.41 - ///\todo This might be implemented to be also usable in other places.
183.42 - class _FixId
183.43 - {
183.44 - std::vector<int> index;
183.45 - std::vector<int> cross;
183.46 - int first_free;
183.47 - public:
183.48 - _FixId() : first_free(-1) {};
183.49 - ///Convert a floating id to a fix one
183.50 -
183.51 - ///\param n is a floating id
183.52 - ///\return the corresponding fix id
183.53 - int fixId(int n) {return cross[n];}
183.54 - ///Convert a fix id to a floating one
183.55 -
183.56 - ///\param n is a fix id
183.57 - ///\return the corresponding floating id
183.58 - int floatingId(int n) { return index[n];}
183.59 - ///Add a new floating id.
183.60 -
183.61 - ///\param n is a floating id
183.62 - ///\return the fix id of the new value
183.63 - ///\todo Multiple additions should also be handled.
183.64 - int insert(int n)
183.65 - {
183.66 - if(n>=int(cross.size())) {
183.67 - cross.resize(n+1);
183.68 - if(first_free==-1) {
183.69 - cross[n]=index.size();
183.70 - index.push_back(n);
183.71 - }
183.72 - else {
183.73 - cross[n]=first_free;
183.74 - int next=index[first_free];
183.75 - index[first_free]=n;
183.76 - first_free=next;
183.77 - }
183.78 - return cross[n];
183.79 - }
183.80 - ///\todo Create an own exception type.
183.81 - else throw LogicError(); //floatingId-s must form a continuous range;
183.82 - }
183.83 - ///Remove a fix id.
183.84 -
183.85 - ///\param n is a fix id
183.86 - ///
183.87 - void erase(int n)
183.88 - {
183.89 - int fl=index[n];
183.90 - index[n]=first_free;
183.91 - first_free=n;
183.92 - for(int i=fl+1;i<int(cross.size());++i) {
183.93 - cross[i-1]=cross[i];
183.94 - index[cross[i]]--;
183.95 - }
183.96 - cross.pop_back();
183.97 - }
183.98 - ///An upper bound on the largest fix id.
183.99 -
183.100 - ///\todo Do we need this?
183.101 - ///
183.102 - std::size_t maxFixId() { return cross.size()-1; }
183.103 -
183.104 - };
183.105 -
183.106 - ///Common base class for LP solvers
183.107 -
183.108 - ///\todo Much more docs
183.109 - ///\ingroup gen_opt_group
183.110 - class LpSolverBase {
183.111 -
183.112 - public:
183.113 -
183.114 - ///\e
183.115 - enum SolveExitStatus {
183.116 - ///\e
183.117 - SOLVED = 0,
183.118 - ///\e
183.119 - UNSOLVED = 1
183.120 - };
183.121 -
183.122 - ///\e
183.123 - enum SolutionStatus {
183.124 - ///Feasible solution has'n been found (but may exist).
183.125 -
183.126 - ///\todo NOTFOUND might be a better name.
183.127 - ///
183.128 - UNDEFINED = 0,
183.129 - ///The problem has no feasible solution
183.130 - INFEASIBLE = 1,
183.131 - ///Feasible solution found
183.132 - FEASIBLE = 2,
183.133 - ///Optimal solution exists and found
183.134 - OPTIMAL = 3,
183.135 - ///The cost function is unbounded
183.136 -
183.137 - ///\todo Give a feasible solution and an infinite ray (and the
183.138 - ///corresponding bases)
183.139 - INFINITE = 4
183.140 - };
183.141 -
183.142 - ///The floating point type used by the solver
183.143 - typedef double Value;
183.144 - ///The infinity constant
183.145 - static const Value INF;
183.146 - ///The not a number constant
183.147 - static const Value NaN;
183.148 -
183.149 - ///Refer to a column of the LP.
183.150 -
183.151 - ///This type is used to refer to a column of the LP.
183.152 - ///
183.153 - ///Its value remains valid and correct even after the addition or erase of
183.154 - ///other columns.
183.155 - ///
183.156 - ///\todo Document what can one do with a Col (INVALID, comparing,
183.157 - ///it is similar to Node/Edge)
183.158 - class Col {
183.159 - protected:
183.160 - int id;
183.161 - friend class LpSolverBase;
183.162 - public:
183.163 - typedef Value ExprValue;
183.164 - typedef True LpSolverCol;
183.165 - Col() {}
183.166 - Col(const Invalid&) : id(-1) {}
183.167 - bool operator<(Col c) const {return id<c.id;}
183.168 - bool operator==(Col c) const {return id==c.id;}
183.169 - bool operator!=(Col c) const {return id==c.id;}
183.170 - };
183.171 -
183.172 - ///Refer to a row of the LP.
183.173 -
183.174 - ///This type is used to refer to a row of the LP.
183.175 - ///
183.176 - ///Its value remains valid and correct even after the addition or erase of
183.177 - ///other rows.
183.178 - ///
183.179 - ///\todo Document what can one do with a Row (INVALID, comparing,
183.180 - ///it is similar to Node/Edge)
183.181 - class Row {
183.182 - protected:
183.183 - int id;
183.184 - friend class LpSolverBase;
183.185 - public:
183.186 - typedef Value ExprValue;
183.187 - typedef True LpSolverRow;
183.188 - Row() {}
183.189 - Row(const Invalid&) : id(-1) {}
183.190 - typedef True LpSolverRow;
183.191 - bool operator<(Row c) const {return id<c.id;}
183.192 - bool operator==(Row c) const {return id==c.id;}
183.193 - bool operator!=(Row c) const {return id==c.id;}
183.194 - };
183.195 -
183.196 - ///Linear expression of variables and a constant component
183.197 -
183.198 - ///This data structure strores a linear expression of the variables
183.199 - ///(\ref Col "Col"s) and also has a constant component.
183.200 - ///
183.201 - ///There are several ways to access and modify the contents of this
183.202 - ///container.
183.203 - ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
183.204 - ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
183.205 - ///read and modify the coefficients like
183.206 - ///these.
183.207 - ///\code
183.208 - ///e[v]=5;
183.209 - ///e[v]+=12;
183.210 - ///e.erase(v);
183.211 - ///\endcode
183.212 - ///or you can also iterate through its elements.
183.213 - ///\code
183.214 - ///double s=0;
183.215 - ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
183.216 - /// s+=i->second;
183.217 - ///\endcode
183.218 - ///(This code computes the sum of all coefficients).
183.219 - ///- Numbers (<tt>double</tt>'s)
183.220 - ///and variables (\ref Col "Col"s) directly convert to an
183.221 - ///\ref Expr and the usual linear operations are defined so
183.222 - ///\code
183.223 - ///v+w
183.224 - ///2*v-3.12*(v-w/2)+2
183.225 - ///v*2.1+(3*v+(v*12+w+6)*3)/2
183.226 - ///\endcode
183.227 - ///are valid \ref Expr "Expr"essions.
183.228 - ///The usual assignment operations are also defined.
183.229 - ///\code
183.230 - ///e=v+w;
183.231 - ///e+=2*v-3.12*(v-w/2)+2;
183.232 - ///e*=3.4;
183.233 - ///e/=5;
183.234 - ///\endcode
183.235 - ///- The constant member can be set and read by \ref constComp()
183.236 - ///\code
183.237 - ///e.constComp()=12;
183.238 - ///double c=e.constComp();
183.239 - ///\endcode
183.240 - ///
183.241 - ///\note \ref clear() not only sets all coefficients to 0 but also
183.242 - ///clears the constant components.
183.243 - ///
183.244 - ///\sa Constr
183.245 - ///
183.246 - class Expr : public std::map<Col,Value>
183.247 - {
183.248 - public:
183.249 - typedef LpSolverBase::Col Key;
183.250 - typedef LpSolverBase::Value Value;
183.251 -
183.252 - protected:
183.253 - typedef std::map<Col,Value> Base;
183.254 -
183.255 - Value const_comp;
183.256 - public:
183.257 - typedef True IsLinExpression;
183.258 - ///\e
183.259 - Expr() : Base(), const_comp(0) { }
183.260 - ///\e
183.261 - Expr(const Key &v) : const_comp(0) {
183.262 - Base::insert(std::make_pair(v, 1));
183.263 - }
183.264 - ///\e
183.265 - Expr(const Value &v) : const_comp(v) {}
183.266 - ///\e
183.267 - void set(const Key &v,const Value &c) {
183.268 - Base::insert(std::make_pair(v, c));
183.269 - }
183.270 - ///\e
183.271 - Value &constComp() { return const_comp; }
183.272 - ///\e
183.273 - const Value &constComp() const { return const_comp; }
183.274 -
183.275 - ///Removes the components with zero coefficient.
183.276 - void simplify() {
183.277 - for (Base::iterator i=Base::begin(); i!=Base::end();) {
183.278 - Base::iterator j=i;
183.279 - ++j;
183.280 - if ((*i).second==0) Base::erase(i);
183.281 - j=i;
183.282 - }
183.283 - }
183.284 -
183.285 - ///Sets all coefficients and the constant component to 0.
183.286 - void clear() {
183.287 - Base::clear();
183.288 - const_comp=0;
183.289 - }
183.290 -
183.291 - ///\e
183.292 - Expr &operator+=(const Expr &e) {
183.293 - for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
183.294 - (*this)[j->first]+=j->second;
183.295 - ///\todo it might be speeded up using "hints"
183.296 - const_comp+=e.const_comp;
183.297 - return *this;
183.298 - }
183.299 - ///\e
183.300 - Expr &operator-=(const Expr &e) {
183.301 - for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
183.302 - (*this)[j->first]-=j->second;
183.303 - const_comp-=e.const_comp;
183.304 - return *this;
183.305 - }
183.306 - ///\e
183.307 - Expr &operator*=(const Value &c) {
183.308 - for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
183.309 - j->second*=c;
183.310 - const_comp*=c;
183.311 - return *this;
183.312 - }
183.313 - ///\e
183.314 - Expr &operator/=(const Value &c) {
183.315 - for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
183.316 - j->second/=c;
183.317 - const_comp/=c;
183.318 - return *this;
183.319 - }
183.320 - };
183.321 -
183.322 - ///Linear constraint
183.323 -
183.324 - ///This data stucture represents a linear constraint in the LP.
183.325 - ///Basically it is a linear expression with a lower or an upper bound
183.326 - ///(or both). These parts of the constraint can be obtained by the member
183.327 - ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
183.328 - ///respectively.
183.329 - ///There are two ways to construct a constraint.
183.330 - ///- You can set the linear expression and the bounds directly
183.331 - /// by the functions above.
183.332 - ///- The operators <tt>\<=</tt>, <tt>==</tt> and <tt>\>=</tt>
183.333 - /// are defined between expressions, or even between constraints whenever
183.334 - /// it makes sense. Therefore if \c e and \c f are linear expressions and
183.335 - /// \c s and \c t are numbers, then the followings are valid expressions
183.336 - /// and thus they can be used directly e.g. in \ref addRow() whenever
183.337 - /// it makes sense.
183.338 - /// \code
183.339 - /// e<=s
183.340 - /// e<=f
183.341 - /// s<=e<=t
183.342 - /// e>=t
183.343 - /// \endcode
183.344 - ///\warning The validity of a constraint is checked only at run time, so
183.345 - ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
183.346 - ///\ref LogicError exception.
183.347 - class Constr
183.348 - {
183.349 - public:
183.350 - typedef LpSolverBase::Expr Expr;
183.351 - typedef Expr::Key Key;
183.352 - typedef Expr::Value Value;
183.353 -
183.354 -// static const Value INF;
183.355 -// static const Value NaN;
183.356 -
183.357 - protected:
183.358 - Expr _expr;
183.359 - Value _lb,_ub;
183.360 - public:
183.361 - ///\e
183.362 - Constr() : _expr(), _lb(NaN), _ub(NaN) {}
183.363 - ///\e
183.364 - Constr(Value lb,const Expr &e,Value ub) :
183.365 - _expr(e), _lb(lb), _ub(ub) {}
183.366 - ///\e
183.367 - Constr(const Expr &e,Value ub) :
183.368 - _expr(e), _lb(NaN), _ub(ub) {}
183.369 - ///\e
183.370 - Constr(Value lb,const Expr &e) :
183.371 - _expr(e), _lb(lb), _ub(NaN) {}
183.372 - ///\e
183.373 - Constr(const Expr &e) :
183.374 - _expr(e), _lb(NaN), _ub(NaN) {}
183.375 - ///\e
183.376 - void clear()
183.377 - {
183.378 - _expr.clear();
183.379 - _lb=_ub=NaN;
183.380 - }
183.381 -
183.382 - ///Reference to the linear expression
183.383 - Expr &expr() { return _expr; }
183.384 - ///Cont reference to the linear expression
183.385 - const Expr &expr() const { return _expr; }
183.386 - ///Reference to the lower bound.
183.387 -
183.388 - ///\return
183.389 - ///- -\ref INF: the constraint is lower unbounded.
183.390 - ///- -\ref NaN: lower bound has not been set.
183.391 - ///- finite number: the lower bound
183.392 - Value &lowerBound() { return _lb; }
183.393 - ///The const version of \ref lowerBound()
183.394 - const Value &lowerBound() const { return _lb; }
183.395 - ///Reference to the upper bound.
183.396 -
183.397 - ///\return
183.398 - ///- -\ref INF: the constraint is upper unbounded.
183.399 - ///- -\ref NaN: upper bound has not been set.
183.400 - ///- finite number: the upper bound
183.401 - Value &upperBound() { return _ub; }
183.402 - ///The const version of \ref upperBound()
183.403 - const Value &upperBound() const { return _ub; }
183.404 - ///Is the constraint lower bounded?
183.405 - bool lowerBounded() const {
183.406 - using namespace std;
183.407 - return finite(_lb);
183.408 - }
183.409 - ///Is the constraint upper bounded?
183.410 - bool upperBounded() const {
183.411 - using namespace std;
183.412 - return finite(_ub);
183.413 - }
183.414 - };
183.415 -
183.416 -
183.417 - protected:
183.418 - _FixId rows;
183.419 - _FixId cols;
183.420 -
183.421 - //Abstract virtual functions
183.422 - virtual LpSolverBase &_newLp() = 0;
183.423 - virtual LpSolverBase &_copyLp() = 0;
183.424 -
183.425 - virtual int _addCol() = 0;
183.426 - virtual int _addRow() = 0;
183.427 - virtual void _setRowCoeffs(int i,
183.428 - int length,
183.429 - int const * indices,
183.430 - Value const * values ) = 0;
183.431 - virtual void _setColCoeffs(int i,
183.432 - int length,
183.433 - int const * indices,
183.434 - Value const * values ) = 0;
183.435 - virtual void _setCoeff(int row, int col, Value value) = 0;
183.436 - virtual void _setColLowerBound(int i, Value value) = 0;
183.437 - virtual void _setColUpperBound(int i, Value value) = 0;
183.438 -// virtual void _setRowLowerBound(int i, Value value) = 0;
183.439 -// virtual void _setRowUpperBound(int i, Value value) = 0;
183.440 - virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
183.441 - virtual void _setObjCoeff(int i, Value obj_coef) = 0;
183.442 - virtual void _clearObj()=0;
183.443 -// virtual void _setObj(int length,
183.444 -// int const * indices,
183.445 -// Value const * values ) = 0;
183.446 - virtual SolveExitStatus _solve() = 0;
183.447 - virtual Value _getPrimal(int i) = 0;
183.448 - virtual Value _getPrimalValue() = 0;
183.449 - virtual SolutionStatus _getPrimalStatus() = 0;
183.450 - virtual void _setMax() = 0;
183.451 - virtual void _setMin() = 0;
183.452 -
183.453 - //Own protected stuff
183.454 -
183.455 - //Constant component of the objective function
183.456 - Value obj_const_comp;
183.457 -
183.458 -
183.459 -
183.460 -
183.461 - public:
183.462 -
183.463 - ///\e
183.464 - LpSolverBase() : obj_const_comp(0) {}
183.465 -
183.466 - ///\e
183.467 - virtual ~LpSolverBase() {}
183.468 -
183.469 - ///Creates a new LP problem
183.470 - LpSolverBase &newLp() {return _newLp();}
183.471 - ///Makes a copy of the LP problem
183.472 - LpSolverBase ©Lp() {return _copyLp();}
183.473 -
183.474 - ///\name Build up and modify of the LP
183.475 -
183.476 - ///@{
183.477 -
183.478 - ///Add a new empty column (i.e a new variable) to the LP
183.479 - Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
183.480 -
183.481 - ///\brief Adds several new columns
183.482 - ///(i.e a variables) at once
183.483 - ///
183.484 - ///This magic function takes a container as its argument
183.485 - ///and fills its elements
183.486 - ///with new columns (i.e. variables)
183.487 - ///\param t can be
183.488 - ///- a standard STL compatible iterable container with
183.489 - ///\ref Col as its \c values_type
183.490 - ///like
183.491 - ///\code
183.492 - ///std::vector<LpSolverBase::Col>
183.493 - ///std::list<LpSolverBase::Col>
183.494 - ///\endcode
183.495 - ///- a standard STL compatible iterable container with
183.496 - ///\ref Col as its \c mapped_type
183.497 - ///like
183.498 - ///\code
183.499 - ///std::map<AnyType,LpSolverBase::Col>
183.500 - ///\endcode
183.501 - ///- an iterable lemon \ref concept::WriteMap "write map" like
183.502 - ///\code
183.503 - ///ListGraph::NodeMap<LpSolverBase::Col>
183.504 - ///ListGraph::EdgeMap<LpSolverBase::Col>
183.505 - ///\endcode
183.506 - ///\return The number of the created column.
183.507 -#ifdef DOXYGEN
183.508 - template<class T>
183.509 - int addColSet(T &t) { return 0;}
183.510 -#else
183.511 - template<class T>
183.512 - typename enable_if<typename T::value_type::LpSolverCol,int>::type
183.513 - addColSet(T &t,dummy<0> = 0) {
183.514 - int s=0;
183.515 - for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
183.516 - return s;
183.517 - }
183.518 - template<class T>
183.519 - typename enable_if<typename T::value_type::second_type::LpSolverCol,
183.520 - int>::type
183.521 - addColSet(T &t,dummy<1> = 1) {
183.522 - int s=0;
183.523 - for(typename T::iterator i=t.begin();i!=t.end();++i) {
183.524 - i->second=addCol();
183.525 - s++;
183.526 - }
183.527 - return s;
183.528 - }
183.529 - template<class T>
183.530 - typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
183.531 - int>::type
183.532 - addColSet(T &t,dummy<2> = 2) {
183.533 - ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
183.534 - int s=0;
183.535 - for(typename T::ValueSet::iterator i=t.valueSet().begin();
183.536 - i!=t.valueSet().end();
183.537 - ++i)
183.538 - {
183.539 - *i=addCol();
183.540 - s++;
183.541 - }
183.542 - return s;
183.543 - }
183.544 -#endif
183.545 -
183.546 - ///Add a new empty row (i.e a new constaint) to the LP
183.547 -
183.548 - ///This function adds a new empty row (i.e a new constaint) to the LP.
183.549 - ///\return The created row
183.550 - Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
183.551 -
183.552 - ///Set a row (i.e a constaint) of the LP
183.553 -
183.554 - ///\param r is the row to be modified
183.555 - ///\param l is lower bound (-\ref INF means no bound)
183.556 - ///\param e is a linear expression (see \ref Expr)
183.557 - ///\param u is the upper bound (\ref INF means no bound)
183.558 - ///\bug This is a temportary function. The interface will change to
183.559 - ///a better one.
183.560 - ///\todo Option to control whether a constraint with a single variable is
183.561 - ///added or not.
183.562 - void setRow(Row r, Value l,const Expr &e, Value u) {
183.563 - std::vector<int> indices;
183.564 - std::vector<Value> values;
183.565 - indices.push_back(0);
183.566 - values.push_back(0);
183.567 - for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
183.568 - if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
183.569 - indices.push_back(cols.floatingId((*i).first.id));
183.570 - values.push_back((*i).second);
183.571 - }
183.572 - _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
183.573 - &indices[0],&values[0]);
183.574 -// _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
183.575 -// _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
183.576 - _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
183.577 - }
183.578 -
183.579 - ///Set a row (i.e a constaint) of the LP
183.580 -
183.581 - ///\param r is the row to be modified
183.582 - ///\param c is a linear expression (see \ref Constr)
183.583 - void setRow(Row r, const Constr &c) {
183.584 - setRow(r,
183.585 - c.lowerBounded()?c.lowerBound():-INF,
183.586 - c.expr(),
183.587 - c.upperBounded()?c.upperBound():INF);
183.588 - }
183.589 -
183.590 - ///Add a new row (i.e a new constaint) to the LP
183.591 -
183.592 - ///\param l is the lower bound (-\ref INF means no bound)
183.593 - ///\param e is a linear expression (see \ref Expr)
183.594 - ///\param u is the upper bound (\ref INF means no bound)
183.595 - ///\return The created row.
183.596 - ///\bug This is a temportary function. The interface will change to
183.597 - ///a better one.
183.598 - Row addRow(Value l,const Expr &e, Value u) {
183.599 - Row r=addRow();
183.600 - setRow(r,l,e,u);
183.601 - return r;
183.602 - }
183.603 -
183.604 - ///Add a new row (i.e a new constaint) to the LP
183.605 -
183.606 - ///\param c is a linear expression (see \ref Constr)
183.607 - ///\return The created row.
183.608 - Row addRow(const Constr &c) {
183.609 - Row r=addRow();
183.610 - setRow(r,c);
183.611 - return r;
183.612 - }
183.613 -
183.614 - /// Set the lower bound of a column (i.e a variable)
183.615 -
183.616 - /// The upper bound of a variable (column) has to be given by an
183.617 - /// extended number of type Value, i.e. a finite number of type
183.618 - /// Value or -\ref INF.
183.619 - void colLowerBound(Col c, Value value) {
183.620 - _setColLowerBound(cols.floatingId(c.id),value);
183.621 - }
183.622 - /// Set the upper bound of a column (i.e a variable)
183.623 -
183.624 - /// The upper bound of a variable (column) has to be given by an
183.625 - /// extended number of type Value, i.e. a finite number of type
183.626 - /// Value or \ref INF.
183.627 - void colUpperBound(Col c, Value value) {
183.628 - _setColUpperBound(cols.floatingId(c.id),value);
183.629 - };
183.630 - /// Set the lower and the upper bounds of a column (i.e a variable)
183.631 -
183.632 - /// The lower and the upper bounds of
183.633 - /// a variable (column) have to be given by an
183.634 - /// extended number of type Value, i.e. a finite number of type
183.635 - /// Value, -\ref INF or \ref INF.
183.636 - void colBounds(Col c, Value lower, Value upper) {
183.637 - _setColLowerBound(cols.floatingId(c.id),lower);
183.638 - _setColUpperBound(cols.floatingId(c.id),upper);
183.639 - }
183.640 -
183.641 -// /// Set the lower bound of a row (i.e a constraint)
183.642 -
183.643 -// /// The lower bound of a linear expression (row) has to be given by an
183.644 -// /// extended number of type Value, i.e. a finite number of type
183.645 -// /// Value or -\ref INF.
183.646 -// void rowLowerBound(Row r, Value value) {
183.647 -// _setRowLowerBound(rows.floatingId(r.id),value);
183.648 -// };
183.649 -// /// Set the upper bound of a row (i.e a constraint)
183.650 -
183.651 -// /// The upper bound of a linear expression (row) has to be given by an
183.652 -// /// extended number of type Value, i.e. a finite number of type
183.653 -// /// Value or \ref INF.
183.654 -// void rowUpperBound(Row r, Value value) {
183.655 -// _setRowUpperBound(rows.floatingId(r.id),value);
183.656 -// };
183.657 -
183.658 - /// Set the lower and the upper bounds of a row (i.e a constraint)
183.659 -
183.660 - /// The lower and the upper bounds of
183.661 - /// a constraint (row) have to be given by an
183.662 - /// extended number of type Value, i.e. a finite number of type
183.663 - /// Value, -\ref INF or \ref INF.
183.664 - void rowBounds(Row c, Value lower, Value upper) {
183.665 - _setRowBounds(rows.floatingId(c.id),lower, upper);
183.666 - // _setRowUpperBound(rows.floatingId(c.id),upper);
183.667 - }
183.668 -
183.669 - ///Set an element of the objective function
183.670 - void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
183.671 - ///Set the objective function
183.672 -
183.673 - ///\param e is a linear expression of type \ref Expr.
183.674 - ///\bug The previous objective function is not cleared!
183.675 - void setObj(Expr e) {
183.676 - _clearObj();
183.677 - for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
183.678 - objCoeff((*i).first,(*i).second);
183.679 - obj_const_comp=e.constComp();
183.680 - }
183.681 -
183.682 - ///Maximize
183.683 - void max() { _setMax(); }
183.684 - ///Minimize
183.685 - void min() { _setMin(); }
183.686 -
183.687 -
183.688 - ///@}
183.689 -
183.690 -
183.691 - ///\name Solve the LP
183.692 -
183.693 - ///@{
183.694 -
183.695 - ///\e
183.696 - SolveExitStatus solve() { return _solve(); }
183.697 -
183.698 - ///@}
183.699 -
183.700 - ///\name Obtain the solution
183.701 -
183.702 - ///@{
183.703 -
183.704 - ///\e
183.705 - SolutionStatus primalStatus() {
183.706 - return _getPrimalStatus();
183.707 - }
183.708 -
183.709 - ///\e
183.710 - Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
183.711 -
183.712 - ///\e
183.713 -
183.714 - ///\return
183.715 - ///- \ref INF or -\ref INF means either infeasibility or unboundedness
183.716 - /// of the primal problem, depending on whether we minimize or maximize.
183.717 - ///- \ref NaN if no primal solution is found.
183.718 - ///- The (finite) objective value if an optimal solution is found.
183.719 - Value primalValue() { return _getPrimalValue()+obj_const_comp;}
183.720 - ///@}
183.721 -
183.722 - };
183.723 -
183.724 - ///\e
183.725 -
183.726 - ///\relates LpSolverBase::Expr
183.727 - ///
183.728 - inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
183.729 - const LpSolverBase::Expr &b)
183.730 - {
183.731 - LpSolverBase::Expr tmp(a);
183.732 - tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
183.733 - return tmp;
183.734 - }
183.735 - ///\e
183.736 -
183.737 - ///\relates LpSolverBase::Expr
183.738 - ///
183.739 - inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
183.740 - const LpSolverBase::Expr &b)
183.741 - {
183.742 - LpSolverBase::Expr tmp(a);
183.743 - tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
183.744 - return tmp;
183.745 - }
183.746 - ///\e
183.747 -
183.748 - ///\relates LpSolverBase::Expr
183.749 - ///
183.750 - inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
183.751 - const LpSolverBase::Value &b)
183.752 - {
183.753 - LpSolverBase::Expr tmp(a);
183.754 - tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
183.755 - return tmp;
183.756 - }
183.757 -
183.758 - ///\e
183.759 -
183.760 - ///\relates LpSolverBase::Expr
183.761 - ///
183.762 - inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
183.763 - const LpSolverBase::Expr &b)
183.764 - {
183.765 - LpSolverBase::Expr tmp(b);
183.766 - tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
183.767 - return tmp;
183.768 - }
183.769 - ///\e
183.770 -
183.771 - ///\relates LpSolverBase::Expr
183.772 - ///
183.773 - inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
183.774 - const LpSolverBase::Value &b)
183.775 - {
183.776 - LpSolverBase::Expr tmp(a);
183.777 - tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
183.778 - return tmp;
183.779 - }
183.780 -
183.781 - ///\e
183.782 -
183.783 - ///\relates LpSolverBase::Constr
183.784 - ///
183.785 - inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
183.786 - const LpSolverBase::Expr &f)
183.787 - {
183.788 - return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
183.789 - }
183.790 -
183.791 - ///\e
183.792 -
183.793 - ///\relates LpSolverBase::Constr
183.794 - ///
183.795 - inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
183.796 - const LpSolverBase::Expr &f)
183.797 - {
183.798 - return LpSolverBase::Constr(e,f);
183.799 - }
183.800 -
183.801 - ///\e
183.802 -
183.803 - ///\relates LpSolverBase::Constr
183.804 - ///
183.805 - inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
183.806 - const LpSolverBase::Value &f)
183.807 - {
183.808 - return LpSolverBase::Constr(e,f);
183.809 - }
183.810 -
183.811 - ///\e
183.812 -
183.813 - ///\relates LpSolverBase::Constr
183.814 - ///
183.815 - inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
183.816 - const LpSolverBase::Expr &f)
183.817 - {
183.818 - return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
183.819 - }
183.820 -
183.821 -
183.822 - ///\e
183.823 -
183.824 - ///\relates LpSolverBase::Constr
183.825 - ///
183.826 - inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
183.827 - const LpSolverBase::Expr &f)
183.828 - {
183.829 - return LpSolverBase::Constr(f,e);
183.830 - }
183.831 -
183.832 -
183.833 - ///\e
183.834 -
183.835 - ///\relates LpSolverBase::Constr
183.836 - ///
183.837 - inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
183.838 - const LpSolverBase::Value &f)
183.839 - {
183.840 - return LpSolverBase::Constr(f,e);
183.841 - }
183.842 -
183.843 - ///\e
183.844 -
183.845 - ///\relates LpSolverBase::Constr
183.846 - ///
183.847 - inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
183.848 - const LpSolverBase::Expr &f)
183.849 - {
183.850 - return LpSolverBase::Constr(0,e-f,0);
183.851 - }
183.852 -
183.853 - ///\e
183.854 -
183.855 - ///\relates LpSolverBase::Constr
183.856 - ///
183.857 - inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
183.858 - const LpSolverBase::Constr&c)
183.859 - {
183.860 - LpSolverBase::Constr tmp(c);
183.861 - ///\todo Create an own exception type.
183.862 - if(!isnan(tmp.lowerBound())) throw LogicError();
183.863 - else tmp.lowerBound()=n;
183.864 - return tmp;
183.865 - }
183.866 - ///\e
183.867 -
183.868 - ///\relates LpSolverBase::Constr
183.869 - ///
183.870 - inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
183.871 - const LpSolverBase::Value &n)
183.872 - {
183.873 - LpSolverBase::Constr tmp(c);
183.874 - ///\todo Create an own exception type.
183.875 - if(!isnan(tmp.upperBound())) throw LogicError();
183.876 - else tmp.upperBound()=n;
183.877 - return tmp;
183.878 - }
183.879 -
183.880 - ///\e
183.881 -
183.882 - ///\relates LpSolverBase::Constr
183.883 - ///
183.884 - inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
183.885 - const LpSolverBase::Constr&c)
183.886 - {
183.887 - LpSolverBase::Constr tmp(c);
183.888 - ///\todo Create an own exception type.
183.889 - if(!isnan(tmp.upperBound())) throw LogicError();
183.890 - else tmp.upperBound()=n;
183.891 - return tmp;
183.892 - }
183.893 - ///\e
183.894 -
183.895 - ///\relates LpSolverBase::Constr
183.896 - ///
183.897 - inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
183.898 - const LpSolverBase::Value &n)
183.899 - {
183.900 - LpSolverBase::Constr tmp(c);
183.901 - ///\todo Create an own exception type.
183.902 - if(!isnan(tmp.lowerBound())) throw LogicError();
183.903 - else tmp.lowerBound()=n;
183.904 - return tmp;
183.905 - }
183.906 -
183.907 -
183.908 -} //namespace lemon
183.909 -
183.910 -#endif //LEMON_LP_BASE_H
184.1 --- a/src/lemon/lp_cplex.cc Sat May 21 21:04:57 2005 +0000
184.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
184.3 @@ -1,408 +0,0 @@
184.4 -/* -*- C++ -*-
184.5 - * src/lemon/lp_cplex.cc
184.6 - * - Part of LEMON, a generic C++ optimization library
184.7 - *
184.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
184.9 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
184.10 - *
184.11 - * Permission to use, modify and distribute this software is granted
184.12 - * provided that this copyright notice appears in all copies. For
184.13 - * precise terms see the accompanying LICENSE file.
184.14 - *
184.15 - * This software is provided "AS IS" with no warranty of any kind,
184.16 - * express or implied, and with no claim as to its suitability for any
184.17 - * purpose.
184.18 - *
184.19 - */
184.20 -#include <iostream>
184.21 -#include<lemon/lp_cplex.h>
184.22 -
184.23 -///\file
184.24 -///\brief Implementation of the LEMON-CPLEX lp solver interface.
184.25 -namespace lemon {
184.26 -
184.27 - LpCplex::LpCplex() : LpSolverBase() {
184.28 - env = NULL;
184.29 - lp = NULL;
184.30 - env = CPXopenCPLEXdevelop(&status);
184.31 -// if (Env == NULL)
184.32 -// {
184.33 -// fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
184.34 -// CPXgeterrorstring(Env, Status, ErrorMsg);
184.35 -// fprintf(stderr,"%s",ErrorMsg);
184.36 -// goto Terminate;
184.37 -// }
184.38 -
184.39 - // *** A problema létrehozása ***
184.40 - lp = CPXcreateprob(env, &status, "LP problem");
184.41 -
184.42 - // if (Problem == NULL)
184.43 -// {
184.44 -// fprintf(stderr,"Az LP létrehozása sikertelen");
184.45 -// goto Terminate;
184.46 -// }
184.47 -
184.48 - }
184.49 -
184.50 - LpCplex::~LpCplex() {
184.51 - status = CPXfreeprob(env,&lp);
184.52 - // if (Status != 0)
184.53 - // {
184.54 -// fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
184.55 -// CPXgeterrorstring(Env, Status, ErrorMsg);
184.56 -// fprintf(stderr,"%s",ErrorMsg);
184.57 -// goto Terminate;
184.58 -// }
184.59 -
184.60 - status = CPXcloseCPLEX(&env);
184.61 - // if (Status != 0)
184.62 - // {
184.63 - // fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
184.64 -// CPXgeterrorstring(Env, Status, ErrorMsg);
184.65 -// fprintf(stderr,"%s",ErrorMsg);
184.66 -// goto Terminate;
184.67 -// }
184.68 -
184.69 - }
184.70 -
184.71 - LpSolverBase &LpCplex::_newLp()
184.72 - {
184.73 - return *(LpSolverBase*)0;
184.74 - }
184.75 - LpSolverBase &LpCplex::_copyLp() {
184.76 - return *(LpSolverBase*)0;
184.77 - //Ez lesz majd CPXcloneprob (env, lp, &status);
184.78 - }
184.79 -
184.80 - int LpCplex::_addCol()
184.81 - {
184.82 - int i = CPXgetnumcols (env, lp);
184.83 - Value lb[1],ub[1];
184.84 - lb[0]=-INF;//-CPX_INFBOUND;
184.85 - ub[0]=INF;//CPX_INFBOUND;
184.86 - status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
184.87 - return i;
184.88 - }
184.89 -
184.90 - int LpCplex::_addRow()
184.91 - {
184.92 - //We want a row that is not constrained
184.93 - char sense[1];
184.94 - sense[0]='L';//<= constraint
184.95 - Value rhs[1];
184.96 - rhs[0]=INF;
184.97 - int i = CPXgetnumrows (env, lp);
184.98 - status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
184.99 - return i;
184.100 - }
184.101 -
184.102 -
184.103 - void LpCplex::_eraseCol(int i) {
184.104 - ///\todo Not implemented yet
184.105 - }
184.106 -
184.107 - void LpCplex::_eraseRow(int i) {
184.108 - ///\todo Not implemented yet
184.109 - }
184.110 -
184.111 -
184.112 - ///\warning Data at index 0 is ignored in the arrays.
184.113 - void LpCplex::_setRowCoeffs(int i,
184.114 - int length,
184.115 - int const * indices,
184.116 - Value const * values )
184.117 - {
184.118 - int rowlist[length+1];
184.119 - int* p=rowlist;
184.120 - for (int k=1;k<=length;++k){
184.121 - rowlist[k]=i;
184.122 - }
184.123 - status = CPXchgcoeflist(env, lp,
184.124 - length,
184.125 - p+1,
184.126 - const_cast<int * >(indices+1),
184.127 - const_cast<Value * >(values+1));
184.128 - }
184.129 -
184.130 - void LpCplex::_setColCoeffs(int i,
184.131 - int length,
184.132 - int const * indices,
184.133 - Value const * values)
184.134 - {
184.135 - int collist[length+1];
184.136 - int* p=collist;
184.137 - for (int k=1;k<=length;++k){
184.138 - collist[k]=i;
184.139 - }
184.140 - status = CPXchgcoeflist(env, lp,
184.141 - length,
184.142 - const_cast<int * >(indices+1),
184.143 - p+1,
184.144 - const_cast<Value * >(values+1));
184.145 - }
184.146 -
184.147 - void LpCplex::_setCoeff(int row, int col, Value value)
184.148 - {
184.149 - CPXchgcoef (env, lp, row, col, value);
184.150 - }
184.151 -
184.152 - void LpCplex::_setColLowerBound(int i, Value value)
184.153 - {
184.154 - int indices[1];
184.155 - indices[0]=i;
184.156 - char lu[1];
184.157 - lu[0]='L';
184.158 - Value bd[1];
184.159 - bd[0]=value;
184.160 - status = CPXchgbds (env, lp, 1, indices, lu, bd);
184.161 -
184.162 - }
184.163 -
184.164 - void LpCplex::_setColUpperBound(int i, Value value)
184.165 - {
184.166 - int indices[1];
184.167 - indices[0]=i;
184.168 - char lu[1];
184.169 - lu[0]='U';
184.170 - Value bd[1];
184.171 - bd[0]=value;
184.172 - status = CPXchgbds (env, lp, 1, indices, lu, bd);
184.173 - }
184.174 -
184.175 - //This will be easier to implement
184.176 - void LpCplex::_setRowBounds(int i, Value lb, Value ub)
184.177 - {
184.178 - //Bad parameter
184.179 - if (lb==INF || ub==-INF) {
184.180 - //FIXME error
184.181 - }
184.182 -
184.183 - int cnt=1;
184.184 - int indices[1];
184.185 - indices[0]=i;
184.186 - char sense[1];
184.187 -
184.188 - if (lb==-INF){
184.189 - sense[0]='L';
184.190 - CPXchgsense (env, lp, cnt, indices, sense);
184.191 - CPXchgcoef (env, lp, i, -1, ub);
184.192 -
184.193 - }
184.194 - else{
184.195 - if (ub==INF){
184.196 - sense[0]='G';
184.197 - CPXchgsense (env, lp, cnt, indices, sense);
184.198 - CPXchgcoef (env, lp, i, -1, lb);
184.199 - }
184.200 - else{
184.201 - if (lb == ub){
184.202 - sense[0]='E';
184.203 - CPXchgsense (env, lp, cnt, indices, sense);
184.204 - CPXchgcoef (env, lp, i, -1, lb);
184.205 - }
184.206 - else{
184.207 - sense[0]='R';
184.208 - CPXchgsense (env, lp, cnt, indices, sense);
184.209 - CPXchgcoef (env, lp, i, -1, lb);
184.210 - CPXchgcoef (env, lp, i, -2, ub-lb);
184.211 - }
184.212 - }
184.213 - }
184.214 - }
184.215 -
184.216 -// void LpCplex::_setRowLowerBound(int i, Value value)
184.217 -// {
184.218 -// //Not implemented, obsolete
184.219 -// }
184.220 -
184.221 -// void LpCplex::_setRowUpperBound(int i, Value value)
184.222 -// {
184.223 -// //Not implemented, obsolete
184.224 -// // //TODO Ezt kell meg megirni
184.225 -// // //type of the problem
184.226 -// // char sense[1];
184.227 -// // status = CPXgetsense (env, lp, sense, i, i);
184.228 -// // Value rhs[1];
184.229 -// // status = CPXgetrhs (env, lp, rhs, i, i);
184.230 -
184.231 -// // switch (sense[0]) {
184.232 -// // case 'L'://<= constraint
184.233 -// // break;
184.234 -// // case 'E'://= constraint
184.235 -// // break;
184.236 -// // case 'G'://>= constraint
184.237 -// // break;
184.238 -// // case 'R'://ranged constraint
184.239 -// // break;
184.240 -// // default: ;
184.241 -// // //FIXME error
184.242 -// // }
184.243 -
184.244 -// // status = CPXchgcoef (env, lp, i, -2, value_rng);
184.245 -// }
184.246 -
184.247 - void LpCplex::_setObjCoeff(int i, Value obj_coef)
184.248 - {
184.249 - CPXchgcoef (env, lp, -1, i, obj_coef);
184.250 - }
184.251 -
184.252 - void LpCplex::_clearObj()
184.253 - {
184.254 - for (int i=0;i< CPXgetnumcols (env, lp);++i){
184.255 - CPXchgcoef (env, lp, -1, i, 0);
184.256 - }
184.257 -
184.258 - }
184.259 -
184.260 - LpCplex::SolveExitStatus LpCplex::_solve()
184.261 - {
184.262 -
184.263 - status = CPXlpopt (env, lp);
184.264 - if (status == 0){
184.265 - return SOLVED;
184.266 - }
184.267 - else{
184.268 - return UNSOLVED;
184.269 - }
184.270 -// int i= lpx_simplex(lp);
184.271 -// switch (i) {
184.272 -// case LPX_E_OK:
184.273 -// return SOLVED;
184.274 -// break;
184.275 -// default:
184.276 -// return UNSOLVED;
184.277 -// }
184.278 - }
184.279 -
184.280 - LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
184.281 - {
184.282 -//7.5-os cplex statusai
184.283 -// #define CPX_OPTIMAL 1
184.284 -// #define CPX_INFEASIBLE 2
184.285 -// #define CPX_UNBOUNDED 3
184.286 -// #define CPX_OBJ_LIM 4
184.287 -// #define CPX_IT_LIM_FEAS 5
184.288 -// #define CPX_IT_LIM_INFEAS 6
184.289 -// #define CPX_TIME_LIM_FEAS 7
184.290 -// #define CPX_TIME_LIM_INFEAS 8
184.291 -// #define CPX_NUM_BEST_FEAS 9
184.292 -// #define CPX_NUM_BEST_INFEAS 10
184.293 -// #define CPX_OPTIMAL_INFEAS 11
184.294 -// #define CPX_ABORT_FEAS 12
184.295 -// #define CPX_ABORT_INFEAS 13
184.296 -// #define CPX_ABORT_DUAL_INFEAS 14
184.297 -// #define CPX_ABORT_PRIM_INFEAS 15
184.298 -// #define CPX_ABORT_PRIM_DUAL_INFEAS 16
184.299 -// #define CPX_ABORT_PRIM_DUAL_FEAS 17
184.300 -// #define CPX_ABORT_CROSSOVER 18
184.301 -// #define CPX_INForUNBD 19
184.302 -// #define CPX_PIVOT 20
184.303 -
184.304 -// Ezeket hova tegyem:
184.305 -// ??case CPX_ABORT_DUAL_INFEAS
184.306 -// ??case CPX_ABORT_CROSSOVER
184.307 -// ??case CPX_INForUNBD
184.308 -// ??case CPX_PIVOT
184.309 -
184.310 - int stat = CPXgetstat (env, lp);
184.311 - switch (stat) {
184.312 - case 0:
184.313 - return UNDEFINED; //Undefined
184.314 - break;
184.315 - case CPX_OPTIMAL://Optimal
184.316 - return OPTIMAL;
184.317 - break;
184.318 - case CPX_UNBOUNDED://Unbounded
184.319 - return INFINITE;
184.320 - break;
184.321 - case CPX_INFEASIBLE://Infeasible
184.322 - case CPX_IT_LIM_INFEAS:
184.323 - case CPX_TIME_LIM_INFEAS:
184.324 - case CPX_NUM_BEST_INFEAS:
184.325 - case CPX_OPTIMAL_INFEAS:
184.326 - case CPX_ABORT_INFEAS:
184.327 - case CPX_ABORT_PRIM_INFEAS:
184.328 - case CPX_ABORT_PRIM_DUAL_INFEAS:
184.329 - return INFEASIBLE;
184.330 - break;
184.331 - case CPX_OBJ_LIM:
184.332 - case CPX_IT_LIM_FEAS:
184.333 - case CPX_TIME_LIM_FEAS:
184.334 - case CPX_NUM_BEST_FEAS:
184.335 - case CPX_ABORT_FEAS:
184.336 - case CPX_ABORT_PRIM_DUAL_FEAS:
184.337 - return FEASIBLE;
184.338 - break;
184.339 - default:
184.340 - return UNDEFINED; //Everything else comes here
184.341 - //FIXME error
184.342 - }
184.343 -
184.344 -
184.345 - //Nem tudom, hanyas cplex verzio statusai
184.346 -// CPX_STAT_ABORT_DUAL_OBJ_LIM
184.347 -// CPX_STAT_ABORT_IT_LIM
184.348 -// CPX_STAT_ABORT_OBJ_LIM
184.349 -// CPX_STAT_ABORT_PRIM_OBJ_LIM
184.350 -// CPX_STAT_ABORT_TIME_LIM
184.351 -// CPX_STAT_ABORT_USER
184.352 -// CPX_STAT_FEASIBLE_RELAXED
184.353 -// CPX_STAT_INFEASIBLE
184.354 -// CPX_STAT_INForUNBD
184.355 -// CPX_STAT_NUM_BEST
184.356 -// CPX_STAT_OPTIMAL
184.357 -// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
184.358 -// CPX_STAT_OPTIMAL_INFEAS
184.359 -// CPX_STAT_OPTIMAL_RELAXED
184.360 -// CPX_STAT_UNBOUNDED
184.361 -
184.362 -// int stat = CPXgetstat (env, lp);
184.363 -// switch (stat) {
184.364 -// case CPX_STAT_OPTIMAL://Optimal
184.365 -// return OPTIMAL;
184.366 -// break;
184.367 -// case CPX_STAT_INFEASIBLE://Infeasible
184.368 -// return INFEASIBLE;
184.369 -// break;
184.370 -// case CPX_STAT_UNBOUNDED://Unbounded
184.371 -// return INFINITE;
184.372 -// break;
184.373 -// case CPX_STAT_NUM_BEST://Feasible
184.374 -// return FEASIBLE;
184.375 -// break;
184.376 -// default:
184.377 -// return UNDEFINED; //Everything else comes here
184.378 -// //FIXME error
184.379 -// }
184.380 -
184.381 - }
184.382 -
184.383 - LpCplex::Value LpCplex::_getPrimal(int i)
184.384 - {
184.385 - Value x;
184.386 - CPXgetx (env, lp, &x, i, i);
184.387 - return x;
184.388 - }
184.389 -
184.390 - LpCplex::Value LpCplex::_getPrimalValue()
184.391 - {
184.392 - Value objval;
184.393 - //method = CPXgetmethod (env, lp);
184.394 - status = CPXgetobjval (env, lp, &objval);
184.395 - return objval;
184.396 - }
184.397 -
184.398 -
184.399 -
184.400 -
184.401 - void LpCplex::_setMax()
184.402 - {
184.403 - CPXchgobjsen (env, lp, CPX_MAX);
184.404 - }
184.405 - void LpCplex::_setMin()
184.406 - {
184.407 - CPXchgobjsen (env, lp, CPX_MIN);
184.408 - }
184.409 -
184.410 -} //namespace lemon
184.411 -
185.1 --- a/src/lemon/lp_cplex.h Sat May 21 21:04:57 2005 +0000
185.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
185.3 @@ -1,112 +0,0 @@
185.4 -/* -*- C++ -*-
185.5 - * src/lemon/lp_cplex.h - Part of LEMON, a generic C++ optimization library
185.6 - *
185.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
185.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
185.9 - *
185.10 - * Permission to use, modify and distribute this software is granted
185.11 - * provided that this copyright notice appears in all copies. For
185.12 - * precise terms see the accompanying LICENSE file.
185.13 - *
185.14 - * This software is provided "AS IS" with no warranty of any kind,
185.15 - * express or implied, and with no claim as to its suitability for any
185.16 - * purpose.
185.17 - *
185.18 - */
185.19 -
185.20 -#ifndef LEMON_LP_CPLEX_H
185.21 -#define LEMON_LP_CPLEX_H
185.22 -
185.23 -///\file
185.24 -///\brief Header of the LEMON-CPLEX lp solver interface.
185.25 -
185.26 -#include <lemon/lp_base.h>
185.27 -
185.28 -extern "C" {
185.29 -#include <ilcplex/cplex.h>
185.30 -}
185.31 -
185.32 -namespace lemon {
185.33 -
185.34 -
185.35 - /// \brief Interface for the CPLEX solver
185.36 - ///
185.37 - /// This class implements an interface for the CPLEX LP solver.
185.38 - class LpCplex : public LpSolverBase {
185.39 -
185.40 - public:
185.41 -
185.42 - typedef LpSolverBase Parent;
185.43 -
185.44 - /// \e
185.45 - int status;
185.46 - CPXENVptr env;
185.47 - CPXLPptr lp;
185.48 -
185.49 -
185.50 - /// \e
185.51 - LpCplex();
185.52 - /// \e
185.53 - ~LpCplex();
185.54 -
185.55 - protected:
185.56 - virtual LpSolverBase &_newLp();
185.57 - virtual LpSolverBase &_copyLp();
185.58 -
185.59 - virtual int _addCol();
185.60 - virtual int _addRow();
185.61 - virtual void _eraseCol(int i);
185.62 - virtual void _eraseRow(int i);
185.63 - virtual void _setRowCoeffs(int i,
185.64 - int length,
185.65 - const int * indices,
185.66 - const Value * values );
185.67 - virtual void _setColCoeffs(int i,
185.68 - int length,
185.69 - const int * indices,
185.70 - const Value * values);
185.71 - virtual void _setCoeff(int row, int col, Value value);
185.72 - virtual void _setColLowerBound(int i, Value value);
185.73 - virtual void _setColUpperBound(int i, Value value);
185.74 -// virtual void _setRowLowerBound(int i, Value value);
185.75 -// virtual void _setRowUpperBound(int i, Value value);
185.76 - virtual void _setRowBounds(int i, Value lower, Value upper);
185.77 - virtual void _setObjCoeff(int i, Value obj_coef);
185.78 - virtual void _clearObj();
185.79 - ///\e
185.80 -
185.81 - ///\bug Unimplemented
185.82 - ///
185.83 - virtual SolveExitStatus _solve();
185.84 - ///\e
185.85 -
185.86 - ///\bug Unimplemented
185.87 - ///
185.88 - virtual Value _getPrimal(int i);
185.89 - ///\e
185.90 -
185.91 - ///\bug Unimplemented
185.92 - ///
185.93 - virtual Value _getPrimalValue();
185.94 - ///\e
185.95 -
185.96 - ///\bug Unimplemented
185.97 - ///
185.98 - virtual SolutionStatus _getPrimalStatus();
185.99 -
185.100 - ///\e
185.101 -
185.102 - ///\bug Unimplemented
185.103 - ///
185.104 - virtual void _setMax();
185.105 - ///\e
185.106 -
185.107 - ///\bug Unimplemented
185.108 - ///
185.109 - virtual void _setMin();
185.110 -
185.111 - };
185.112 -} //END OF NAMESPACE LEMON
185.113 -
185.114 -#endif //LEMON_LP_CPLEX_H
185.115 -
186.1 --- a/src/lemon/lp_glpk.cc Sat May 21 21:04:57 2005 +0000
186.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
186.3 @@ -1,447 +0,0 @@
186.4 -/* -*- C++ -*-
186.5 - * src/lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
186.6 - *
186.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
186.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
186.9 - *
186.10 - * Permission to use, modify and distribute this software is granted
186.11 - * provided that this copyright notice appears in all copies. For
186.12 - * precise terms see the accompanying LICENSE file.
186.13 - *
186.14 - * This software is provided "AS IS" with no warranty of any kind,
186.15 - * express or implied, and with no claim as to its suitability for any
186.16 - * purpose.
186.17 - *
186.18 - */
186.19 -
186.20 -#ifndef LEMON_LP_GLPK_CC
186.21 -#define LEMON_LP_GLPK_CC
186.22 -
186.23 -///\file
186.24 -///\brief Implementation of the LEMON-GLPK lp solver interface.
186.25 -
186.26 -#include <lemon/lp_glpk.h>
186.27 -
186.28 -namespace lemon {
186.29 -
186.30 - ///\e
186.31 -
186.32 - ///\bug Unimplemented!
186.33 - ///
186.34 - LpSolverBase &LpGlpk::_newLp()
186.35 - {
186.36 - LpSolverBase *tmp=0;
186.37 - return *tmp;
186.38 - }
186.39 -
186.40 - ///\e
186.41 -
186.42 - ///\bug Unimplemented!
186.43 - ///
186.44 - LpSolverBase &LpGlpk::_copyLp()
186.45 - {
186.46 - LpSolverBase *tmp=0;
186.47 - return *tmp;
186.48 - }
186.49 -
186.50 - LpGlpk::LpGlpk() : Parent(),
186.51 - lp(lpx_create_prob()) {
186.52 - ///\todo constrol function for this:
186.53 - lpx_set_int_parm(lp, LPX_K_DUAL, 1);
186.54 - messageLevel(0);
186.55 - }
186.56 -
186.57 - LpGlpk::~LpGlpk() {
186.58 - lpx_delete_prob(lp);
186.59 - }
186.60 -
186.61 - int LpGlpk::_addCol() {
186.62 - int i=lpx_add_cols(lp, 1);
186.63 - _setColLowerBound(i, -INF);
186.64 - _setColUpperBound(i, INF);
186.65 - return i;
186.66 - }
186.67 -
186.68 - int LpGlpk::_addRow() {
186.69 - int i=lpx_add_rows(lp, 1);
186.70 - return i;
186.71 - }
186.72 -
186.73 -
186.74 - void LpGlpk::_eraseCol(int i) {
186.75 - int cols[2];
186.76 - cols[1]=i;
186.77 - lpx_del_cols(lp, 1, cols);
186.78 - }
186.79 -
186.80 - void LpGlpk::_eraseRow(int i) {
186.81 - int rows[2];
186.82 - rows[1]=i;
186.83 - lpx_del_rows(lp, 1, rows);
186.84 - }
186.85 -
186.86 - void LpGlpk::_setRowCoeffs(int i,
186.87 - int length,
186.88 - const int * indices,
186.89 - const Value * values )
186.90 - {
186.91 - lpx_set_mat_row(lp, i, length,
186.92 - const_cast<int * >(indices) ,
186.93 - const_cast<Value * >(values));
186.94 - }
186.95 -
186.96 - void LpGlpk::_setColCoeffs(int i,
186.97 - int length,
186.98 - const int * indices,
186.99 - const Value * values)
186.100 - {
186.101 - lpx_set_mat_col(lp, i, length,
186.102 - const_cast<int * >(indices),
186.103 - const_cast<Value * >(values));
186.104 - }
186.105 -
186.106 -
186.107 - void LpGlpk::_setCoeff(int row, int col, Value value)
186.108 - {
186.109 - ///FIXME Of course this is not efficient at all, but GLPK knows not more.
186.110 - // First approach: get one row, apply changes and set it again
186.111 - //(one idea to improve this: maybe it is better to do this with 1 coloumn)
186.112 -
186.113 - int mem_length=2+lpx_get_num_cols(lp);
186.114 - int* indices = new int[mem_length];
186.115 - Value* values = new Value[mem_length];
186.116 -
186.117 -
186.118 - int length=lpx_get_mat_row(lp, row, indices, values);
186.119 -
186.120 - //The following code does not suppose that the elements of the array indices are sorted
186.121 - int i=1;
186.122 - bool found=false;
186.123 - while (i <= length && !found){
186.124 - if (indices[i]==col){
186.125 - found = true;
186.126 - values[i]=value;
186.127 - }
186.128 - ++i;
186.129 - }
186.130 - if (!found){
186.131 - ++length;
186.132 - indices[length]=col;
186.133 - values[length]=value;
186.134 - }
186.135 -
186.136 - lpx_set_mat_row(lp, row, length, indices, values);
186.137 - delete [] indices;
186.138 - delete [] values;
186.139 -
186.140 - }
186.141 -
186.142 - void LpGlpk::_setColLowerBound(int i, Value lo)
186.143 - {
186.144 - if (lo==INF) {
186.145 - //FIXME error
186.146 - }
186.147 - int b=lpx_get_col_type(lp, i);
186.148 - double up=lpx_get_col_ub(lp, i);
186.149 - if (lo==-INF) {
186.150 - switch (b) {
186.151 - case LPX_FR:
186.152 - case LPX_LO:
186.153 - lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
186.154 - break;
186.155 - case LPX_UP:
186.156 - break;
186.157 - case LPX_DB:
186.158 - case LPX_FX:
186.159 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
186.160 - break;
186.161 - default: ;
186.162 - //FIXME error
186.163 - }
186.164 - } else {
186.165 - switch (b) {
186.166 - case LPX_FR:
186.167 - case LPX_LO:
186.168 - lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
186.169 - break;
186.170 - case LPX_UP:
186.171 - case LPX_DB:
186.172 - case LPX_FX:
186.173 - if (lo==up)
186.174 - lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
186.175 - else
186.176 - lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
186.177 - break;
186.178 - default: ;
186.179 - //FIXME error
186.180 - }
186.181 - }
186.182 -
186.183 - }
186.184 -
186.185 - void LpGlpk::_setColUpperBound(int i, Value up)
186.186 - {
186.187 - if (up==-INF) {
186.188 - //FIXME error
186.189 - }
186.190 - int b=lpx_get_col_type(lp, i);
186.191 - double lo=lpx_get_col_lb(lp, i);
186.192 - if (up==INF) {
186.193 - switch (b) {
186.194 - case LPX_FR:
186.195 - case LPX_LO:
186.196 - break;
186.197 - case LPX_UP:
186.198 - lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
186.199 - break;
186.200 - case LPX_DB:
186.201 - case LPX_FX:
186.202 - lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
186.203 - break;
186.204 - default: ;
186.205 - //FIXME error
186.206 - }
186.207 - } else {
186.208 - switch (b) {
186.209 - case LPX_FR:
186.210 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
186.211 - break;
186.212 - case LPX_UP:
186.213 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
186.214 - break;
186.215 - case LPX_LO:
186.216 - case LPX_DB:
186.217 - case LPX_FX:
186.218 - if (lo==up)
186.219 - lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
186.220 - else
186.221 - lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
186.222 - break;
186.223 - default: ;
186.224 - //FIXME error
186.225 - }
186.226 - }
186.227 - }
186.228 -
186.229 -// void LpGlpk::_setRowLowerBound(int i, Value lo)
186.230 -// {
186.231 -// if (lo==INF) {
186.232 -// //FIXME error
186.233 -// }
186.234 -// int b=lpx_get_row_type(lp, i);
186.235 -// double up=lpx_get_row_ub(lp, i);
186.236 -// if (lo==-INF) {
186.237 -// switch (b) {
186.238 -// case LPX_FR:
186.239 -// case LPX_LO:
186.240 -// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
186.241 -// break;
186.242 -// case LPX_UP:
186.243 -// break;
186.244 -// case LPX_DB:
186.245 -// case LPX_FX:
186.246 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
186.247 -// break;
186.248 -// default: ;
186.249 -// //FIXME error
186.250 -// }
186.251 -// } else {
186.252 -// switch (b) {
186.253 -// case LPX_FR:
186.254 -// case LPX_LO:
186.255 -// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
186.256 -// break;
186.257 -// case LPX_UP:
186.258 -// case LPX_DB:
186.259 -// case LPX_FX:
186.260 -// if (lo==up)
186.261 -// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
186.262 -// else
186.263 -// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
186.264 -// break;
186.265 -// default: ;
186.266 -// //FIXME error
186.267 -// }
186.268 -// }
186.269 -// }
186.270 -
186.271 -// void LpGlpk::_setRowUpperBound(int i, Value up)
186.272 -// {
186.273 -// if (up==-INF) {
186.274 -// //FIXME error
186.275 -// }
186.276 -// int b=lpx_get_row_type(lp, i);
186.277 -// double lo=lpx_get_row_lb(lp, i);
186.278 -// if (up==INF) {
186.279 -// switch (b) {
186.280 -// case LPX_FR:
186.281 -// case LPX_LO:
186.282 -// break;
186.283 -// case LPX_UP:
186.284 -// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
186.285 -// break;
186.286 -// case LPX_DB:
186.287 -// case LPX_FX:
186.288 -// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
186.289 -// break;
186.290 -// default: ;
186.291 -// //FIXME error
186.292 -// }
186.293 -// } else {
186.294 -// switch (b) {
186.295 -// case LPX_FR:
186.296 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
186.297 -// break;
186.298 -// case LPX_UP:
186.299 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
186.300 -// break;
186.301 -// case LPX_LO:
186.302 -// case LPX_DB:
186.303 -// case LPX_FX:
186.304 -// if (lo==up)
186.305 -// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
186.306 -// else
186.307 -// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
186.308 -// break;
186.309 -// default: ;
186.310 -// //FIXME error
186.311 -// }
186.312 -// }
186.313 -// }
186.314 -
186.315 - void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
186.316 - {
186.317 - //Bad parameter
186.318 - if (lb==INF || ub==-INF) {
186.319 - //FIXME error
186.320 - }
186.321 -
186.322 - if (lb == -INF){
186.323 - if (ub == INF){
186.324 - lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
186.325 - }
186.326 - else{
186.327 - lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
186.328 - }
186.329 - }
186.330 - else{
186.331 - if (ub==INF){
186.332 - lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
186.333 -
186.334 - }
186.335 - else{
186.336 - if (lb == ub){
186.337 - lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
186.338 - }
186.339 - else{
186.340 - lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
186.341 - }
186.342 - }
186.343 - }
186.344 -
186.345 - }
186.346 -
186.347 - void LpGlpk::_setObjCoeff(int i, Value obj_coef)
186.348 - {
186.349 - //i=0 means the constant term (shift)
186.350 - lpx_set_obj_coef(lp, i, obj_coef);
186.351 - }
186.352 -
186.353 - void LpGlpk::_clearObj()
186.354 - {
186.355 - for (int i=0;i<=lpx_get_num_cols(lp);++i){
186.356 - lpx_set_obj_coef(lp, i, 0);
186.357 - }
186.358 - }
186.359 -// void LpGlpk::_setObj(int length,
186.360 -// int const * indices,
186.361 -// Value const * values )
186.362 -// {
186.363 -// Value new_values[1+lpx_num_cols()];
186.364 -// for (i=0;i<=lpx_num_cols();++i){
186.365 -// new_values[i]=0;
186.366 -// }
186.367 -// for (i=1;i<=length;++i){
186.368 -// new_values[indices[i]]=values[i];
186.369 -// }
186.370 -
186.371 -// for (i=0;i<=lpx_num_cols();++i){
186.372 -// lpx_set_obj_coef(lp, i, new_values[i]);
186.373 -// }
186.374 -// }
186.375 -
186.376 - LpGlpk::SolveExitStatus LpGlpk::_solve()
186.377 - {
186.378 - int i= lpx_simplex(lp);
186.379 - switch (i) {
186.380 - case LPX_E_OK:
186.381 - return SOLVED;
186.382 - break;
186.383 - default:
186.384 - return UNSOLVED;
186.385 - }
186.386 - }
186.387 -
186.388 - LpGlpk::Value LpGlpk::_getPrimal(int i)
186.389 - {
186.390 - return lpx_get_col_prim(lp,i);
186.391 - }
186.392 -
186.393 - LpGlpk::Value LpGlpk::_getPrimalValue()
186.394 - {
186.395 - return lpx_get_obj_val(lp);
186.396 - }
186.397 -
186.398 -
186.399 - LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
186.400 - {
186.401 - int stat= lpx_get_status(lp);
186.402 - switch (stat) {
186.403 - case LPX_UNDEF://Undefined (no solve has been run yet)
186.404 - return UNDEFINED;
186.405 - break;
186.406 - case LPX_NOFEAS://There is no feasible solution (primal, I guess)
186.407 - case LPX_INFEAS://Infeasible
186.408 - return INFEASIBLE;
186.409 - break;
186.410 - case LPX_UNBND://Unbounded
186.411 - return INFINITE;
186.412 - break;
186.413 - case LPX_FEAS://Feasible
186.414 - return FEASIBLE;
186.415 - break;
186.416 - case LPX_OPT://Feasible
186.417 - return OPTIMAL;
186.418 - break;
186.419 - default:
186.420 - return UNDEFINED; //to avoid gcc warning
186.421 - //FIXME error
186.422 - }
186.423 - }
186.424 -
186.425 -
186.426 - void LpGlpk::_setMax()
186.427 - {
186.428 - lpx_set_obj_dir(lp, LPX_MAX);
186.429 - }
186.430 -
186.431 - void LpGlpk::_setMin()
186.432 - {
186.433 - lpx_set_obj_dir(lp, LPX_MIN);
186.434 - }
186.435 -
186.436 -
186.437 - void LpGlpk::messageLevel(int m)
186.438 - {
186.439 - lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
186.440 - }
186.441 -
186.442 - void LpGlpk::presolver(bool b)
186.443 - {
186.444 - lpx_set_int_parm(lp, LPX_K_PRESOL, b);
186.445 - }
186.446 -
186.447 -
186.448 -} //END OF NAMESPACE LEMON
186.449 -
186.450 -#endif //LEMON_LP_GLPK_CC
187.1 --- a/src/lemon/lp_glpk.h Sat May 21 21:04:57 2005 +0000
187.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
187.3 @@ -1,114 +0,0 @@
187.4 -/* -*- C++ -*-
187.5 - * src/lemon/lp_glpk.h - Part of LEMON, a generic C++ optimization library
187.6 - *
187.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
187.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
187.9 - *
187.10 - * Permission to use, modify and distribute this software is granted
187.11 - * provided that this copyright notice appears in all copies. For
187.12 - * precise terms see the accompanying LICENSE file.
187.13 - *
187.14 - * This software is provided "AS IS" with no warranty of any kind,
187.15 - * express or implied, and with no claim as to its suitability for any
187.16 - * purpose.
187.17 - *
187.18 - */
187.19 -
187.20 -#ifndef LEMON_LP_GLPK_H
187.21 -#define LEMON_LP_GLPK_H
187.22 -
187.23 -///\file
187.24 -///\brief Header of the LEMON-GLPK lp solver interface.
187.25 -///\ingroup gen_opt_group
187.26 -
187.27 -#include <lemon/lp_base.h>
187.28 -extern "C" {
187.29 -#include <glpk.h>
187.30 -}
187.31 -
187.32 -namespace lemon {
187.33 -
187.34 -
187.35 - /// \brief Interface for the GLPK LP solver
187.36 - ///
187.37 - /// This class implements an interface for the GLPK LP solver.
187.38 - ///\ingroup gen_opt_group
187.39 - class LpGlpk : public LpSolverBase {
187.40 - protected:
187.41 - LPX* lp;
187.42 -
187.43 - public:
187.44 -
187.45 - typedef LpSolverBase Parent;
187.46 -
187.47 - LpGlpk();
187.48 - ~LpGlpk();
187.49 -
187.50 - protected:
187.51 - virtual LpSolverBase &_newLp();
187.52 - virtual LpSolverBase &_copyLp();
187.53 -
187.54 - virtual int _addCol();
187.55 - virtual int _addRow();
187.56 - virtual void _eraseCol(int i);
187.57 - virtual void _eraseRow(int i);
187.58 -
187.59 - virtual void _setRowCoeffs(int i,
187.60 - int length,
187.61 - const int * indices,
187.62 - const Value * values );
187.63 - virtual void _setColCoeffs(int i,
187.64 - int length,
187.65 - const int * indices,
187.66 - const Value * values);
187.67 - virtual void _setCoeff(int row, int col, Value value);
187.68 - virtual void _setColLowerBound(int i, Value value);
187.69 - virtual void _setColUpperBound(int i, Value value);
187.70 -// virtual void _setRowLowerBound(int i, Value value);
187.71 -// virtual void _setRowUpperBound(int i, Value value);
187.72 - virtual void _setRowBounds(int i, Value lower, Value upper);
187.73 - virtual void _setObjCoeff(int i, Value obj_coef);
187.74 - virtual void _clearObj();
187.75 -// virtual void _setObj(int length,
187.76 -// int const * indices,
187.77 -// Value const * values ) = 0;
187.78 -
187.79 - ///\e
187.80 -
187.81 - ///\todo It should be clarified
187.82 - ///
187.83 - virtual SolveExitStatus _solve();
187.84 - virtual Value _getPrimal(int i);
187.85 - virtual Value _getPrimalValue();
187.86 - ///\e
187.87 -
187.88 - ///\todo It should be clarified
187.89 - ///
187.90 - virtual SolutionStatus _getPrimalStatus();
187.91 - virtual void _setMax();
187.92 - virtual void _setMin();
187.93 -
187.94 - public:
187.95 - ///Set the verbosity of the messages
187.96 -
187.97 - ///Set the verbosity of the messages
187.98 - ///
187.99 - ///\param m is the level of the messages output by the solver routines.
187.100 - ///The possible values are:
187.101 - ///- 0 --- no output (default value)
187.102 - ///- 1 --- error messages only
187.103 - ///- 2 --- normal output
187.104 - ///- 3 --- full output (includes informational messages)
187.105 - void messageLevel(int m);
187.106 - ///Turns on or off the presolver
187.107 -
187.108 - ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
187.109 - ///
187.110 - ///The presolver is off by default.
187.111 - void presolver(bool b);
187.112 -
187.113 - };
187.114 -} //END OF NAMESPACE LEMON
187.115 -
187.116 -#endif //LEMON_LP_GLPK_H
187.117 -
188.1 --- a/src/lemon/lp_skeleton.cc Sat May 21 21:04:57 2005 +0000
188.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
188.3 @@ -1,128 +0,0 @@
188.4 -/* -*- C++ -*-
188.5 - * src/lemon/lp_skeleton.cc
188.6 - * - Part of LEMON, a generic C++ optimization library
188.7 - *
188.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
188.9 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
188.10 - *
188.11 - * Permission to use, modify and distribute this software is granted
188.12 - * provided that this copyright notice appears in all copies. For
188.13 - * precise terms see the accompanying LICENSE file.
188.14 - *
188.15 - * This software is provided "AS IS" with no warranty of any kind,
188.16 - * express or implied, and with no claim as to its suitability for any
188.17 - * purpose.
188.18 - *
188.19 - */
188.20 -
188.21 -#include <lemon/lp_skeleton.h>
188.22 -
188.23 -///\file
188.24 -///\brief A skeleton file to implement LP solver interfaces
188.25 -namespace lemon {
188.26 -
188.27 - LpSolverBase &LpSkeleton::_newLp()
188.28 - {
188.29 - LpSolverBase *tmp=0;
188.30 - return *tmp;
188.31 - }
188.32 -
188.33 - LpSolverBase &LpSkeleton::_copyLp()
188.34 - {
188.35 - LpSolverBase *tmp=0;
188.36 - return *tmp;
188.37 - }
188.38 -
188.39 - int LpSkeleton::_addCol()
188.40 - {
188.41 - return ++col_num;
188.42 - }
188.43 -
188.44 - int LpSkeleton::_addRow()
188.45 - {
188.46 - return ++row_num;
188.47 - }
188.48 -
188.49 - void LpSkeleton::_eraseCol(int ) {
188.50 - }
188.51 -
188.52 - void LpSkeleton::_eraseRow(int) {
188.53 - }
188.54 -
188.55 - void LpSkeleton::_setRowCoeffs(int,
188.56 - int,
188.57 - int const *,
188.58 - Value const *)
188.59 - {
188.60 - }
188.61 -
188.62 - void LpSkeleton::_setColCoeffs(int,
188.63 - int,
188.64 - int const *,
188.65 - Value const *)
188.66 - {
188.67 - }
188.68 -
188.69 - void LpSkeleton::_setCoeff(int, int, Value )
188.70 - {
188.71 - }
188.72 -
188.73 -
188.74 - void LpSkeleton::_setColLowerBound(int, Value)
188.75 - {
188.76 - }
188.77 -
188.78 - void LpSkeleton::_setColUpperBound(int, Value)
188.79 - {
188.80 - }
188.81 -
188.82 -// void LpSkeleton::_setRowLowerBound(int, Value)
188.83 -// {
188.84 -// }
188.85 -
188.86 -// void LpSkeleton::_setRowUpperBound(int, Value)
188.87 -// {
188.88 -// }
188.89 -
188.90 - void LpSkeleton::_setRowBounds(int, Value, Value)
188.91 - {
188.92 - }
188.93 -
188.94 - void LpSkeleton::_setObjCoeff(int, Value)
188.95 - {
188.96 - }
188.97 -
188.98 - void LpSkeleton::_setMax()
188.99 - {
188.100 - }
188.101 -
188.102 - void LpSkeleton::_setMin()
188.103 - {
188.104 - }
188.105 -
188.106 - void LpSkeleton::_clearObj()
188.107 - {
188.108 - }
188.109 -
188.110 - LpSkeleton::SolveExitStatus LpSkeleton::_solve()
188.111 - {
188.112 - return SOLVED;
188.113 - }
188.114 -
188.115 - LpSkeleton::Value LpSkeleton::_getPrimal(int)
188.116 - {
188.117 - return 0;
188.118 - }
188.119 -
188.120 - LpSkeleton::Value LpSkeleton::_getPrimalValue()
188.121 - {
188.122 - return 0;
188.123 - }
188.124 -
188.125 - LpSkeleton::SolutionStatus LpSkeleton::_getPrimalStatus()
188.126 - {
188.127 - return OPTIMAL;
188.128 - }
188.129 -
188.130 -} //namespace lemon
188.131 -
189.1 --- a/src/lemon/lp_skeleton.h Sat May 21 21:04:57 2005 +0000
189.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
189.3 @@ -1,134 +0,0 @@
189.4 -/* -*- C++ -*-
189.5 - * src/lemon/lp_skeleton.h
189.6 - * - Part of LEMON, a generic C++ optimization library
189.7 - *
189.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
189.9 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
189.10 - *
189.11 - * Permission to use, modify and distribute this software is granted
189.12 - * provided that this copyright notice appears in all copies. For
189.13 - * precise terms see the accompanying LICENSE file.
189.14 - *
189.15 - * This software is provided "AS IS" with no warranty of any kind,
189.16 - * express or implied, and with no claim as to its suitability for any
189.17 - * purpose.
189.18 - *
189.19 - */
189.20 -
189.21 -#ifndef LEMON_LP_SKELETON
189.22 -#define LEMON_LP_SKELETON
189.23 -
189.24 -#include <lemon/lp_base.h>
189.25 -
189.26 -///\file
189.27 -///\brief A skeleton file to implement LP solver interfaces
189.28 -namespace lemon {
189.29 -
189.30 - ///A skeleton class to implement LP solver interfaces
189.31 - class LpSkeleton :public LpSolverBase {
189.32 - int col_num,row_num;
189.33 -
189.34 - protected:
189.35 - ///\e
189.36 - virtual LpSolverBase &_newLp();
189.37 - ///\e
189.38 - virtual LpSolverBase &_copyLp();
189.39 - /// \e
189.40 - virtual int _addCol();
189.41 - /// \e
189.42 - virtual int _addRow();
189.43 - /// \e
189.44 - virtual void _eraseCol(int i);
189.45 - /// \e
189.46 - virtual void _eraseRow(int i);
189.47 - /// \e
189.48 -
189.49 - /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
189.50 - ///
189.51 - virtual void _setRowCoeffs(int i,
189.52 - int length,
189.53 - int const * indices,
189.54 - Value const * values );
189.55 - /// \e
189.56 -
189.57 - /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
189.58 - ///
189.59 - virtual void _setColCoeffs(int i,
189.60 - int length,
189.61 - int const * indices,
189.62 - Value const * values );
189.63 -
189.64 - /// Set one element of the coefficient matrix
189.65 - virtual void _setCoeff(int row, int col, Value value);
189.66 -
189.67 - /// The lower bound of a variable (column) have to be given by an
189.68 - /// extended number of type Value, i.e. a finite number of type
189.69 - /// Value or -\ref INF.
189.70 - virtual void _setColLowerBound(int i, Value value);
189.71 - /// \e
189.72 -
189.73 - /// The upper bound of a variable (column) have to be given by an
189.74 - /// extended number of type Value, i.e. a finite number of type
189.75 - /// Value or \ref INF.
189.76 - virtual void _setColUpperBound(int i, Value value);
189.77 - /// \e
189.78 -
189.79 -// /// The lower bound of a linear expression (row) have to be given by an
189.80 -// /// extended number of type Value, i.e. a finite number of type
189.81 -// /// Value or -\ref INF.
189.82 -// virtual void _setRowLowerBound(int i, Value value);
189.83 -// /// \e
189.84 -
189.85 -// /// The upper bound of a linear expression (row) have to be given by an
189.86 -// /// extended number of type Value, i.e. a finite number of type
189.87 -// /// Value or \ref INF.
189.88 -// virtual void _setRowUpperBound(int i, Value value);
189.89 -
189.90 - /// The lower and upper bound of a linear expression (row) have to be
189.91 - /// given by an
189.92 - /// extended number of type Value, i.e. a finite number of type
189.93 - /// Value or +/-\ref INF.
189.94 - virtual void _setRowBounds(int i, Value lb, Value ub);
189.95 - /// \e
189.96 -
189.97 -
189.98 - /// \e
189.99 - virtual void _clearObj();
189.100 - /// \e
189.101 - virtual void _setObjCoeff(int i, Value obj_coef);
189.102 -
189.103 - ///\e
189.104 -
189.105 - ///\bug Wrong interface
189.106 - ///
189.107 - virtual SolveExitStatus _solve();
189.108 -
189.109 - ///\e
189.110 -
189.111 - ///\bug Wrong interface
189.112 - ///
189.113 - virtual Value _getPrimal(int i);
189.114 - ///\e
189.115 -
189.116 - ///\bug Wrong interface
189.117 - ///
189.118 - virtual Value _getPrimalValue();
189.119 - ///\e
189.120 -
189.121 - ///\bug Wrong interface
189.122 - ///
189.123 - virtual SolutionStatus _getPrimalStatus();
189.124 -
189.125 - ///\e
189.126 - virtual void _setMax();
189.127 - ///\e
189.128 - virtual void _setMin();
189.129 -
189.130 -
189.131 - public:
189.132 - LpSkeleton() : LpSolverBase(), col_num(0), row_num(0) {}
189.133 - };
189.134 -
189.135 -} //namespace lemon
189.136 -
189.137 -#endif // LEMON_LP_SKELETON
190.1 --- a/src/lemon/maps.h Sat May 21 21:04:57 2005 +0000
190.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
190.3 @@ -1,841 +0,0 @@
190.4 -/* -*- C++ -*-
190.5 - * src/lemon/maps.h - Part of LEMON, a generic C++ optimization library
190.6 - *
190.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
190.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
190.9 - *
190.10 - * Permission to use, modify and distribute this software is granted
190.11 - * provided that this copyright notice appears in all copies. For
190.12 - * precise terms see the accompanying LICENSE file.
190.13 - *
190.14 - * This software is provided "AS IS" with no warranty of any kind,
190.15 - * express or implied, and with no claim as to its suitability for any
190.16 - * purpose.
190.17 - *
190.18 - */
190.19 -
190.20 -#ifndef LEMON_MAPS_H
190.21 -#define LEMON_MAPS_H
190.22 -
190.23 -#include <lemon/graph_utils.h>
190.24 -#include <lemon/utility.h>
190.25 -
190.26 -
190.27 -///\file
190.28 -///\ingroup maps
190.29 -///\brief Miscellaneous property maps
190.30 -///
190.31 -///\todo This file has the same name as the concept file in concept/,
190.32 -/// and this is not easily detectable in docs...
190.33 -
190.34 -#include <map>
190.35 -
190.36 -namespace lemon {
190.37 -
190.38 - /// \addtogroup maps
190.39 - /// @{
190.40 -
190.41 - /// Base class of maps.
190.42 -
190.43 - /// Base class of maps.
190.44 - /// It provides the necessary <tt>typedef</tt>s required by the map concept.
190.45 - template<typename K, typename T>
190.46 - class MapBase
190.47 - {
190.48 - public:
190.49 - ///\e
190.50 - typedef K Key;
190.51 - ///\e
190.52 - typedef T Value;
190.53 - };
190.54 -
190.55 - /// Null map. (a.k.a. DoNothingMap)
190.56 -
190.57 - /// If you have to provide a map only for its type definitions,
190.58 - /// or if you have to provide a writable map, but
190.59 - /// data written to it will sent to <tt>/dev/null</tt>...
190.60 - template<typename K, typename T>
190.61 - class NullMap : public MapBase<K,T>
190.62 - {
190.63 - public:
190.64 -
190.65 - typedef True NeedCopy;
190.66 -
190.67 - /// Gives back a default constructed element.
190.68 - T operator[](const K&) const { return T(); }
190.69 - /// Absorbs the value.
190.70 - void set(const K&, const T&) {}
190.71 - };
190.72 -
190.73 - template <typename K, typename V>
190.74 - NullMap<K, V> nullMap() {
190.75 - return NullMap<K, V>();
190.76 - }
190.77 -
190.78 -
190.79 - /// Constant map.
190.80 -
190.81 - /// This is a readable map which assigns a specified value to each key.
190.82 - /// In other aspects it is equivalent to the \ref NullMap.
190.83 - /// \todo set could be used to set the value.
190.84 - template<typename K, typename T>
190.85 - class ConstMap : public MapBase<K,T>
190.86 - {
190.87 - T v;
190.88 - public:
190.89 -
190.90 - typedef True NeedCopy;
190.91 -
190.92 - /// Default constructor
190.93 -
190.94 - /// The value of the map will be uninitialized.
190.95 - /// (More exactly it will be default constructed.)
190.96 - ConstMap() {}
190.97 - ///\e
190.98 -
190.99 - /// \param _v The initial value of the map.
190.100 - ///
190.101 - ConstMap(const T &_v) : v(_v) {}
190.102 -
190.103 - T operator[](const K&) const { return v; }
190.104 - void set(const K&, const T&) {}
190.105 -
190.106 - template<typename T1>
190.107 - struct rebind {
190.108 - typedef ConstMap<K,T1> other;
190.109 - };
190.110 -
190.111 - template<typename T1>
190.112 - ConstMap(const ConstMap<K,T1> &, const T &_v) : v(_v) {}
190.113 - };
190.114 -
190.115 - ///Returns a \ref ConstMap class
190.116 -
190.117 - ///This function just returns a \ref ConstMap class.
190.118 - ///\relates ConstMap
190.119 - template<class V,class K>
190.120 - inline ConstMap<V,K> constMap(const K &k)
190.121 - {
190.122 - return ConstMap<V,K>(k);
190.123 - }
190.124 -
190.125 -
190.126 - //to document later
190.127 - template<typename T, T v>
190.128 - struct Const { };
190.129 - //to document later
190.130 - template<typename K, typename V, V v>
190.131 - class ConstMap<K, Const<V, v> > : public MapBase<K, V>
190.132 - {
190.133 - public:
190.134 - ConstMap() { }
190.135 - V operator[](const K&) const { return v; }
190.136 - void set(const K&, const V&) { }
190.137 - };
190.138 -
190.139 - /// \c std::map wrapper
190.140 -
190.141 - /// This is essentially a wrapper for \c std::map. With addition that
190.142 - /// you can specify a default value different from \c Value() .
190.143 - ///
190.144 - /// \todo Provide allocator parameter...
190.145 - template <typename K, typename T, typename Compare = std::less<K> >
190.146 - class StdMap : public std::map<K,T,Compare> {
190.147 - typedef std::map<K,T,Compare> parent;
190.148 - T v;
190.149 - typedef typename parent::value_type PairType;
190.150 -
190.151 - public:
190.152 - typedef K Key;
190.153 - typedef T Value;
190.154 - typedef T& Reference;
190.155 - typedef const T& ConstReference;
190.156 -
190.157 -
190.158 - StdMap() : v() {}
190.159 - /// Constructor with specified default value
190.160 - StdMap(const T& _v) : v(_v) {}
190.161 -
190.162 - /// \brief Constructs the map from an appropriate std::map.
190.163 - ///
190.164 - /// \warning Inefficient: copies the content of \c m !
190.165 - StdMap(const parent &m) : parent(m) {}
190.166 - /// \brief Constructs the map from an appropriate std::map, and explicitly
190.167 - /// specifies a default value.
190.168 - ///
190.169 - /// \warning Inefficient: copies the content of \c m !
190.170 - StdMap(const parent &m, const T& _v) : parent(m), v(_v) {}
190.171 -
190.172 - template<typename T1, typename Comp1>
190.173 - StdMap(const StdMap<Key,T1,Comp1> &m, const T &_v) {
190.174 - //FIXME;
190.175 - }
190.176 -
190.177 - Reference operator[](const Key &k) {
190.178 - return insert(PairType(k,v)).first -> second;
190.179 - }
190.180 - ConstReference operator[](const Key &k) const {
190.181 - typename parent::iterator i = lower_bound(k);
190.182 - if (i == parent::end() || parent::key_comp()(k, (*i).first))
190.183 - return v;
190.184 - return (*i).second;
190.185 - }
190.186 - void set(const Key &k, const T &t) {
190.187 - parent::operator[](k) = t;
190.188 - }
190.189 -
190.190 - /// Changes the default value of the map.
190.191 - /// \return Returns the previous default value.
190.192 - ///
190.193 - /// \warning The value of some keys (which has already been queried, but
190.194 - /// the value has been unchanged from the default) may change!
190.195 - T setDefault(const T &_v) { T old=v; v=_v; return old; }
190.196 -
190.197 - template<typename T1>
190.198 - struct rebind {
190.199 - typedef StdMap<Key,T1,Compare> other;
190.200 - };
190.201 - };
190.202 -
190.203 - /// @}
190.204 -
190.205 - /// \addtogroup map_adaptors
190.206 - /// @{
190.207 -
190.208 -
190.209 - ///Convert the \c Value of a maps to another type.
190.210 -
190.211 - ///This \ref concept::ReadMap "read only map"
190.212 - ///converts the \c Value of a maps to type \c T.
190.213 - ///Its \c Value is inherited from \c M.
190.214 - ///
190.215 - ///Actually,
190.216 - ///\code
190.217 - /// ConvertMap<X> sh(x,v);
190.218 - ///\endcode
190.219 - ///it is equivalent with
190.220 - ///\code
190.221 - /// ConstMap<X::Key, X::Value> c_tmp(v);
190.222 - /// AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
190.223 - ///\endcode
190.224 - ///\bug wrong documentation
190.225 - template<class M, class T>
190.226 - class ConvertMap {
190.227 - typename SmartConstReference<M>::Type m;
190.228 - public:
190.229 -
190.230 - typedef True NeedCopy;
190.231 -
190.232 - typedef typename M::Key Key;
190.233 - typedef T Value;
190.234 -
190.235 - ///Constructor
190.236 -
190.237 - ///Constructor
190.238 - ///\param _m is the undelying map
190.239 - ///\param _v is the convert value
190.240 - ConvertMap(const M &_m) : m(_m) {};
190.241 -
190.242 - /// \brief The subscript operator.
190.243 - ///
190.244 - /// The subscript operator.
190.245 - /// \param edge The edge
190.246 - /// \return The target of the edge
190.247 - Value operator[](Key k) const {return m[k];}
190.248 - };
190.249 -
190.250 - ///Returns an \ref ConvertMap class
190.251 -
190.252 - ///This function just returns an \ref ConvertMap class.
190.253 - ///\relates ConvertMap
190.254 - ///\todo The order of the template parameters are changed.
190.255 - template<class T, class M>
190.256 - inline ConvertMap<M,T> convertMap(const M &m)
190.257 - {
190.258 - return ConvertMap<M,T>(m);
190.259 - }
190.260 -
190.261 - ///Sum of two maps
190.262 -
190.263 - ///This \ref concept::ReadMap "read only map" returns the sum of the two
190.264 - ///given maps. Its \c Key and \c Value will be inherited from \c M1.
190.265 - ///The \c Key and \c Value of M2 must be convertible to those of \c M1.
190.266 -
190.267 - template<class M1,class M2>
190.268 - class AddMap
190.269 - {
190.270 - typename SmartConstReference<M1>::Type m1;
190.271 - typename SmartConstReference<M2>::Type m2;
190.272 -
190.273 - public:
190.274 -
190.275 - typedef True NeedCopy;
190.276 -
190.277 - typedef typename M1::Key Key;
190.278 - typedef typename M1::Value Value;
190.279 -
190.280 - ///Constructor
190.281 -
190.282 - ///\e
190.283 - ///
190.284 - AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.285 - Value operator[](Key k) const {return m1[k]+m2[k];}
190.286 - };
190.287 -
190.288 - ///Returns an \ref AddMap class
190.289 -
190.290 - ///This function just returns an \ref AddMap class.
190.291 - ///\todo How to call these type of functions?
190.292 - ///
190.293 - ///\relates AddMap
190.294 - ///\todo Wrong scope in Doxygen when \c \\relates is used
190.295 - template<class M1,class M2>
190.296 - inline AddMap<M1,M2> addMap(const M1 &m1,const M2 &m2)
190.297 - {
190.298 - return AddMap<M1,M2>(m1,m2);
190.299 - }
190.300 -
190.301 - ///Shift a maps with a constant.
190.302 -
190.303 - ///This \ref concept::ReadMap "read only map" returns the sum of the
190.304 - ///given map and a constant value.
190.305 - ///Its \c Key and \c Value is inherited from \c M.
190.306 - ///
190.307 - ///Actually,
190.308 - ///\code
190.309 - /// ShiftMap<X> sh(x,v);
190.310 - ///\endcode
190.311 - ///it is equivalent with
190.312 - ///\code
190.313 - /// ConstMap<X::Key, X::Value> c_tmp(v);
190.314 - /// AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
190.315 - ///\endcode
190.316 - template<class M>
190.317 - class ShiftMap
190.318 - {
190.319 - typename SmartConstReference<M>::Type m;
190.320 - typename M::Value v;
190.321 - public:
190.322 -
190.323 - typedef True NeedCopy;
190.324 - typedef typename M::Key Key;
190.325 - typedef typename M::Value Value;
190.326 -
190.327 - ///Constructor
190.328 -
190.329 - ///Constructor
190.330 - ///\param _m is the undelying map
190.331 - ///\param _v is the shift value
190.332 - ShiftMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
190.333 - Value operator[](Key k) const {return m[k]+v;}
190.334 - };
190.335 -
190.336 - ///Returns an \ref ShiftMap class
190.337 -
190.338 - ///This function just returns an \ref ShiftMap class.
190.339 - ///\relates ShiftMap
190.340 - ///\todo A better name is required.
190.341 - template<class M>
190.342 - inline ShiftMap<M> shiftMap(const M &m,const typename M::Value &v)
190.343 - {
190.344 - return ShiftMap<M>(m,v);
190.345 - }
190.346 -
190.347 - ///Difference of two maps
190.348 -
190.349 - ///This \ref concept::ReadMap "read only map" returns the difference
190.350 - ///of the values returned by the two
190.351 - ///given maps. Its \c Key and \c Value will be inherited from \c M1.
190.352 - ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
190.353 -
190.354 - template<class M1,class M2>
190.355 - class SubMap
190.356 - {
190.357 - typename SmartConstReference<M1>::Type m1;
190.358 - typename SmartConstReference<M2>::Type m2;
190.359 - public:
190.360 -
190.361 - typedef True NeedCopy;
190.362 - typedef typename M1::Key Key;
190.363 - typedef typename M1::Value Value;
190.364 -
190.365 - ///Constructor
190.366 -
190.367 - ///\e
190.368 - ///
190.369 - SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.370 - Value operator[](Key k) const {return m1[k]-m2[k];}
190.371 - };
190.372 -
190.373 - ///Returns a \ref SubMap class
190.374 -
190.375 - ///This function just returns a \ref SubMap class.
190.376 - ///
190.377 - ///\relates SubMap
190.378 - template<class M1,class M2>
190.379 - inline SubMap<M1,M2> subMap(const M1 &m1,const M2 &m2)
190.380 - {
190.381 - return SubMap<M1,M2>(m1,m2);
190.382 - }
190.383 -
190.384 - ///Product of two maps
190.385 -
190.386 - ///This \ref concept::ReadMap "read only map" returns the product of the
190.387 - ///values returned by the two
190.388 - ///given
190.389 - ///maps. Its \c Key and \c Value will be inherited from \c M1.
190.390 - ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
190.391 -
190.392 - template<class M1,class M2>
190.393 - class MulMap
190.394 - {
190.395 - typename SmartConstReference<M1>::Type m1;
190.396 - typename SmartConstReference<M2>::Type m2;
190.397 - public:
190.398 -
190.399 - typedef True NeedCopy;
190.400 - typedef typename M1::Key Key;
190.401 - typedef typename M1::Value Value;
190.402 -
190.403 - ///Constructor
190.404 -
190.405 - ///\e
190.406 - ///
190.407 - MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.408 - Value operator[](Key k) const {return m1[k]*m2[k];}
190.409 - };
190.410 -
190.411 - ///Returns a \ref MulMap class
190.412 -
190.413 - ///This function just returns a \ref MulMap class.
190.414 - ///\relates MulMap
190.415 - template<class M1,class M2>
190.416 - inline MulMap<M1,M2> mulMap(const M1 &m1,const M2 &m2)
190.417 - {
190.418 - return MulMap<M1,M2>(m1,m2);
190.419 - }
190.420 -
190.421 - ///Scale a maps with a constant.
190.422 -
190.423 - ///This \ref concept::ReadMap "read only map" returns the value of the
190.424 - ///given map multipied with a constant value.
190.425 - ///Its \c Key and \c Value is inherited from \c M.
190.426 - ///
190.427 - ///Actually,
190.428 - ///\code
190.429 - /// ScaleMap<X> sc(x,v);
190.430 - ///\endcode
190.431 - ///it is equivalent with
190.432 - ///\code
190.433 - /// ConstMap<X::Key, X::Value> c_tmp(v);
190.434 - /// MulMap<X, ConstMap<X::Key, X::Value> > sc(x,v);
190.435 - ///\endcode
190.436 - template<class M>
190.437 - class ScaleMap
190.438 - {
190.439 - typename SmartConstReference<M>::Type m;
190.440 - typename M::Value v;
190.441 - public:
190.442 -
190.443 - typedef True NeedCopy;
190.444 - typedef typename M::Key Key;
190.445 - typedef typename M::Value Value;
190.446 -
190.447 - ///Constructor
190.448 -
190.449 - ///Constructor
190.450 - ///\param _m is the undelying map
190.451 - ///\param _v is the scaling value
190.452 - ScaleMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
190.453 - Value operator[](Key k) const {return m[k]*v;}
190.454 - };
190.455 -
190.456 - ///Returns an \ref ScaleMap class
190.457 -
190.458 - ///This function just returns an \ref ScaleMap class.
190.459 - ///\relates ScaleMap
190.460 - ///\todo A better name is required.
190.461 - template<class M>
190.462 - inline ScaleMap<M> scaleMap(const M &m,const typename M::Value &v)
190.463 - {
190.464 - return ScaleMap<M>(m,v);
190.465 - }
190.466 -
190.467 - ///Quotient of two maps
190.468 -
190.469 - ///This \ref concept::ReadMap "read only map" returns the quotient of the
190.470 - ///values returned by the two
190.471 - ///given maps. Its \c Key and \c Value will be inherited from \c M1.
190.472 - ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
190.473 -
190.474 - template<class M1,class M2>
190.475 - class DivMap
190.476 - {
190.477 - typename SmartConstReference<M1>::Type m1;
190.478 - typename SmartConstReference<M2>::Type m2;
190.479 - public:
190.480 -
190.481 - typedef True NeedCopy;
190.482 - typedef typename M1::Key Key;
190.483 - typedef typename M1::Value Value;
190.484 -
190.485 - ///Constructor
190.486 -
190.487 - ///\e
190.488 - ///
190.489 - DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.490 - Value operator[](Key k) const {return m1[k]/m2[k];}
190.491 - };
190.492 -
190.493 - ///Returns a \ref DivMap class
190.494 -
190.495 - ///This function just returns a \ref DivMap class.
190.496 - ///\relates DivMap
190.497 - template<class M1,class M2>
190.498 - inline DivMap<M1,M2> divMap(const M1 &m1,const M2 &m2)
190.499 - {
190.500 - return DivMap<M1,M2>(m1,m2);
190.501 - }
190.502 -
190.503 - ///Composition of two maps
190.504 -
190.505 - ///This \ref concept::ReadMap "read only map" returns the composition of
190.506 - ///two
190.507 - ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is
190.508 - ///of \c M2,
190.509 - ///then for
190.510 - ///\code
190.511 - /// ComposeMap<M1,M2> cm(m1,m2);
190.512 - ///\endcode
190.513 - /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>
190.514 - ///
190.515 - ///Its \c Key is inherited from \c M2 and its \c Value is from
190.516 - ///\c M1.
190.517 - ///The \c M2::Value must be convertible to \c M1::Key.
190.518 - ///\todo Check the requirements.
190.519 -
190.520 - template<class M1,class M2>
190.521 - class ComposeMap
190.522 - {
190.523 - typename SmartConstReference<M1>::Type m1;
190.524 - typename SmartConstReference<M2>::Type m2;
190.525 - public:
190.526 -
190.527 - typedef True NeedCopy;
190.528 - typedef typename M2::Key Key;
190.529 - typedef typename M1::Value Value;
190.530 -
190.531 - typedef True NeedCopy;
190.532 -
190.533 - ///Constructor
190.534 -
190.535 - ///\e
190.536 - ///
190.537 - ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.538 - Value operator[](Key k) const {return m1[m2[k]];}
190.539 - };
190.540 - ///Returns a \ref ComposeMap class
190.541 -
190.542 - ///This function just returns a \ref ComposeMap class.
190.543 - ///
190.544 - ///\relates ComposeMap
190.545 - template<class M1,class M2>
190.546 - inline ComposeMap<M1,M2> composeMap(const M1 &m1,const M2 &m2)
190.547 - {
190.548 - return ComposeMap<M1,M2>(m1,m2);
190.549 - }
190.550 -
190.551 - ///Combine of two maps using an STL (binary) functor.
190.552 -
190.553 - ///Combine of two maps using an STL (binary) functor.
190.554 - ///
190.555 - ///
190.556 - ///This \ref concept::ReadMap "read only map" takes to maps and a
190.557 - ///binary functor and returns the composition of
190.558 - ///two
190.559 - ///given maps unsing the functor.
190.560 - ///That is to say, if \c m1 and \c m2 is of type \c M1 and \c M2
190.561 - ///and \c f is of \c F,
190.562 - ///then for
190.563 - ///\code
190.564 - /// CombineMap<M1,M2,F,V> cm(m1,m2,f);
190.565 - ///\endcode
190.566 - /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>
190.567 - ///
190.568 - ///Its \c Key is inherited from \c M1 and its \c Value is \c V.
190.569 - ///The \c M2::Value and \c M1::Value must be convertible to the corresponding
190.570 - ///input parameter of \c F and the return type of \c F must be convertible
190.571 - ///to \c V.
190.572 - ///\todo Check the requirements.
190.573 -
190.574 - template<class M1,class M2,class F,class V = typename F::result_type>
190.575 - class CombineMap
190.576 - {
190.577 - typename SmartConstReference<M1>::Type m1;
190.578 - typename SmartConstReference<M2>::Type m2;
190.579 - F f;
190.580 - public:
190.581 -
190.582 - typedef True NeedCopy;
190.583 - typedef typename M1::Key Key;
190.584 - typedef V Value;
190.585 -
190.586 - ///Constructor
190.587 -
190.588 - ///\e
190.589 - ///
190.590 - CombineMap(const M1 &_m1,const M2 &_m2,const F &_f)
190.591 - : m1(_m1), m2(_m2), f(_f) {};
190.592 - Value operator[](Key k) const {return f(m1[k],m2[k]);}
190.593 - };
190.594 -
190.595 - ///Returns a \ref CombineMap class
190.596 -
190.597 - ///This function just returns a \ref CombineMap class.
190.598 - ///
190.599 - ///Only the first template parameter (the value type) must be given.
190.600 - ///
190.601 - ///For example if \c m1 and \c m2 are both \c double valued maps, then
190.602 - ///\code
190.603 - ///combineMap<double>(m1,m2,std::plus<double>)
190.604 - ///\endcode
190.605 - ///is equivalent with
190.606 - ///\code
190.607 - ///addMap(m1,m2)
190.608 - ///\endcode
190.609 - ///
190.610 - ///\relates CombineMap
190.611 - template<class M1,class M2,class F>
190.612 - inline CombineMap<M1,M2,F> combineMap(const M1 &m1,const M2 &m2,const F &f)
190.613 - {
190.614 - return CombineMap<M1,M2,F>(m1,m2,f);
190.615 - }
190.616 -
190.617 - ///Negative value of a map
190.618 -
190.619 - ///This \ref concept::ReadMap "read only map" returns the negative
190.620 - ///value of the
190.621 - ///value returned by the
190.622 - ///given map. Its \c Key and \c Value will be inherited from \c M.
190.623 - ///The unary \c - operator must be defined for \c Value, of course.
190.624 -
190.625 - template<class M>
190.626 - class NegMap
190.627 - {
190.628 - typename SmartConstReference<M>::Type m;
190.629 - public:
190.630 -
190.631 - typedef True NeedCopy;
190.632 - typedef typename M::Key Key;
190.633 - typedef typename M::Value Value;
190.634 -
190.635 - ///Constructor
190.636 -
190.637 - ///\e
190.638 - ///
190.639 - NegMap(const M &_m) : m(_m) {};
190.640 - Value operator[](Key k) const {return -m[k];}
190.641 - };
190.642 -
190.643 - ///Returns a \ref NegMap class
190.644 -
190.645 - ///This function just returns a \ref NegMap class.
190.646 - ///\relates NegMap
190.647 - template<class M>
190.648 - inline NegMap<M> negMap(const M &m)
190.649 - {
190.650 - return NegMap<M>(m);
190.651 - }
190.652 -
190.653 -
190.654 - ///Absolute value of a map
190.655 -
190.656 - ///This \ref concept::ReadMap "read only map" returns the absolute value
190.657 - ///of the
190.658 - ///value returned by the
190.659 - ///given map. Its \c Key and \c Value will be inherited
190.660 - ///from <tt>M</tt>. <tt>Value</tt>
190.661 - ///must be comparable to <tt>0</tt> and the unary <tt>-</tt>
190.662 - ///operator must be defined for it, of course.
190.663 - ///
190.664 - ///\bug We need a unified way to handle the situation below:
190.665 - ///\code
190.666 - /// struct _UnConvertible {};
190.667 - /// template<class A> inline A t_abs(A a) {return _UnConvertible();}
190.668 - /// template<> inline int t_abs<>(int n) {return abs(n);}
190.669 - /// template<> inline long int t_abs<>(long int n) {return labs(n);}
190.670 - /// template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);}
190.671 - /// template<> inline float t_abs<>(float n) {return fabsf(n);}
190.672 - /// template<> inline double t_abs<>(double n) {return fabs(n);}
190.673 - /// template<> inline long double t_abs<>(long double n) {return fabsl(n);}
190.674 - ///\endcode
190.675 -
190.676 -
190.677 - template<class M>
190.678 - class AbsMap
190.679 - {
190.680 - typename SmartConstReference<M>::Type m;
190.681 - public:
190.682 -
190.683 - typedef True NeedCopy;
190.684 - typedef typename M::Key Key;
190.685 - typedef typename M::Value Value;
190.686 -
190.687 - ///Constructor
190.688 -
190.689 - ///\e
190.690 - ///
190.691 - AbsMap(const M &_m) : m(_m) {};
190.692 - Value operator[](Key k) const {Value tmp=m[k]; return tmp>=0?tmp:-tmp;}
190.693 - };
190.694 -
190.695 - ///Returns a \ref AbsMap class
190.696 -
190.697 - ///This function just returns a \ref AbsMap class.
190.698 - ///\relates AbsMap
190.699 - template<class M>
190.700 - inline AbsMap<M> absMap(const M &m)
190.701 - {
190.702 - return AbsMap<M>(m);
190.703 - }
190.704 -
190.705 - ///Converts an STL style functor to a map
190.706 -
190.707 - ///This \ref concept::ReadMap "read only map" returns the value
190.708 - ///of a
190.709 - ///given map.
190.710 - ///
190.711 - ///Template parameters \c K and \c V will become its
190.712 - ///\c Key and \c Value. They must be given explicitely
190.713 - ///because a functor does not provide such typedefs.
190.714 - ///
190.715 - ///Parameter \c F is the type of the used functor.
190.716 -
190.717 -
190.718 - template<class K,class V,class F>
190.719 - class FunctorMap
190.720 - {
190.721 - const F &f;
190.722 - public:
190.723 -
190.724 - typedef True NeedCopy;
190.725 - typedef K Key;
190.726 - typedef V Value;
190.727 -
190.728 - ///Constructor
190.729 -
190.730 - ///\e
190.731 - ///
190.732 - FunctorMap(const F &_f) : f(_f) {};
190.733 - Value operator[](Key k) const {return f(k);}
190.734 - };
190.735 -
190.736 - ///Returns a \ref FunctorMap class
190.737 -
190.738 - ///This function just returns a \ref FunctorMap class.
190.739 - ///
190.740 - ///The third template parameter isn't necessary to be given.
190.741 - ///\relates FunctorMap
190.742 - template<class K,class V, class F>
190.743 - inline FunctorMap<K,V,F> functorMap(const F &f)
190.744 - {
190.745 - return FunctorMap<K,V,F>(f);
190.746 - }
190.747 -
190.748 - ///Converts a map to an STL style (unary) functor
190.749 -
190.750 - ///This class Converts a map to an STL style (unary) functor.
190.751 - ///that is it provides an <tt>operator()</tt> to read its values.
190.752 - ///
190.753 - ///For the sake of convenience it also works as
190.754 - ///a ususal \ref concept::ReadMap "readable map", i.e
190.755 - ///<tt>operator[]</tt> and the \c Key and \c Value typedefs also exist.
190.756 -
190.757 - template<class M>
190.758 - class MapFunctor
190.759 - {
190.760 - typename SmartConstReference<M>::Type m;
190.761 - public:
190.762 -
190.763 - typedef True NeedCopy;
190.764 - typedef typename M::Key argument_type;
190.765 - typedef typename M::Value result_type;
190.766 - typedef typename M::Key Key;
190.767 - typedef typename M::Value Value;
190.768 -
190.769 - ///Constructor
190.770 -
190.771 - ///\e
190.772 - ///
190.773 - MapFunctor(const M &_m) : m(_m) {};
190.774 - ///Returns a value of the map
190.775 -
190.776 - ///\e
190.777 - ///
190.778 - Value operator()(Key k) const {return m[k];}
190.779 - ///\e
190.780 - ///
190.781 - Value operator[](Key k) const {return m[k];}
190.782 - };
190.783 -
190.784 - ///Returns a \ref MapFunctor class
190.785 -
190.786 - ///This function just returns a \ref MapFunctor class.
190.787 - ///\relates MapFunctor
190.788 - template<class M>
190.789 - inline MapFunctor<M> mapFunctor(const M &m)
190.790 - {
190.791 - return MapFunctor<M>(m);
190.792 - }
190.793 -
190.794 -
190.795 - ///Apply all map setting operations to two maps
190.796 -
190.797 - ///This map has two \ref concept::WriteMap "writable map"
190.798 - ///parameters and each write request will be passed to both of them.
190.799 - ///If \c M1 is also \ref concept::ReadMap "readable",
190.800 - ///then the read operations will return the
190.801 - ///corresponding values of \c M1.
190.802 - ///
190.803 - ///The \c Key and \c Value will be inherited from \c M1.
190.804 - ///The \c Key and \c Value of M2 must be convertible from those of \c M1.
190.805 -
190.806 - template<class M1,class M2>
190.807 - class ForkMap
190.808 - {
190.809 - typename SmartConstReference<M1>::Type m1;
190.810 - typename SmartConstReference<M2>::Type m2;
190.811 - public:
190.812 -
190.813 - typedef True NeedCopy;
190.814 - typedef typename M1::Key Key;
190.815 - typedef typename M1::Value Value;
190.816 -
190.817 - ///Constructor
190.818 -
190.819 - ///\e
190.820 - ///
190.821 - ForkMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
190.822 - Value operator[](Key k) const {return m1[k];}
190.823 - void set(Key k,const Value &v) {m1.set(k,v); m2.set(k,v);}
190.824 - };
190.825 -
190.826 - ///Returns an \ref ForkMap class
190.827 -
190.828 - ///This function just returns an \ref ForkMap class.
190.829 - ///\todo How to call these type of functions?
190.830 - ///
190.831 - ///\relates ForkMap
190.832 - ///\todo Wrong scope in Doxygen when \c \\relates is used
190.833 - template<class M1,class M2>
190.834 - inline ForkMap<M1,M2> forkMap(const M1 &m1,const M2 &m2)
190.835 - {
190.836 - return ForkMap<M1,M2>(m1,m2);
190.837 - }
190.838 -
190.839 - /// @}
190.840 -
190.841 -}
190.842 -
190.843 -
190.844 -#endif // LEMON_MAPS_H
191.1 --- a/src/lemon/max_matching.h Sat May 21 21:04:57 2005 +0000
191.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
191.3 @@ -1,583 +0,0 @@
191.4 -/* -*- C++ -*-
191.5 - * src/lemon/max_matching.h - Part of LEMON, a generic C++ optimization library
191.6 - *
191.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
191.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
191.9 - *
191.10 - * Permission to use, modify and distribute this software is granted
191.11 - * provided that this copyright notice appears in all copies. For
191.12 - * precise terms see the accompanying LICENSE file.
191.13 - *
191.14 - * This software is provided "AS IS" with no warranty of any kind,
191.15 - * express or implied, and with no claim as to its suitability for any
191.16 - * purpose.
191.17 - *
191.18 - */
191.19 -
191.20 -#ifndef LEMON_MAX_MATCHING_H
191.21 -#define LEMON_MAX_MATCHING_H
191.22 -
191.23 -#include <queue>
191.24 -#include <lemon/invalid.h>
191.25 -#include <lemon/unionfind.h>
191.26 -#include <lemon/graph_utils.h>
191.27 -
191.28 -///\ingroup galgs
191.29 -///\file
191.30 -///\brief Maximum matching algorithm.
191.31 -
191.32 -namespace lemon {
191.33 -
191.34 - /// \addtogroup galgs
191.35 - /// @{
191.36 -
191.37 - ///Edmonds' alternating forest maximum matching algorithm.
191.38 -
191.39 - ///This class provides Edmonds' alternating forest matching
191.40 - ///algorithm. The starting matching (if any) can be passed to the
191.41 - ///algorithm using read-in functions \ref readNMapNode, \ref
191.42 - ///readNMapEdge or \ref readEMapBool depending on the container. The
191.43 - ///resulting maximum matching can be attained by write-out functions
191.44 - ///\ref writeNMapNode, \ref writeNMapEdge or \ref writeEMapBool
191.45 - ///depending on the preferred container.
191.46 - ///
191.47 - ///The dual side of a matching is a map of the nodes to
191.48 - ///MaxMatching::pos_enum, having values D, A and C showing the
191.49 - ///Gallai-Edmonds decomposition of the graph. The nodes in D induce
191.50 - ///a graph with factor-critical components, the nodes in A form the
191.51 - ///barrier, and the nodes in C induce a graph having a perfect
191.52 - ///matching. This decomposition can be attained by calling \ref
191.53 - ///writePos after running the algorithm.
191.54 - ///
191.55 - ///\param Graph The undirected graph type the algorithm runs on.
191.56 - ///
191.57 - ///\author Jacint Szabo
191.58 - template <typename Graph>
191.59 - class MaxMatching {
191.60 -
191.61 - protected:
191.62 -
191.63 - typedef typename Graph::Node Node;
191.64 - typedef typename Graph::Edge Edge;
191.65 - typedef typename Graph::UndirEdge UndirEdge;
191.66 - typedef typename Graph::UndirEdgeIt UndirEdgeIt;
191.67 - typedef typename Graph::NodeIt NodeIt;
191.68 - typedef typename Graph::IncEdgeIt IncEdgeIt;
191.69 -
191.70 - typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
191.71 -
191.72 - public:
191.73 -
191.74 - ///Indicates the Gallai-Edmonds decomposition of the graph.
191.75 -
191.76 - ///Indicates the Gallai-Edmonds decomposition of the graph, which
191.77 - ///shows an upper bound on the size of a maximum matching. The
191.78 - ///nodes with pos_enum \c D induce a graph with factor-critical
191.79 - ///components, the nodes in \c A form the canonical barrier, and the
191.80 - ///nodes in \c C induce a graph having a perfect matching.
191.81 - enum pos_enum {
191.82 - D=0,
191.83 - A=1,
191.84 - C=2
191.85 - };
191.86 -
191.87 - protected:
191.88 -
191.89 - static const int HEUR_density=2;
191.90 - const Graph& g;
191.91 - typename Graph::template NodeMap<Node> _mate;
191.92 - typename Graph::template NodeMap<pos_enum> position;
191.93 -
191.94 - public:
191.95 -
191.96 - MaxMatching(const Graph& _g) : g(_g), _mate(_g,INVALID), position(_g) {}
191.97 -
191.98 - ///Runs Edmonds' algorithm.
191.99 -
191.100 - ///Runs Edmonds' algorithm for sparse graphs (number of edges <
191.101 - ///2*number of nodes), and a heuristical Edmonds' algorithm with a
191.102 - ///heuristic of postponing shrinks for dense graphs.
191.103 - inline void run();
191.104 -
191.105 - ///Runs Edmonds' algorithm.
191.106 -
191.107 - ///If heur=0 it runs Edmonds' algorithm. If heur=1 it runs
191.108 - ///Edmonds' algorithm with a heuristic of postponing shrinks,
191.109 - ///giving a faster algorithm for dense graphs.
191.110 - void runEdmonds( int heur );
191.111 -
191.112 - ///Finds a greedy matching starting from the actual matching.
191.113 -
191.114 - ///Starting form the actual matching stored, it finds a maximal
191.115 - ///greedy matching.
191.116 - void greedyMatching();
191.117 -
191.118 - ///Returns the size of the actual matching stored.
191.119 -
191.120 - ///Returns the size of the actual matching stored. After \ref
191.121 - ///run() it returns the size of a maximum matching in the graph.
191.122 - int size() const;
191.123 -
191.124 - ///Resets the actual matching to the empty matching.
191.125 -
191.126 - ///Resets the actual matching to the empty matching.
191.127 - ///
191.128 - void resetMatching();
191.129 -
191.130 - ///Returns the mate of a node in the actual matching.
191.131 -
191.132 - ///Returns the mate of a \c node in the actual matching.
191.133 - ///Returns INVALID if the \c node is not covered by the actual matching.
191.134 - Node mate(Node& node) const {
191.135 - return _mate[node];
191.136 - }
191.137 -
191.138 - ///Reads a matching from a \c Node valued \c Node map.
191.139 -
191.140 - ///Reads a matching from a \c Node valued \c Node map. This map
191.141 - ///must be \e symmetric, i.e. if \c map[u]==v then \c map[v]==u
191.142 - ///must hold, and \c uv will be an edge of the matching.
191.143 - template<typename NMapN>
191.144 - void readNMapNode(NMapN& map) {
191.145 - for(NodeIt v(g); v!=INVALID; ++v) {
191.146 - _mate.set(v,map[v]);
191.147 - }
191.148 - }
191.149 -
191.150 - ///Writes the stored matching to a \c Node valued \c Node map.
191.151 -
191.152 - ///Writes the stored matching to a \c Node valued \c Node map. The
191.153 - ///resulting map will be \e symmetric, i.e. if \c map[u]==v then \c
191.154 - ///map[v]==u will hold, and now \c uv is an edge of the matching.
191.155 - template<typename NMapN>
191.156 - void writeNMapNode (NMapN& map) const {
191.157 - for(NodeIt v(g); v!=INVALID; ++v) {
191.158 - map.set(v,_mate[v]);
191.159 - }
191.160 - }
191.161 -
191.162 - ///Reads a matching from an \c UndirEdge valued \c Node map.
191.163 -
191.164 - ///Reads a matching from an \c UndirEdge valued \c Node map. \c
191.165 - ///map[v] must be an \c UndirEdge incident to \c v. This map must
191.166 - ///have the property that if \c g.oppositeNode(u,map[u])==v then
191.167 - ///\c \c g.oppositeNode(v,map[v])==u holds, and now some edge
191.168 - ///joining \c u to \c v will be an edge of the matching.
191.169 - template<typename NMapE>
191.170 - void readNMapEdge(NMapE& map) {
191.171 - for(NodeIt v(g); v!=INVALID; ++v) {
191.172 - UndirEdge e=map[v];
191.173 - if ( e!=INVALID )
191.174 - _mate.set(v,g.oppositeNode(v,e));
191.175 - }
191.176 - }
191.177 -
191.178 - ///Writes the matching stored to an \c UndirEdge valued \c Node map.
191.179 -
191.180 - ///Writes the stored matching to an \c UndirEdge valued \c Node
191.181 - ///map. \c map[v] will be an \c UndirEdge incident to \c v. This
191.182 - ///map will have the property that if \c g.oppositeNode(u,map[u])
191.183 - ///== v then \c map[u]==map[v] holds, and now this edge is an edge
191.184 - ///of the matching.
191.185 - template<typename NMapE>
191.186 - void writeNMapEdge (NMapE& map) const {
191.187 - typename Graph::template NodeMap<bool> todo(g,true);
191.188 - for(NodeIt v(g); v!=INVALID; ++v) {
191.189 - if ( todo[v] && _mate[v]!=INVALID ) {
191.190 - Node u=_mate[v];
191.191 - for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
191.192 - if ( g.runningNode(e) == u ) {
191.193 - map.set(u,e);
191.194 - map.set(v,e);
191.195 - todo.set(u,false);
191.196 - todo.set(v,false);
191.197 - break;
191.198 - }
191.199 - }
191.200 - }
191.201 - }
191.202 - }
191.203 -
191.204 -
191.205 - ///Reads a matching from a \c bool valued \c Edge map.
191.206 -
191.207 - ///Reads a matching from a \c bool valued \c Edge map. This map
191.208 - ///must have the property that there are no two incident edges \c
191.209 - ///e, \c f with \c map[e]==map[f]==true. The edges \c e with \c
191.210 - ///map[e]==true form the matching.
191.211 - template<typename EMapB>
191.212 - void readEMapBool(EMapB& map) {
191.213 - for(UndirEdgeIt e(g); e!=INVALID; ++e) {
191.214 - if ( map[e] ) {
191.215 - Node u=g.source(e);
191.216 - Node v=g.target(e);
191.217 - _mate.set(u,v);
191.218 - _mate.set(v,u);
191.219 - }
191.220 - }
191.221 - }
191.222 -
191.223 -
191.224 - ///Writes the matching stored to a \c bool valued \c Edge map.
191.225 -
191.226 - ///Writes the matching stored to a \c bool valued \c Edge
191.227 - ///map. This map will have the property that there are no two
191.228 - ///incident edges \c e, \c f with \c map[e]==map[f]==true. The
191.229 - ///edges \c e with \c map[e]==true form the matching.
191.230 - template<typename EMapB>
191.231 - void writeEMapBool (EMapB& map) const {
191.232 - for(UndirEdgeIt e(g); e!=INVALID; ++e) map.set(e,false);
191.233 -
191.234 - typename Graph::template NodeMap<bool> todo(g,true);
191.235 - for(NodeIt v(g); v!=INVALID; ++v) {
191.236 - if ( todo[v] && _mate[v]!=INVALID ) {
191.237 - Node u=_mate[v];
191.238 - for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
191.239 - if ( g.runningNode(e) == u ) {
191.240 - map.set(e,true);
191.241 - todo.set(u,false);
191.242 - todo.set(v,false);
191.243 - break;
191.244 - }
191.245 - }
191.246 - }
191.247 - }
191.248 - }
191.249 -
191.250 -
191.251 - ///Writes the canonical decomposition of the graph after running
191.252 - ///the algorithm.
191.253 -
191.254 - ///After calling any run methods of the class, it writes the
191.255 - ///Gallai-Edmonds canonical decomposition of the graph. \c map
191.256 - ///must be a node map of \ref pos_enum 's.
191.257 - template<typename NMapEnum>
191.258 - void writePos (NMapEnum& map) const {
191.259 - for(NodeIt v(g); v!=INVALID; ++v) map.set(v,position[v]);
191.260 - }
191.261 -
191.262 - private:
191.263 -
191.264 -
191.265 - void lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,
191.266 - UFE& blossom, UFE& tree);
191.267 -
191.268 - void normShrink(Node v, typename Graph::template NodeMap<Node>& ear,
191.269 - UFE& blossom, UFE& tree);
191.270 -
191.271 - bool noShrinkStep(Node x, typename Graph::template NodeMap<Node>& ear,
191.272 - UFE& blossom, UFE& tree, std::queue<Node>& Q);
191.273 -
191.274 - void shrinkStep(Node& top, Node& middle, Node& bottom,
191.275 - typename Graph::template NodeMap<Node>& ear,
191.276 - UFE& blossom, UFE& tree, std::queue<Node>& Q);
191.277 -
191.278 - void augment(Node x, typename Graph::template NodeMap<Node>& ear,
191.279 - UFE& blossom, UFE& tree);
191.280 -
191.281 - };
191.282 -
191.283 -
191.284 - // **********************************************************************
191.285 - // IMPLEMENTATIONS
191.286 - // **********************************************************************
191.287 -
191.288 -
191.289 - template <typename Graph>
191.290 - void MaxMatching<Graph>::run() {
191.291 - if ( countUndirEdges(g) < HEUR_density*countNodes(g) ) {
191.292 - greedyMatching();
191.293 - runEdmonds(0);
191.294 - } else runEdmonds(1);
191.295 - }
191.296 -
191.297 -
191.298 - template <typename Graph>
191.299 - void MaxMatching<Graph>::runEdmonds( int heur=1 ) {
191.300 -
191.301 - for(NodeIt v(g); v!=INVALID; ++v)
191.302 - position.set(v,C);
191.303 -
191.304 - typename Graph::template NodeMap<Node> ear(g,INVALID);
191.305 - //undefined for the base nodes of the blossoms (i.e. for the
191.306 - //representative elements of UFE blossom) and for the nodes in C
191.307 -
191.308 - typename UFE::MapType blossom_base(g);
191.309 - UFE blossom(blossom_base);
191.310 - typename UFE::MapType tree_base(g);
191.311 - UFE tree(tree_base);
191.312 - //If these UFE's would be members of the class then also
191.313 - //blossom_base and tree_base should be a member.
191.314 -
191.315 - for(NodeIt v(g); v!=INVALID; ++v) {
191.316 - if ( position[v]==C && _mate[v]==INVALID ) {
191.317 - blossom.insert(v);
191.318 - tree.insert(v);
191.319 - position.set(v,D);
191.320 - if ( heur == 1 ) lateShrink( v, ear, blossom, tree );
191.321 - else normShrink( v, ear, blossom, tree );
191.322 - }
191.323 - }
191.324 - }
191.325 -
191.326 -
191.327 - template <typename Graph>
191.328 - void MaxMatching<Graph>::lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,
191.329 - UFE& blossom, UFE& tree) {
191.330 -
191.331 - std::queue<Node> Q; //queue of the totally unscanned nodes
191.332 - Q.push(v);
191.333 - std::queue<Node> R;
191.334 - //queue of the nodes which must be scanned for a possible shrink
191.335 -
191.336 - while ( !Q.empty() ) {
191.337 - Node x=Q.front();
191.338 - Q.pop();
191.339 - if ( noShrinkStep( x, ear, blossom, tree, Q ) ) return;
191.340 - else R.push(x);
191.341 - }
191.342 -
191.343 - while ( !R.empty() ) {
191.344 - Node x=R.front();
191.345 - R.pop();
191.346 -
191.347 - for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) {
191.348 - Node y=g.runningNode(e);
191.349 -
191.350 - if ( position[y] == D && blossom.find(x) != blossom.find(y) ) {
191.351 - //x and y must be in the same tree
191.352 -
191.353 - typename Graph::template NodeMap<bool> path(g,false);
191.354 -
191.355 - Node b=blossom.find(x);
191.356 - path.set(b,true);
191.357 - b=_mate[b];
191.358 - while ( b!=INVALID ) {
191.359 - b=blossom.find(ear[b]);
191.360 - path.set(b,true);
191.361 - b=_mate[b];
191.362 - } //going till the root
191.363 -
191.364 - Node top=y;
191.365 - Node middle=blossom.find(top);
191.366 - Node bottom=x;
191.367 - while ( !path[middle] )
191.368 - shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
191.369 -
191.370 - Node base=middle;
191.371 - top=x;
191.372 - middle=blossom.find(top);
191.373 - bottom=y;
191.374 - Node blossom_base=blossom.find(base);
191.375 - while ( middle!=blossom_base )
191.376 - shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
191.377 -
191.378 - blossom.makeRep(base);
191.379 - } // if shrink is needed
191.380 -
191.381 - while ( !Q.empty() ) {
191.382 - Node x=Q.front();
191.383 - Q.pop();
191.384 - if ( noShrinkStep(x, ear, blossom, tree, Q) ) return;
191.385 - else R.push(x);
191.386 - }
191.387 - } //for e
191.388 - } // while ( !R.empty() )
191.389 - }
191.390 -
191.391 -
191.392 - template <typename Graph>
191.393 - void MaxMatching<Graph>::normShrink(Node v,
191.394 - typename Graph::template
191.395 - NodeMap<Node>& ear,
191.396 - UFE& blossom, UFE& tree) {
191.397 - std::queue<Node> Q; //queue of the unscanned nodes
191.398 - Q.push(v);
191.399 - while ( !Q.empty() ) {
191.400 -
191.401 - Node x=Q.front();
191.402 - Q.pop();
191.403 -
191.404 - for( IncEdgeIt e(g,x); e!=INVALID; ++e ) {
191.405 - Node y=g.runningNode(e);
191.406 -
191.407 - switch ( position[y] ) {
191.408 - case D: //x and y must be in the same tree
191.409 -
191.410 - if ( blossom.find(x) != blossom.find(y) ) { //shrink
191.411 - typename Graph::template NodeMap<bool> path(g,false);
191.412 -
191.413 - Node b=blossom.find(x);
191.414 - path.set(b,true);
191.415 - b=_mate[b];
191.416 - while ( b!=INVALID ) {
191.417 - b=blossom.find(ear[b]);
191.418 - path.set(b,true);
191.419 - b=_mate[b];
191.420 - } //going till the root
191.421 -
191.422 - Node top=y;
191.423 - Node middle=blossom.find(top);
191.424 - Node bottom=x;
191.425 - while ( !path[middle] )
191.426 - shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
191.427 -
191.428 - Node base=middle;
191.429 - top=x;
191.430 - middle=blossom.find(top);
191.431 - bottom=y;
191.432 - Node blossom_base=blossom.find(base);
191.433 - while ( middle!=blossom_base )
191.434 - shrinkStep(top, middle, bottom, ear, blossom, tree, Q);
191.435 -
191.436 - blossom.makeRep(base);
191.437 - }
191.438 - break;
191.439 - case C:
191.440 - if ( _mate[y]!=INVALID ) { //grow
191.441 -
191.442 - ear.set(y,x);
191.443 - Node w=_mate[y];
191.444 - blossom.insert(w);
191.445 - position.set(y,A);
191.446 - position.set(w,D);
191.447 - tree.insert(y);
191.448 - tree.insert(w);
191.449 - tree.join(y,blossom.find(x));
191.450 - tree.join(w,y);
191.451 - Q.push(w);
191.452 - } else { //augment
191.453 - augment(x, ear, blossom, tree);
191.454 - _mate.set(x,y);
191.455 - _mate.set(y,x);
191.456 - return;
191.457 - } //if
191.458 - break;
191.459 - default: break;
191.460 - }
191.461 - }
191.462 - }
191.463 - }
191.464 -
191.465 - template <typename Graph>
191.466 - void MaxMatching<Graph>::greedyMatching() {
191.467 - for(NodeIt v(g); v!=INVALID; ++v)
191.468 - if ( _mate[v]==INVALID ) {
191.469 - for( IncEdgeIt e(g,v); e!=INVALID ; ++e ) {
191.470 - Node y=g.runningNode(e);
191.471 - if ( _mate[y]==INVALID && y!=v ) {
191.472 - _mate.set(v,y);
191.473 - _mate.set(y,v);
191.474 - break;
191.475 - }
191.476 - }
191.477 - }
191.478 - }
191.479 -
191.480 - template <typename Graph>
191.481 - int MaxMatching<Graph>::size() const {
191.482 - int s=0;
191.483 - for(NodeIt v(g); v!=INVALID; ++v) {
191.484 - if ( _mate[v]!=INVALID ) {
191.485 - ++s;
191.486 - }
191.487 - }
191.488 - return s/2;
191.489 - }
191.490 -
191.491 - template <typename Graph>
191.492 - void MaxMatching<Graph>::resetMatching() {
191.493 - for(NodeIt v(g); v!=INVALID; ++v)
191.494 - _mate.set(v,INVALID);
191.495 - }
191.496 -
191.497 - template <typename Graph>
191.498 - bool MaxMatching<Graph>::noShrinkStep(Node x,
191.499 - typename Graph::template
191.500 - NodeMap<Node>& ear,
191.501 - UFE& blossom, UFE& tree,
191.502 - std::queue<Node>& Q) {
191.503 - for( IncEdgeIt e(g,x); e!= INVALID; ++e ) {
191.504 - Node y=g.runningNode(e);
191.505 -
191.506 - if ( position[y]==C ) {
191.507 - if ( _mate[y]!=INVALID ) { //grow
191.508 - ear.set(y,x);
191.509 - Node w=_mate[y];
191.510 - blossom.insert(w);
191.511 - position.set(y,A);
191.512 - position.set(w,D);
191.513 - tree.insert(y);
191.514 - tree.insert(w);
191.515 - tree.join(y,blossom.find(x));
191.516 - tree.join(w,y);
191.517 - Q.push(w);
191.518 - } else { //augment
191.519 - augment(x, ear, blossom, tree);
191.520 - _mate.set(x,y);
191.521 - _mate.set(y,x);
191.522 - return true;
191.523 - }
191.524 - }
191.525 - }
191.526 - return false;
191.527 - }
191.528 -
191.529 - template <typename Graph>
191.530 - void MaxMatching<Graph>::shrinkStep(Node& top, Node& middle, Node& bottom,
191.531 - typename Graph::template
191.532 - NodeMap<Node>& ear,
191.533 - UFE& blossom, UFE& tree,
191.534 - std::queue<Node>& Q) {
191.535 - ear.set(top,bottom);
191.536 - Node t=top;
191.537 - while ( t!=middle ) {
191.538 - Node u=_mate[t];
191.539 - t=ear[u];
191.540 - ear.set(t,u);
191.541 - }
191.542 - bottom=_mate[middle];
191.543 - position.set(bottom,D);
191.544 - Q.push(bottom);
191.545 - top=ear[bottom];
191.546 - Node oldmiddle=middle;
191.547 - middle=blossom.find(top);
191.548 - tree.erase(bottom);
191.549 - tree.erase(oldmiddle);
191.550 - blossom.insert(bottom);
191.551 - blossom.join(bottom, oldmiddle);
191.552 - blossom.join(top, oldmiddle);
191.553 - }
191.554 -
191.555 - template <typename Graph>
191.556 - void MaxMatching<Graph>::augment(Node x,
191.557 - typename Graph::template NodeMap<Node>& ear,
191.558 - UFE& blossom, UFE& tree) {
191.559 - Node v=_mate[x];
191.560 - while ( v!=INVALID ) {
191.561 -
191.562 - Node u=ear[v];
191.563 - _mate.set(v,u);
191.564 - Node tmp=v;
191.565 - v=_mate[u];
191.566 - _mate.set(u,tmp);
191.567 - }
191.568 - typename UFE::ItemIt it;
191.569 - for (tree.first(it,blossom.find(x)); tree.valid(it); tree.next(it)) {
191.570 - if ( position[it] == D ) {
191.571 - typename UFE::ItemIt b_it;
191.572 - for (blossom.first(b_it,it); blossom.valid(b_it); blossom.next(b_it)) {
191.573 - position.set( b_it ,C);
191.574 - }
191.575 - blossom.eraseClass(it);
191.576 - } else position.set( it ,C);
191.577 - }
191.578 - tree.eraseClass(x);
191.579 -
191.580 - }
191.581 -
191.582 - /// @}
191.583 -
191.584 -} //END OF NAMESPACE LEMON
191.585 -
191.586 -#endif //LEMON_MAX_MATCHING_H
192.1 --- a/src/lemon/min_cost_flow.h Sat May 21 21:04:57 2005 +0000
192.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
192.3 @@ -1,260 +0,0 @@
192.4 -/* -*- C++ -*-
192.5 - * src/lemon/min_cost_flow.h - Part of LEMON, a generic C++ optimization library
192.6 - *
192.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
192.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
192.9 - *
192.10 - * Permission to use, modify and distribute this software is granted
192.11 - * provided that this copyright notice appears in all copies. For
192.12 - * precise terms see the accompanying LICENSE file.
192.13 - *
192.14 - * This software is provided "AS IS" with no warranty of any kind,
192.15 - * express or implied, and with no claim as to its suitability for any
192.16 - * purpose.
192.17 - *
192.18 - */
192.19 -
192.20 -#ifndef LEMON_MIN_COST_FLOW_H
192.21 -#define LEMON_MIN_COST_FLOW_H
192.22 -
192.23 -///\ingroup flowalgs
192.24 -///\file
192.25 -///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost
192.26 -
192.27 -
192.28 -#include <lemon/dijkstra.h>
192.29 -#include <lemon/graph_adaptor.h>
192.30 -#include <lemon/maps.h>
192.31 -#include <vector>
192.32 -
192.33 -namespace lemon {
192.34 -
192.35 -/// \addtogroup flowalgs
192.36 -/// @{
192.37 -
192.38 - ///\brief Implementation of an algorithm for finding a flow of value \c k
192.39 - ///(for small values of \c k) having minimal total cost between 2 nodes
192.40 - ///
192.41 - ///
192.42 - /// The class \ref lemon::MinCostFlow "MinCostFlow" implements an
192.43 - /// algorithm for finding a flow of value \c k having minimal total
192.44 - /// cost from a given source node to a given target node in an
192.45 - /// edge-weighted directed graph. To this end, the edge-capacities
192.46 - /// and edge-weights have to be nonnegative. The edge-capacities
192.47 - /// should be integers, but the edge-weights can be integers, reals
192.48 - /// or of other comparable numeric type. This algorithm is intended
192.49 - /// to be used only for small values of \c k, since it is only
192.50 - /// polynomial in k, not in the length of k (which is log k): in
192.51 - /// order to find the minimum cost flow of value \c k it finds the
192.52 - /// minimum cost flow of value \c i for every \c i between 0 and \c
192.53 - /// k.
192.54 - ///
192.55 - ///\param Graph The directed graph type the algorithm runs on.
192.56 - ///\param LengthMap The type of the length map.
192.57 - ///\param CapacityMap The capacity map type.
192.58 - ///
192.59 - ///\author Attila Bernath
192.60 - template <typename Graph, typename LengthMap, typename CapacityMap>
192.61 - class MinCostFlow {
192.62 -
192.63 - typedef typename LengthMap::Value Length;
192.64 -
192.65 - //Warning: this should be integer type
192.66 - typedef typename CapacityMap::Value Capacity;
192.67 -
192.68 - typedef typename Graph::Node Node;
192.69 - typedef typename Graph::NodeIt NodeIt;
192.70 - typedef typename Graph::Edge Edge;
192.71 - typedef typename Graph::OutEdgeIt OutEdgeIt;
192.72 - typedef typename Graph::template EdgeMap<int> EdgeIntMap;
192.73 -
192.74 - typedef ResGraphAdaptor<const Graph,int,CapacityMap,EdgeIntMap> ResGW;
192.75 - typedef typename ResGW::Edge ResGraphEdge;
192.76 -
192.77 - protected:
192.78 -
192.79 - const Graph& g;
192.80 - const LengthMap& length;
192.81 - const CapacityMap& capacity;
192.82 -
192.83 - EdgeIntMap flow;
192.84 - typedef typename Graph::template NodeMap<Length> PotentialMap;
192.85 - PotentialMap potential;
192.86 -
192.87 - Node s;
192.88 - Node t;
192.89 -
192.90 - Length total_length;
192.91 -
192.92 - class ModLengthMap {
192.93 - typedef typename Graph::template NodeMap<Length> NodeMap;
192.94 - const ResGW& g;
192.95 - const LengthMap &length;
192.96 - const NodeMap &pot;
192.97 - public :
192.98 - typedef typename LengthMap::Key Key;
192.99 - typedef typename LengthMap::Value Value;
192.100 -
192.101 - ModLengthMap(const ResGW& _g,
192.102 - const LengthMap &_length, const NodeMap &_pot) :
192.103 - g(_g), /*rev(_rev),*/ length(_length), pot(_pot) { }
192.104 -
192.105 - Value operator[](typename ResGW::Edge e) const {
192.106 - if (g.forward(e))
192.107 - return length[e]-(pot[g.target(e)]-pot[g.source(e)]);
192.108 - else
192.109 - return -length[e]-(pot[g.target(e)]-pot[g.source(e)]);
192.110 - }
192.111 -
192.112 - }; //ModLengthMap
192.113 -
192.114 - ResGW res_graph;
192.115 - ModLengthMap mod_length;
192.116 - Dijkstra<ResGW, ModLengthMap> dijkstra;
192.117 -
192.118 - public :
192.119 -
192.120 - /*! \brief The constructor of the class.
192.121 -
192.122 - \param _g The directed graph the algorithm runs on.
192.123 - \param _length The length (weight or cost) of the edges.
192.124 - \param _cap The capacity of the edges.
192.125 - \param _s Source node.
192.126 - \param _t Target node.
192.127 - */
192.128 - MinCostFlow(Graph& _g, LengthMap& _length, CapacityMap& _cap,
192.129 - Node _s, Node _t) :
192.130 - g(_g), length(_length), capacity(_cap), flow(_g), potential(_g),
192.131 - s(_s), t(_t),
192.132 - res_graph(g, capacity, flow),
192.133 - mod_length(res_graph, length, potential),
192.134 - dijkstra(res_graph, mod_length) {
192.135 - reset();
192.136 - }
192.137 -
192.138 - /*! Tries to augment the flow between s and t by 1.
192.139 - The return value shows if the augmentation is successful.
192.140 - */
192.141 - bool augment() {
192.142 - dijkstra.run(s);
192.143 - if (!dijkstra.reached(t)) {
192.144 -
192.145 - //Unsuccessful augmentation.
192.146 - return false;
192.147 - } else {
192.148 -
192.149 - //We have to change the potential
192.150 - for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n)
192.151 - potential.set(n, potential[n]+dijkstra.distMap()[n]);
192.152 -
192.153 - //Augmenting on the shortest path
192.154 - Node n=t;
192.155 - ResGraphEdge e;
192.156 - while (n!=s){
192.157 - e = dijkstra.pred(n);
192.158 - n = dijkstra.predNode(n);
192.159 - res_graph.augment(e,1);
192.160 - //Let's update the total length
192.161 - if (res_graph.forward(e))
192.162 - total_length += length[e];
192.163 - else
192.164 - total_length -= length[e];
192.165 - }
192.166 -
192.167 - return true;
192.168 - }
192.169 - }
192.170 -
192.171 - /*! \brief Runs the algorithm.
192.172 -
192.173 - Runs the algorithm.
192.174 - Returns k if there is a flow of value at least k from s to t.
192.175 - Otherwise it returns the maximum value of a flow from s to t.
192.176 -
192.177 - \param k The value of the flow we are looking for.
192.178 -
192.179 - \todo May be it does make sense to be able to start with a nonzero
192.180 - feasible primal-dual solution pair as well.
192.181 -
192.182 - \todo If the actual flow value is bigger than k, then everything is
192.183 - cleared and the algorithm starts from zero flow. Is it a good approach?
192.184 - */
192.185 - int run(int k) {
192.186 - if (flowValue()>k) reset();
192.187 - while (flowValue()<k && augment()) { }
192.188 - return flowValue();
192.189 - }
192.190 -
192.191 - /*! \brief The class is reset to zero flow and potential.
192.192 - The class is reset to zero flow and potential.
192.193 - */
192.194 - void reset() {
192.195 - total_length=0;
192.196 - for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
192.197 - for (typename Graph::NodeIt n(g); n!=INVALID; ++n) potential.set(n, 0);
192.198 - }
192.199 -
192.200 - /*! Returns the value of the actual flow.
192.201 - */
192.202 - int flowValue() const {
192.203 - int i=0;
192.204 - for (typename Graph::OutEdgeIt e(g, s); e!=INVALID; ++e) i+=flow[e];
192.205 - for (typename Graph::InEdgeIt e(g, s); e!=INVALID; ++e) i-=flow[e];
192.206 - return i;
192.207 - }
192.208 -
192.209 - /// Total weight of the found flow.
192.210 -
192.211 - /// This function gives back the total weight of the found flow.
192.212 - Length totalLength(){
192.213 - return total_length;
192.214 - }
192.215 -
192.216 - ///Returns a const reference to the EdgeMap \c flow.
192.217 -
192.218 - ///Returns a const reference to the EdgeMap \c flow.
192.219 - const EdgeIntMap &getFlow() const { return flow;}
192.220 -
192.221 - /*! \brief Returns a const reference to the NodeMap \c potential (the dual solution).
192.222 -
192.223 - Returns a const reference to the NodeMap \c potential (the dual solution).
192.224 - */
192.225 - const PotentialMap &getPotential() const { return potential;}
192.226 -
192.227 - /*! \brief Checking the complementary slackness optimality criteria.
192.228 -
192.229 - This function checks, whether the given flow and potential
192.230 - satisfy the complementary slackness conditions (i.e. these are optimal).
192.231 - This function only checks optimality, doesn't bother with feasibility.
192.232 - For testing purpose.
192.233 - */
192.234 - bool checkComplementarySlackness(){
192.235 - Length mod_pot;
192.236 - Length fl_e;
192.237 - for(typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
192.238 - //C^{\Pi}_{i,j}
192.239 - mod_pot = length[e]-potential[g.target(e)]+potential[g.source(e)];
192.240 - fl_e = flow[e];
192.241 - if (0<fl_e && fl_e<capacity[e]) {
192.242 - /// \todo better comparison is needed for real types, moreover,
192.243 - /// this comparison here is superfluous.
192.244 - if (mod_pot != 0)
192.245 - return false;
192.246 - }
192.247 - else {
192.248 - if (mod_pot > 0 && fl_e != 0)
192.249 - return false;
192.250 - if (mod_pot < 0 && fl_e != capacity[e])
192.251 - return false;
192.252 - }
192.253 - }
192.254 - return true;
192.255 - }
192.256 -
192.257 - }; //class MinCostFlow
192.258 -
192.259 - ///@}
192.260 -
192.261 -} //namespace lemon
192.262 -
192.263 -#endif //LEMON_MIN_COST_FLOW_H
193.1 --- a/src/lemon/path.h Sat May 21 21:04:57 2005 +0000
193.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
193.3 @@ -1,703 +0,0 @@
193.4 -/* -*- C++ -*-
193.5 - * src/lemon/path.h - Part of LEMON, a generic C++ optimization library
193.6 - *
193.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
193.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
193.9 - *
193.10 - * Permission to use, modify and distribute this software is granted
193.11 - * provided that this copyright notice appears in all copies. For
193.12 - * precise terms see the accompanying LICENSE file.
193.13 - *
193.14 - * This software is provided "AS IS" with no warranty of any kind,
193.15 - * express or implied, and with no claim as to its suitability for any
193.16 - * purpose.
193.17 - *
193.18 - */
193.19 -
193.20 -/**
193.21 -@defgroup paths Path Structures
193.22 -@ingroup datas
193.23 -\brief Path structures implemented in LEMON.
193.24 -
193.25 -LEMON provides flexible data structures
193.26 -to work with paths.
193.27 -
193.28 -All of them have the same interface, especially they can be built or extended
193.29 -using a standard Builder subclass. This make is easy to have e.g. the Dijkstra
193.30 -algorithm to store its result in any kind of path structure.
193.31 -
193.32 -\sa lemon::concept::Path
193.33 -
193.34 -*/
193.35 -
193.36 -///\ingroup paths
193.37 -///\file
193.38 -///\brief Classes for representing paths in graphs.
193.39 -///
193.40 -///\todo Iterators have obsolete style
193.41 -
193.42 -#ifndef LEMON_PATH_H
193.43 -#define LEMON_PATH_H
193.44 -
193.45 -#include <deque>
193.46 -#include <vector>
193.47 -#include <algorithm>
193.48 -
193.49 -#include <lemon/invalid.h>
193.50 -
193.51 -namespace lemon {
193.52 -
193.53 - /// \addtogroup paths
193.54 - /// @{
193.55 -
193.56 -
193.57 - //! \brief A structure for representing directed paths in a graph.
193.58 - //!
193.59 - //! A structure for representing directed path in a graph.
193.60 - //! \param Graph The graph type in which the path is.
193.61 - //! \param DM DebugMode, defaults to DefaultDebugMode.
193.62 - //!
193.63 - //! In a sense, the path can be treated as a graph, for is has \c NodeIt
193.64 - //! and \c EdgeIt with the same usage. These types converts to the \c Node
193.65 - //! and \c Edge of the original graph.
193.66 - //!
193.67 - //! \todo Thoroughfully check all the range and consistency tests.
193.68 - template<typename Graph>
193.69 - class DirPath {
193.70 - public:
193.71 - /// Edge type of the underlying graph.
193.72 - typedef typename Graph::Edge GraphEdge;
193.73 - /// Node type of the underlying graph.
193.74 - typedef typename Graph::Node GraphNode;
193.75 - class NodeIt;
193.76 - class EdgeIt;
193.77 -
193.78 - protected:
193.79 - const Graph *gr;
193.80 - typedef std::vector<GraphEdge> Container;
193.81 - Container edges;
193.82 -
193.83 - public:
193.84 -
193.85 - /// \param _G The graph in which the path is.
193.86 - ///
193.87 - DirPath(const Graph &_G) : gr(&_G) {}
193.88 -
193.89 - /// \brief Subpath constructor.
193.90 - ///
193.91 - /// Subpath defined by two nodes.
193.92 - /// \warning It is an error if the two edges are not in order!
193.93 - DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
193.94 - gr = P.gr;
193.95 - edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
193.96 - }
193.97 -
193.98 - /// \brief Subpath constructor.
193.99 - ///
193.100 - /// Subpath defined by two edges. Contains edges in [a,b)
193.101 - /// \warning It is an error if the two edges are not in order!
193.102 - DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
193.103 - gr = P.gr;
193.104 - edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
193.105 - }
193.106 -
193.107 - /// Length of the path.
193.108 - int length() const { return edges.size(); }
193.109 - /// Returns whether the path is empty.
193.110 - bool empty() const { return edges.empty(); }
193.111 -
193.112 - /// Resets the path to an empty path.
193.113 - void clear() { edges.clear(); }
193.114 -
193.115 - /// \brief Starting point of the path.
193.116 - ///
193.117 - /// Starting point of the path.
193.118 - /// Returns INVALID if the path is empty.
193.119 - GraphNode source() const {
193.120 - return empty() ? INVALID : gr->source(edges[0]);
193.121 - }
193.122 - /// \brief End point of the path.
193.123 - ///
193.124 - /// End point of the path.
193.125 - /// Returns INVALID if the path is empty.
193.126 - GraphNode target() const {
193.127 - return empty() ? INVALID : gr->target(edges[length()-1]);
193.128 - }
193.129 -
193.130 - /// \brief Initializes node or edge iterator to point to the first
193.131 - /// node or edge.
193.132 - ///
193.133 - /// \sa nth
193.134 - template<typename It>
193.135 - It& first(It &i) const { return i=It(*this); }
193.136 -
193.137 - /// \brief Initializes node iterator to point to the node of a given index.
193.138 - NodeIt& nth(NodeIt &i, int n) const {
193.139 - return i=NodeIt(*this, n);
193.140 - }
193.141 -
193.142 - /// \brief Initializes edge iterator to point to the edge of a given index.
193.143 - EdgeIt& nth(EdgeIt &i, int n) const {
193.144 - return i=EdgeIt(*this, n);
193.145 - }
193.146 -
193.147 - /// \brief Returns node iterator pointing to the target node of the
193.148 - /// given edge iterator.
193.149 - NodeIt target(const EdgeIt& e) const {
193.150 - return NodeIt(*this, e.idx+1);
193.151 - }
193.152 -
193.153 - /// \brief Returns node iterator pointing to the source node of the
193.154 - /// given edge iterator.
193.155 - NodeIt source(const EdgeIt& e) const {
193.156 - return NodeIt(*this, e.idx);
193.157 - }
193.158 -
193.159 -
193.160 - /* Iterator classes */
193.161 -
193.162 - /**
193.163 - * \brief Iterator class to iterate on the edges of the paths
193.164 - *
193.165 - * This class is used to iterate on the edges of the paths
193.166 - *
193.167 - * Of course it converts to Graph::Edge
193.168 - *
193.169 - */
193.170 - class EdgeIt {
193.171 - friend class DirPath;
193.172 -
193.173 - int idx;
193.174 - const DirPath *p;
193.175 - public:
193.176 - /// Default constructor
193.177 - EdgeIt() {}
193.178 - /// Invalid constructor
193.179 - EdgeIt(Invalid) : idx(-1), p(0) {}
193.180 - /// Constructor with starting point
193.181 - EdgeIt(const DirPath &_p, int _idx = 0) :
193.182 - idx(_idx), p(&_p) { validate(); }
193.183 -
193.184 - ///Validity check
193.185 - bool valid() const { return idx!=-1; }
193.186 -
193.187 - ///Conversion to Graph::Edge
193.188 - operator GraphEdge () const {
193.189 - return valid() ? p->edges[idx] : INVALID;
193.190 - }
193.191 -
193.192 - /// Next edge
193.193 - EdgeIt& operator++() { ++idx; validate(); return *this; }
193.194 -
193.195 - /// Comparison operator
193.196 - bool operator==(const EdgeIt& e) const { return idx==e.idx; }
193.197 - /// Comparison operator
193.198 - bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
193.199 - /// Comparison operator
193.200 - bool operator<(const EdgeIt& e) const { return idx<e.idx; }
193.201 -
193.202 - private:
193.203 - void validate() { if(idx >= p->length() ) idx=-1; }
193.204 - };
193.205 -
193.206 - /**
193.207 - * \brief Iterator class to iterate on the nodes of the paths
193.208 - *
193.209 - * This class is used to iterate on the nodes of the paths
193.210 - *
193.211 - * Of course it converts to Graph::Node
193.212 - *
193.213 - */
193.214 - class NodeIt {
193.215 - friend class DirPath;
193.216 -
193.217 - int idx;
193.218 - const DirPath *p;
193.219 - public:
193.220 - /// Default constructor
193.221 - NodeIt() {}
193.222 - /// Invalid constructor
193.223 - NodeIt(Invalid) : idx(-1), p(0) {}
193.224 - /// Constructor with starting point
193.225 - NodeIt(const DirPath &_p, int _idx = 0) :
193.226 - idx(_idx), p(&_p) { validate(); }
193.227 -
193.228 - ///Validity check
193.229 - bool valid() const { return idx!=-1; }
193.230 -
193.231 - ///Conversion to Graph::Node
193.232 - operator const GraphNode& () const {
193.233 - if(idx >= p->length())
193.234 - return p->target();
193.235 - else if(idx >= 0)
193.236 - return p->gr->source(p->edges[idx]);
193.237 - else
193.238 - return INVALID;
193.239 - }
193.240 - /// Next node
193.241 - NodeIt& operator++() { ++idx; validate(); return *this; }
193.242 -
193.243 - /// Comparison operator
193.244 - bool operator==(const NodeIt& e) const { return idx==e.idx; }
193.245 - /// Comparison operator
193.246 - bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
193.247 - /// Comparison operator
193.248 - bool operator<(const NodeIt& e) const { return idx<e.idx; }
193.249 -
193.250 - private:
193.251 - void validate() { if(idx > p->length() ) idx=-1; }
193.252 - };
193.253 -
193.254 - friend class Builder;
193.255 -
193.256 - /**
193.257 - * \brief Class to build paths
193.258 - *
193.259 - * This class is used to fill a path with edges.
193.260 - *
193.261 - * You can push new edges to the front and to the back of the path in
193.262 - * arbitrary order then you should commit these changes to the graph.
193.263 - *
193.264 - * Fundamentally, for most "Paths" (classes fulfilling the
193.265 - * PathConcept) while the builder is active (after the first modifying
193.266 - * operation and until the commit()) the original Path is in a
193.267 - * "transitional" state (operations on it have undefined result). But
193.268 - * in the case of DirPath the original path remains unchanged until the
193.269 - * commit. However we don't recomend that you use this feature.
193.270 - */
193.271 - class Builder {
193.272 - DirPath &P;
193.273 - Container front, back;
193.274 -
193.275 - public:
193.276 - ///\param _p the path you want to fill in.
193.277 - ///
193.278 - Builder(DirPath &_p) : P(_p) {}
193.279 -
193.280 - /// Sets the starting node of the path.
193.281 -
193.282 - /// Sets the starting node of the path. Edge added to the path
193.283 - /// afterwards have to be incident to this node.
193.284 - /// It should be called if and only if
193.285 - /// the path is empty and before any call to
193.286 - /// \ref pushFront() or \ref pushBack()
193.287 - void setStartNode(const GraphNode &) {}
193.288 -
193.289 - ///Push a new edge to the front of the path
193.290 -
193.291 - ///Push a new edge to the front of the path.
193.292 - ///\sa setStartNode
193.293 - void pushFront(const GraphEdge& e) {
193.294 - front.push_back(e);
193.295 - }
193.296 -
193.297 - ///Push a new edge to the back of the path
193.298 -
193.299 - ///Push a new edge to the back of the path.
193.300 - ///\sa setStartNode
193.301 - void pushBack(const GraphEdge& e) {
193.302 - back.push_back(e);
193.303 - }
193.304 -
193.305 - ///Commit the changes to the path.
193.306 - void commit() {
193.307 - if( !front.empty() || !back.empty() ) {
193.308 - Container tmp;
193.309 - tmp.reserve(front.size()+back.size()+P.length());
193.310 - tmp.insert(tmp.end(), front.rbegin(), front.rend());
193.311 - tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
193.312 - tmp.insert(tmp.end(), back.begin(), back.end());
193.313 - P.edges.swap(tmp);
193.314 - front.clear();
193.315 - back.clear();
193.316 - }
193.317 - }
193.318 -
193.319 - ///Reserve storage for the builder in advance.
193.320 -
193.321 - ///If you know a reasonable upper bound of the number of the edges
193.322 - ///to add to the front, using this function you can speed up the building.
193.323 -
193.324 - void reserveFront(size_t r) {front.reserve(r);}
193.325 -
193.326 - ///Reserve storage for the builder in advance.
193.327 -
193.328 - ///If you know a reasonable upper bound of the number of the edges
193.329 - ///to add to the back, using this function you can speed up the building.
193.330 -
193.331 - void reserveBack(size_t r) {back.reserve(r);}
193.332 -
193.333 - private:
193.334 - bool empty() {
193.335 - return front.empty() && back.empty() && P.empty();
193.336 - }
193.337 -
193.338 - GraphNode source() const {
193.339 - if( ! front.empty() )
193.340 - return P.gr->source(front[front.size()-1]);
193.341 - else if( ! P.empty() )
193.342 - return P.gr->source(P.edges[0]);
193.343 - else if( ! back.empty() )
193.344 - return P.gr->source(back[0]);
193.345 - else
193.346 - return INVALID;
193.347 - }
193.348 - GraphNode target() const {
193.349 - if( ! back.empty() )
193.350 - return P.gr->target(back[back.size()-1]);
193.351 - else if( ! P.empty() )
193.352 - return P.gr->target(P.edges[P.length()-1]);
193.353 - else if( ! front.empty() )
193.354 - return P.gr->target(front[0]);
193.355 - else
193.356 - return INVALID;
193.357 - }
193.358 -
193.359 - };
193.360 -
193.361 - };
193.362 -
193.363 -
193.364 -
193.365 -
193.366 -
193.367 -
193.368 -
193.369 -
193.370 -
193.371 -
193.372 - /**********************************************************************/
193.373 -
193.374 -
193.375 - //! \brief A structure for representing undirected path in a graph.
193.376 - //!
193.377 - //! A structure for representing undirected path in a graph. Ie. this is
193.378 - //! a path in a \e directed graph but the edges should not be directed
193.379 - //! forward.
193.380 - //!
193.381 - //! \param Graph The graph type in which the path is.
193.382 - //! \param DM DebugMode, defaults to DefaultDebugMode.
193.383 - //!
193.384 - //! In a sense, the path can be treated as a graph, for is has \c NodeIt
193.385 - //! and \c EdgeIt with the same usage. These types converts to the \c Node
193.386 - //! and \c Edge of the original graph.
193.387 - //!
193.388 - //! \todo Thoroughfully check all the range and consistency tests.
193.389 - template<typename Graph>
193.390 - class UndirPath {
193.391 - public:
193.392 - /// Edge type of the underlying graph.
193.393 - typedef typename Graph::Edge GraphEdge;
193.394 - /// Node type of the underlying graph.
193.395 - typedef typename Graph::Node GraphNode;
193.396 - class NodeIt;
193.397 - class EdgeIt;
193.398 -
193.399 - protected:
193.400 - const Graph *gr;
193.401 - typedef std::vector<GraphEdge> Container;
193.402 - Container edges;
193.403 -
193.404 - public:
193.405 -
193.406 - /// \param _G The graph in which the path is.
193.407 - ///
193.408 - UndirPath(const Graph &_G) : gr(&_G) {}
193.409 -
193.410 - /// \brief Subpath constructor.
193.411 - ///
193.412 - /// Subpath defined by two nodes.
193.413 - /// \warning It is an error if the two edges are not in order!
193.414 - UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
193.415 - gr = P.gr;
193.416 - edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
193.417 - }
193.418 -
193.419 - /// \brief Subpath constructor.
193.420 - ///
193.421 - /// Subpath defined by two edges. Contains edges in [a,b)
193.422 - /// \warning It is an error if the two edges are not in order!
193.423 - UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
193.424 - gr = P.gr;
193.425 - edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
193.426 - }
193.427 -
193.428 - /// Length of the path.
193.429 - size_t length() const { return edges.size(); }
193.430 - /// Returns whether the path is empty.
193.431 - bool empty() const { return edges.empty(); }
193.432 -
193.433 - /// Resets the path to an empty path.
193.434 - void clear() { edges.clear(); }
193.435 -
193.436 - /// \brief Starting point of the path.
193.437 - ///
193.438 - /// Starting point of the path.
193.439 - /// Returns INVALID if the path is empty.
193.440 - GraphNode source() const {
193.441 - return empty() ? INVALID : gr->source(edges[0]);
193.442 - }
193.443 - /// \brief End point of the path.
193.444 - ///
193.445 - /// End point of the path.
193.446 - /// Returns INVALID if the path is empty.
193.447 - GraphNode target() const {
193.448 - return empty() ? INVALID : gr->target(edges[length()-1]);
193.449 - }
193.450 -
193.451 - /// \brief Initializes node or edge iterator to point to the first
193.452 - /// node or edge.
193.453 - ///
193.454 - /// \sa nth
193.455 - template<typename It>
193.456 - It& first(It &i) const { return i=It(*this); }
193.457 -
193.458 - /// \brief Initializes node iterator to point to the node of a given index.
193.459 - NodeIt& nth(NodeIt &i, int n) const {
193.460 - return i=NodeIt(*this, n);
193.461 - }
193.462 -
193.463 - /// \brief Initializes edge iterator to point to the edge of a given index.
193.464 - EdgeIt& nth(EdgeIt &i, int n) const {
193.465 - return i=EdgeIt(*this, n);
193.466 - }
193.467 -
193.468 - /// Checks validity of a node or edge iterator.
193.469 - template<typename It>
193.470 - static
193.471 - bool valid(const It &i) { return i.valid(); }
193.472 -
193.473 - /// Steps the given node or edge iterator.
193.474 - template<typename It>
193.475 - static
193.476 - It& next(It &e) {
193.477 - return ++e;
193.478 - }
193.479 -
193.480 - /// \brief Returns node iterator pointing to the target node of the
193.481 - /// given edge iterator.
193.482 - NodeIt target(const EdgeIt& e) const {
193.483 - return NodeIt(*this, e.idx+1);
193.484 - }
193.485 -
193.486 - /// \brief Returns node iterator pointing to the source node of the
193.487 - /// given edge iterator.
193.488 - NodeIt source(const EdgeIt& e) const {
193.489 - return NodeIt(*this, e.idx);
193.490 - }
193.491 -
193.492 -
193.493 -
193.494 - /**
193.495 - * \brief Iterator class to iterate on the edges of the paths
193.496 - *
193.497 - * This class is used to iterate on the edges of the paths
193.498 - *
193.499 - * Of course it converts to Graph::Edge
193.500 - *
193.501 - * \todo Its interface differs from the standard edge iterator.
193.502 - * Yes, it shouldn't.
193.503 - */
193.504 - class EdgeIt {
193.505 - friend class UndirPath;
193.506 -
193.507 - int idx;
193.508 - const UndirPath *p;
193.509 - public:
193.510 - /// Default constructor
193.511 - EdgeIt() {}
193.512 - /// Invalid constructor
193.513 - EdgeIt(Invalid) : idx(-1), p(0) {}
193.514 - /// Constructor with starting point
193.515 - EdgeIt(const UndirPath &_p, int _idx = 0) :
193.516 - idx(_idx), p(&_p) { validate(); }
193.517 -
193.518 - ///Validity check
193.519 - bool valid() const { return idx!=-1; }
193.520 -
193.521 - ///Conversion to Graph::Edge
193.522 - operator GraphEdge () const {
193.523 - return valid() ? p->edges[idx] : INVALID;
193.524 - }
193.525 - /// Next edge
193.526 - EdgeIt& operator++() { ++idx; validate(); return *this; }
193.527 -
193.528 - /// Comparison operator
193.529 - bool operator==(const EdgeIt& e) const { return idx==e.idx; }
193.530 - /// Comparison operator
193.531 - bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
193.532 - /// Comparison operator
193.533 - bool operator<(const EdgeIt& e) const { return idx<e.idx; }
193.534 -
193.535 - private:
193.536 - // FIXME: comparison between signed and unsigned...
193.537 - // Jo ez igy? Vagy esetleg legyen a length() int?
193.538 - void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
193.539 - };
193.540 -
193.541 - /**
193.542 - * \brief Iterator class to iterate on the nodes of the paths
193.543 - *
193.544 - * This class is used to iterate on the nodes of the paths
193.545 - *
193.546 - * Of course it converts to Graph::Node
193.547 - *
193.548 - * \todo Its interface differs from the standard node iterator.
193.549 - * Yes, it shouldn't.
193.550 - */
193.551 - class NodeIt {
193.552 - friend class UndirPath;
193.553 -
193.554 - int idx;
193.555 - const UndirPath *p;
193.556 - public:
193.557 - /// Default constructor
193.558 - NodeIt() {}
193.559 - /// Invalid constructor
193.560 - NodeIt(Invalid) : idx(-1), p(0) {}
193.561 - /// Constructor with starting point
193.562 - NodeIt(const UndirPath &_p, int _idx = 0) :
193.563 - idx(_idx), p(&_p) { validate(); }
193.564 -
193.565 - ///Validity check
193.566 - bool valid() const { return idx!=-1; }
193.567 -
193.568 - ///Conversion to Graph::Node
193.569 - operator const GraphNode& () const {
193.570 - if(idx >= p->length())
193.571 - return p->target();
193.572 - else if(idx >= 0)
193.573 - return p->gr->source(p->edges[idx]);
193.574 - else
193.575 - return INVALID;
193.576 - }
193.577 - /// Next node
193.578 - NodeIt& operator++() { ++idx; validate(); return *this; }
193.579 -
193.580 - /// Comparison operator
193.581 - bool operator==(const NodeIt& e) const { return idx==e.idx; }
193.582 - /// Comparison operator
193.583 - bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
193.584 - /// Comparison operator
193.585 - bool operator<(const NodeIt& e) const { return idx<e.idx; }
193.586 -
193.587 - private:
193.588 - void validate() { if( size_t(idx) > p->length() ) idx=-1; }
193.589 - };
193.590 -
193.591 - friend class Builder;
193.592 -
193.593 - /**
193.594 - * \brief Class to build paths
193.595 - *
193.596 - * This class is used to fill a path with edges.
193.597 - *
193.598 - * You can push new edges to the front and to the back of the path in
193.599 - * arbitrary order then you should commit these changes to the graph.
193.600 - *
193.601 - * Fundamentally, for most "Paths" (classes fulfilling the
193.602 - * PathConcept) while the builder is active (after the first modifying
193.603 - * operation and until the commit()) the original Path is in a
193.604 - * "transitional" state (operations ot it have undefined result). But
193.605 - * in the case of UndirPath the original path is unchanged until the
193.606 - * commit. However we don't recomend that you use this feature.
193.607 - */
193.608 - class Builder {
193.609 - UndirPath &P;
193.610 - Container front, back;
193.611 -
193.612 - public:
193.613 - ///\param _p the path you want to fill in.
193.614 - ///
193.615 - Builder(UndirPath &_p) : P(_p) {}
193.616 -
193.617 - /// Sets the starting node of the path.
193.618 -
193.619 - /// Sets the starting node of the path. Edge added to the path
193.620 - /// afterwards have to be incident to this node.
193.621 - /// It should be called if and only if
193.622 - /// the path is empty and before any call to
193.623 - /// \ref pushFront() or \ref pushBack()
193.624 - void setStartNode(const GraphNode &) {}
193.625 -
193.626 - ///Push a new edge to the front of the path
193.627 -
193.628 - ///Push a new edge to the front of the path.
193.629 - ///\sa setStartNode
193.630 - void pushFront(const GraphEdge& e) {
193.631 - front.push_back(e);
193.632 - }
193.633 -
193.634 - ///Push a new edge to the back of the path
193.635 -
193.636 - ///Push a new edge to the back of the path.
193.637 - ///\sa setStartNode
193.638 - void pushBack(const GraphEdge& e) {
193.639 - back.push_back(e);
193.640 - }
193.641 -
193.642 - ///Commit the changes to the path.
193.643 - void commit() {
193.644 - if( !(front.empty() && back.empty()) ) {
193.645 - Container tmp;
193.646 - tmp.reserve(front.size()+back.size()+P.length());
193.647 - tmp.insert(tmp.end(), front.rbegin(), front.rend());
193.648 - tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
193.649 - tmp.insert(tmp.end(), back.begin(), back.end());
193.650 - P.edges.swap(tmp);
193.651 - front.clear();
193.652 - back.clear();
193.653 - }
193.654 - }
193.655 -
193.656 -
193.657 - ///Reserve storage for the builder in advance.
193.658 -
193.659 - ///If you know a reasonable upper bound of the number of the edges
193.660 - ///to add to the front, using this function you can speed up the building.
193.661 -
193.662 - void reserveFront(size_t r) {front.reserve(r);}
193.663 -
193.664 - ///Reserve storage for the builder in advance.
193.665 -
193.666 - ///If you know a reasonable upper bound of the number of the edges
193.667 - ///to add to the back, using this function you can speed up the building.
193.668 -
193.669 - void reserveBack(size_t r) {back.reserve(r);}
193.670 -
193.671 - private:
193.672 - bool empty() {
193.673 - return front.empty() && back.empty() && P.empty();
193.674 - }
193.675 -
193.676 - GraphNode source() const {
193.677 - if( ! front.empty() )
193.678 - return P.gr->source(front[front.size()-1]);
193.679 - else if( ! P.empty() )
193.680 - return P.gr->source(P.edges[0]);
193.681 - else if( ! back.empty() )
193.682 - return P.gr->source(back[0]);
193.683 - else
193.684 - return INVALID;
193.685 - }
193.686 - GraphNode target() const {
193.687 - if( ! back.empty() )
193.688 - return P.gr->target(back[back.size()-1]);
193.689 - else if( ! P.empty() )
193.690 - return P.gr->target(P.edges[P.length()-1]);
193.691 - else if( ! front.empty() )
193.692 - return P.gr->target(front[0]);
193.693 - else
193.694 - return INVALID;
193.695 - }
193.696 -
193.697 - };
193.698 -
193.699 - };
193.700 -
193.701 -
193.702 - ///@}
193.703 -
193.704 -} // namespace lemon
193.705 -
193.706 -#endif // LEMON_PATH_H
194.1 --- a/src/lemon/preflow.h Sat May 21 21:04:57 2005 +0000
194.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
194.3 @@ -1,868 +0,0 @@
194.4 -/* -*- C++ -*-
194.5 - * src/lemon/preflow.h - Part of LEMON, a generic C++ optimization library
194.6 - *
194.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
194.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
194.9 - *
194.10 - * Permission to use, modify and distribute this software is granted
194.11 - * provided that this copyright notice appears in all copies. For
194.12 - * precise terms see the accompanying LICENSE file.
194.13 - *
194.14 - * This software is provided "AS IS" with no warranty of any kind,
194.15 - * express or implied, and with no claim as to its suitability for any
194.16 - * purpose.
194.17 - *
194.18 - */
194.19 -
194.20 -#ifndef LEMON_PREFLOW_H
194.21 -#define LEMON_PREFLOW_H
194.22 -
194.23 -#include <vector>
194.24 -#include <queue>
194.25 -
194.26 -#include <lemon/invalid.h>
194.27 -#include <lemon/maps.h>
194.28 -#include <lemon/graph_utils.h>
194.29 -
194.30 -/// \file
194.31 -/// \ingroup flowalgs
194.32 -/// Implementation of the preflow algorithm.
194.33 -
194.34 -namespace lemon {
194.35 -
194.36 - /// \addtogroup flowalgs
194.37 - /// @{
194.38 -
194.39 - ///%Preflow algorithms class.
194.40 -
194.41 - ///This class provides an implementation of the \e preflow \e
194.42 - ///algorithm producing a flow of maximum value in a directed
194.43 - ///graph. The preflow algorithms are the fastest known max flow algorithms
194.44 - ///up to now. The \e source node, the \e target node, the \e
194.45 - ///capacity of the edges and the \e starting \e flow value of the
194.46 - ///edges should be passed to the algorithm through the
194.47 - ///constructor. It is possible to change these quantities using the
194.48 - ///functions \ref source, \ref target, \ref capacityMap and \ref
194.49 - ///flowMap.
194.50 - ///
194.51 - ///After running \ref lemon::Preflow::phase1() "phase1()"
194.52 - ///or \ref lemon::Preflow::run() "run()", the maximal flow
194.53 - ///value can be obtained by calling \ref flowValue(). The minimum
194.54 - ///value cut can be written into a <tt>bool</tt> node map by
194.55 - ///calling \ref minCut(). (\ref minMinCut() and \ref maxMinCut() writes
194.56 - ///the inclusionwise minimum and maximum of the minimum value cuts,
194.57 - ///resp.)
194.58 - ///
194.59 - ///\param Graph The directed graph type the algorithm runs on.
194.60 - ///\param Num The number type of the capacities and the flow values.
194.61 - ///\param CapacityMap The capacity map type.
194.62 - ///\param FlowMap The flow map type.
194.63 - ///
194.64 - ///\author Jacint Szabo
194.65 - ///\todo Second template parameter is superfluous
194.66 - template <typename Graph, typename Num,
194.67 - typename CapacityMap=typename Graph::template EdgeMap<Num>,
194.68 - typename FlowMap=typename Graph::template EdgeMap<Num> >
194.69 - class Preflow {
194.70 - protected:
194.71 - typedef typename Graph::Node Node;
194.72 - typedef typename Graph::NodeIt NodeIt;
194.73 - typedef typename Graph::EdgeIt EdgeIt;
194.74 - typedef typename Graph::OutEdgeIt OutEdgeIt;
194.75 - typedef typename Graph::InEdgeIt InEdgeIt;
194.76 -
194.77 - typedef typename Graph::template NodeMap<Node> NNMap;
194.78 - typedef typename std::vector<Node> VecNode;
194.79 -
194.80 - const Graph* _g;
194.81 - Node _source;
194.82 - Node _target;
194.83 - const CapacityMap* _capacity;
194.84 - FlowMap* _flow;
194.85 - int _node_num; //the number of nodes of G
194.86 -
194.87 - typename Graph::template NodeMap<int> level;
194.88 - typename Graph::template NodeMap<Num> excess;
194.89 -
194.90 - // constants used for heuristics
194.91 - static const int H0=20;
194.92 - static const int H1=1;
194.93 -
194.94 - public:
194.95 -
194.96 - ///Indicates the property of the starting flow map.
194.97 -
194.98 - ///Indicates the property of the starting flow map.
194.99 - ///The meanings are as follows:
194.100 - ///- \c ZERO_FLOW: constant zero flow
194.101 - ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
194.102 - ///the sum of the out-flows in every node except the \e source and
194.103 - ///the \e target.
194.104 - ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at
194.105 - ///least the sum of the out-flows in every node except the \e source.
194.106 - ///- \c NO_FLOW: indicates an unspecified edge map. \c flow will be
194.107 - ///set to the constant zero flow in the beginning of
194.108 - ///the algorithm in this case.
194.109 - ///
194.110 - enum FlowEnum{
194.111 - NO_FLOW,
194.112 - ZERO_FLOW,
194.113 - GEN_FLOW,
194.114 - PRE_FLOW
194.115 - };
194.116 -
194.117 - ///Indicates the state of the preflow algorithm.
194.118 -
194.119 - ///Indicates the state of the preflow algorithm.
194.120 - ///The meanings are as follows:
194.121 - ///- \c AFTER_NOTHING: before running the algorithm or
194.122 - /// at an unspecified state.
194.123 - ///- \c AFTER_PREFLOW_PHASE_1: right after running \c phase1
194.124 - ///- \c AFTER_PREFLOW_PHASE_2: after running \ref phase2()
194.125 - ///
194.126 - enum StatusEnum {
194.127 - AFTER_NOTHING,
194.128 - AFTER_PREFLOW_PHASE_1,
194.129 - AFTER_PREFLOW_PHASE_2
194.130 - };
194.131 -
194.132 - protected:
194.133 - FlowEnum flow_prop;
194.134 - StatusEnum status; // Do not needle this flag only if necessary.
194.135 -
194.136 - public:
194.137 - ///The constructor of the class.
194.138 -
194.139 - ///The constructor of the class.
194.140 - ///\param _gr The directed graph the algorithm runs on.
194.141 - ///\param _s The source node.
194.142 - ///\param _t The target node.
194.143 - ///\param _cap The capacity of the edges.
194.144 - ///\param _f The flow of the edges.
194.145 - ///Except the graph, all of these parameters can be reset by
194.146 - ///calling \ref source, \ref target, \ref capacityMap and \ref
194.147 - ///flowMap, resp.
194.148 - Preflow(const Graph& _gr, Node _s, Node _t,
194.149 - const CapacityMap& _cap, FlowMap& _f) :
194.150 - _g(&_gr), _source(_s), _target(_t), _capacity(&_cap),
194.151 - _flow(&_f), _node_num(countNodes(_gr)), level(_gr), excess(_gr,0),
194.152 - flow_prop(NO_FLOW), status(AFTER_NOTHING) { }
194.153 -
194.154 -
194.155 -
194.156 - ///Runs the preflow algorithm.
194.157 -
194.158 - ///Runs the preflow algorithm.
194.159 - ///
194.160 - void run() {
194.161 - phase1(flow_prop);
194.162 - phase2();
194.163 - }
194.164 -
194.165 - ///Runs the preflow algorithm.
194.166 -
194.167 - ///Runs the preflow algorithm.
194.168 - ///\pre The starting flow map must be
194.169 - /// - a constant zero flow if \c fp is \c ZERO_FLOW,
194.170 - /// - an arbitrary flow if \c fp is \c GEN_FLOW,
194.171 - /// - an arbitrary preflow if \c fp is \c PRE_FLOW,
194.172 - /// - any map if \c fp is NO_FLOW.
194.173 - ///If the starting flow map is a flow or a preflow then
194.174 - ///the algorithm terminates faster.
194.175 - void run(FlowEnum fp) {
194.176 - flow_prop=fp;
194.177 - run();
194.178 - }
194.179 -
194.180 - ///Runs the first phase of the preflow algorithm.
194.181 -
194.182 - ///The preflow algorithm consists of two phases, this method runs
194.183 - ///the first phase. After the first phase the maximum flow value
194.184 - ///and a minimum value cut can already be computed, although a
194.185 - ///maximum flow is not yet obtained. So after calling this method
194.186 - ///\ref flowValue returns the value of a maximum flow and \ref
194.187 - ///minCut returns a minimum cut.
194.188 - ///\warning \ref minMinCut and \ref maxMinCut do not give minimum
194.189 - ///value cuts unless calling \ref phase2.
194.190 - ///\pre The starting flow must be
194.191 - ///- a constant zero flow if \c fp is \c ZERO_FLOW,
194.192 - ///- an arbitary flow if \c fp is \c GEN_FLOW,
194.193 - ///- an arbitary preflow if \c fp is \c PRE_FLOW,
194.194 - ///- any map if \c fp is NO_FLOW.
194.195 - void phase1(FlowEnum fp)
194.196 - {
194.197 - flow_prop=fp;
194.198 - phase1();
194.199 - }
194.200 -
194.201 -
194.202 - ///Runs the first phase of the preflow algorithm.
194.203 -
194.204 - ///The preflow algorithm consists of two phases, this method runs
194.205 - ///the first phase. After the first phase the maximum flow value
194.206 - ///and a minimum value cut can already be computed, although a
194.207 - ///maximum flow is not yet obtained. So after calling this method
194.208 - ///\ref flowValue returns the value of a maximum flow and \ref
194.209 - ///minCut returns a minimum cut.
194.210 - ///\warning \ref minCut(), \ref minMinCut() and \ref maxMinCut() do not
194.211 - ///give minimum value cuts unless calling \ref phase2().
194.212 - void phase1()
194.213 - {
194.214 - int heur0=(int)(H0*_node_num); //time while running 'bound decrease'
194.215 - int heur1=(int)(H1*_node_num); //time while running 'highest label'
194.216 - int heur=heur1; //starting time interval (#of relabels)
194.217 - int numrelabel=0;
194.218 -
194.219 - bool what_heur=1;
194.220 - //It is 0 in case 'bound decrease' and 1 in case 'highest label'
194.221 -
194.222 - bool end=false;
194.223 - //Needed for 'bound decrease', true means no active
194.224 - //nodes are above bound b.
194.225 -
194.226 - int k=_node_num-2; //bound on the highest level under n containing a node
194.227 - int b=k; //bound on the highest level under n of an active node
194.228 -
194.229 - VecNode first(_node_num, INVALID);
194.230 - NNMap next(*_g, INVALID);
194.231 -
194.232 - NNMap left(*_g, INVALID);
194.233 - NNMap right(*_g, INVALID);
194.234 - VecNode level_list(_node_num,INVALID);
194.235 - //List of the nodes in level i<n, set to n.
194.236 -
194.237 - preflowPreproc(first, next, level_list, left, right);
194.238 -
194.239 - //Push/relabel on the highest level active nodes.
194.240 - while ( true ) {
194.241 - if ( b == 0 ) {
194.242 - if ( !what_heur && !end && k > 0 ) {
194.243 - b=k;
194.244 - end=true;
194.245 - } else break;
194.246 - }
194.247 -
194.248 - if ( first[b]==INVALID ) --b;
194.249 - else {
194.250 - end=false;
194.251 - Node w=first[b];
194.252 - first[b]=next[w];
194.253 - int newlevel=push(w, next, first);
194.254 - if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list,
194.255 - left, right, b, k, what_heur);
194.256 -
194.257 - ++numrelabel;
194.258 - if ( numrelabel >= heur ) {
194.259 - numrelabel=0;
194.260 - if ( what_heur ) {
194.261 - what_heur=0;
194.262 - heur=heur0;
194.263 - end=false;
194.264 - } else {
194.265 - what_heur=1;
194.266 - heur=heur1;
194.267 - b=k;
194.268 - }
194.269 - }
194.270 - }
194.271 - }
194.272 - flow_prop=PRE_FLOW;
194.273 - status=AFTER_PREFLOW_PHASE_1;
194.274 - }
194.275 - // Heuristics:
194.276 - // 2 phase
194.277 - // gap
194.278 - // list 'level_list' on the nodes on level i implemented by hand
194.279 - // stack 'active' on the active nodes on level i
194.280 - // runs heuristic 'highest label' for H1*n relabels
194.281 - // runs heuristic 'bound decrease' for H0*n relabels,
194.282 - // starts with 'highest label'
194.283 - // Parameters H0 and H1 are initialized to 20 and 1.
194.284 -
194.285 -
194.286 - ///Runs the second phase of the preflow algorithm.
194.287 -
194.288 - ///The preflow algorithm consists of two phases, this method runs
194.289 - ///the second phase. After calling \ref phase1 and then \ref
194.290 - ///phase2, \ref flow contains a maximum flow, \ref flowValue
194.291 - ///returns the value of a maximum flow, \ref minCut returns a
194.292 - ///minimum cut, while the methods \ref minMinCut and \ref
194.293 - ///maxMinCut return the inclusionwise minimum and maximum cuts of
194.294 - ///minimum value, resp. \pre \ref phase1 must be called before.
194.295 - void phase2()
194.296 - {
194.297 -
194.298 - int k=_node_num-2; //bound on the highest level under n containing a node
194.299 - int b=k; //bound on the highest level under n of an active node
194.300 -
194.301 -
194.302 - VecNode first(_node_num, INVALID);
194.303 - NNMap next(*_g, INVALID);
194.304 - level.set(_source,0);
194.305 - std::queue<Node> bfs_queue;
194.306 - bfs_queue.push(_source);
194.307 -
194.308 - while ( !bfs_queue.empty() ) {
194.309 -
194.310 - Node v=bfs_queue.front();
194.311 - bfs_queue.pop();
194.312 - int l=level[v]+1;
194.313 -
194.314 - for(InEdgeIt e(*_g,v); e!=INVALID; ++e) {
194.315 - if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
194.316 - Node u=_g->source(e);
194.317 - if ( level[u] >= _node_num ) {
194.318 - bfs_queue.push(u);
194.319 - level.set(u, l);
194.320 - if ( excess[u] > 0 ) {
194.321 - next.set(u,first[l]);
194.322 - first[l]=u;
194.323 - }
194.324 - }
194.325 - }
194.326 -
194.327 - for(OutEdgeIt e(*_g,v); e!=INVALID; ++e) {
194.328 - if ( 0 >= (*_flow)[e] ) continue;
194.329 - Node u=_g->target(e);
194.330 - if ( level[u] >= _node_num ) {
194.331 - bfs_queue.push(u);
194.332 - level.set(u, l);
194.333 - if ( excess[u] > 0 ) {
194.334 - next.set(u,first[l]);
194.335 - first[l]=u;
194.336 - }
194.337 - }
194.338 - }
194.339 - }
194.340 - b=_node_num-2;
194.341 -
194.342 - while ( true ) {
194.343 -
194.344 - if ( b == 0 ) break;
194.345 - if ( first[b]==INVALID ) --b;
194.346 - else {
194.347 - Node w=first[b];
194.348 - first[b]=next[w];
194.349 - int newlevel=push(w,next, first);
194.350 -
194.351 - //relabel
194.352 - if ( excess[w] > 0 ) {
194.353 - level.set(w,++newlevel);
194.354 - next.set(w,first[newlevel]);
194.355 - first[newlevel]=w;
194.356 - b=newlevel;
194.357 - }
194.358 - }
194.359 - } // while(true)
194.360 - flow_prop=GEN_FLOW;
194.361 - status=AFTER_PREFLOW_PHASE_2;
194.362 - }
194.363 -
194.364 - /// Returns the value of the maximum flow.
194.365 -
194.366 - /// Returns the value of the maximum flow by returning the excess
194.367 - /// of the target node \c t. This value equals to the value of
194.368 - /// the maximum flow already after running \ref phase1.
194.369 - Num flowValue() const {
194.370 - return excess[_target];
194.371 - }
194.372 -
194.373 -
194.374 - ///Returns a minimum value cut.
194.375 -
194.376 - ///Sets \c M to the characteristic vector of a minimum value
194.377 - ///cut. This method can be called both after running \ref
194.378 - ///phase1 and \ref phase2. It is much faster after
194.379 - ///\ref phase1. \pre M should be a bool-valued node-map. \pre
194.380 - ///If \ref minCut() is called after \ref phase2() then M should
194.381 - ///be initialized to false.
194.382 - template<typename _CutMap>
194.383 - void minCut(_CutMap& M) const {
194.384 - switch ( status ) {
194.385 - case AFTER_PREFLOW_PHASE_1:
194.386 - for(NodeIt v(*_g); v!=INVALID; ++v) {
194.387 - if (level[v] < _node_num) {
194.388 - M.set(v, false);
194.389 - } else {
194.390 - M.set(v, true);
194.391 - }
194.392 - }
194.393 - break;
194.394 - case AFTER_PREFLOW_PHASE_2:
194.395 - minMinCut(M);
194.396 - break;
194.397 - case AFTER_NOTHING:
194.398 - break;
194.399 - }
194.400 - }
194.401 -
194.402 - ///Returns the inclusionwise minimum of the minimum value cuts.
194.403 -
194.404 - ///Sets \c M to the characteristic vector of the minimum value cut
194.405 - ///which is inclusionwise minimum. It is computed by processing a
194.406 - ///bfs from the source node \c s in the residual graph. \pre M
194.407 - ///should be a node map of bools initialized to false. \pre \ref
194.408 - ///phase2 should already be run.
194.409 - template<typename _CutMap>
194.410 - void minMinCut(_CutMap& M) const {
194.411 -
194.412 - std::queue<Node> queue;
194.413 - M.set(_source,true);
194.414 - queue.push(_source);
194.415 -
194.416 - while (!queue.empty()) {
194.417 - Node w=queue.front();
194.418 - queue.pop();
194.419 -
194.420 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.421 - Node v=_g->target(e);
194.422 - if (!M[v] && (*_flow)[e] < (*_capacity)[e] ) {
194.423 - queue.push(v);
194.424 - M.set(v, true);
194.425 - }
194.426 - }
194.427 -
194.428 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.429 - Node v=_g->source(e);
194.430 - if (!M[v] && (*_flow)[e] > 0 ) {
194.431 - queue.push(v);
194.432 - M.set(v, true);
194.433 - }
194.434 - }
194.435 - }
194.436 - }
194.437 -
194.438 - ///Returns the inclusionwise maximum of the minimum value cuts.
194.439 -
194.440 - ///Sets \c M to the characteristic vector of the minimum value cut
194.441 - ///which is inclusionwise maximum. It is computed by processing a
194.442 - ///backward bfs from the target node \c t in the residual graph.
194.443 - ///\pre \ref phase2() or run() should already be run.
194.444 - template<typename _CutMap>
194.445 - void maxMinCut(_CutMap& M) const {
194.446 -
194.447 - for(NodeIt v(*_g) ; v!=INVALID; ++v) M.set(v, true);
194.448 -
194.449 - std::queue<Node> queue;
194.450 -
194.451 - M.set(_target,false);
194.452 - queue.push(_target);
194.453 -
194.454 - while (!queue.empty()) {
194.455 - Node w=queue.front();
194.456 - queue.pop();
194.457 -
194.458 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.459 - Node v=_g->source(e);
194.460 - if (M[v] && (*_flow)[e] < (*_capacity)[e] ) {
194.461 - queue.push(v);
194.462 - M.set(v, false);
194.463 - }
194.464 - }
194.465 -
194.466 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.467 - Node v=_g->target(e);
194.468 - if (M[v] && (*_flow)[e] > 0 ) {
194.469 - queue.push(v);
194.470 - M.set(v, false);
194.471 - }
194.472 - }
194.473 - }
194.474 - }
194.475 -
194.476 - ///Sets the source node to \c _s.
194.477 -
194.478 - ///Sets the source node to \c _s.
194.479 - ///
194.480 - void source(Node _s) {
194.481 - _source=_s;
194.482 - if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW;
194.483 - status=AFTER_NOTHING;
194.484 - }
194.485 -
194.486 - ///Returns the source node.
194.487 -
194.488 - ///Returns the source node.
194.489 - ///
194.490 - Node source() const {
194.491 - return _source;
194.492 - }
194.493 -
194.494 - ///Sets the target node to \c _t.
194.495 -
194.496 - ///Sets the target node to \c _t.
194.497 - ///
194.498 - void target(Node _t) {
194.499 - _target=_t;
194.500 - if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW;
194.501 - status=AFTER_NOTHING;
194.502 - }
194.503 -
194.504 - ///Returns the target node.
194.505 -
194.506 - ///Returns the target node.
194.507 - ///
194.508 - Node target() const {
194.509 - return _target;
194.510 - }
194.511 -
194.512 - /// Sets the edge map of the capacities to _cap.
194.513 -
194.514 - /// Sets the edge map of the capacities to _cap.
194.515 - ///
194.516 - void capacityMap(const CapacityMap& _cap) {
194.517 - _capacity=&_cap;
194.518 - status=AFTER_NOTHING;
194.519 - }
194.520 - /// Returns a reference to capacity map.
194.521 -
194.522 - /// Returns a reference to capacity map.
194.523 - ///
194.524 - const CapacityMap &capacityMap() const {
194.525 - return *_capacity;
194.526 - }
194.527 -
194.528 - /// Sets the edge map of the flows to _flow.
194.529 -
194.530 - /// Sets the edge map of the flows to _flow.
194.531 - ///
194.532 - void flowMap(FlowMap& _f) {
194.533 - _flow=&_f;
194.534 - flow_prop=NO_FLOW;
194.535 - status=AFTER_NOTHING;
194.536 - }
194.537 -
194.538 - /// Returns a reference to flow map.
194.539 -
194.540 - /// Returns a reference to flow map.
194.541 - ///
194.542 - const FlowMap &flowMap() const {
194.543 - return *_flow;
194.544 - }
194.545 -
194.546 - private:
194.547 -
194.548 - int push(Node w, NNMap& next, VecNode& first) {
194.549 -
194.550 - int lev=level[w];
194.551 - Num exc=excess[w];
194.552 - int newlevel=_node_num; //bound on the next level of w
194.553 -
194.554 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.555 - if ( (*_flow)[e] >= (*_capacity)[e] ) continue;
194.556 - Node v=_g->target(e);
194.557 -
194.558 - if( lev > level[v] ) { //Push is allowed now
194.559 -
194.560 - if ( excess[v]<=0 && v!=_target && v!=_source ) {
194.561 - next.set(v,first[level[v]]);
194.562 - first[level[v]]=v;
194.563 - }
194.564 -
194.565 - Num cap=(*_capacity)[e];
194.566 - Num flo=(*_flow)[e];
194.567 - Num remcap=cap-flo;
194.568 -
194.569 - if ( remcap >= exc ) { //A nonsaturating push.
194.570 -
194.571 - _flow->set(e, flo+exc);
194.572 - excess.set(v, excess[v]+exc);
194.573 - exc=0;
194.574 - break;
194.575 -
194.576 - } else { //A saturating push.
194.577 - _flow->set(e, cap);
194.578 - excess.set(v, excess[v]+remcap);
194.579 - exc-=remcap;
194.580 - }
194.581 - } else if ( newlevel > level[v] ) newlevel = level[v];
194.582 - } //for out edges wv
194.583 -
194.584 - if ( exc > 0 ) {
194.585 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
194.586 -
194.587 - if( (*_flow)[e] <= 0 ) continue;
194.588 - Node v=_g->source(e);
194.589 -
194.590 - if( lev > level[v] ) { //Push is allowed now
194.591 -
194.592 - if ( excess[v]<=0 && v!=_target && v!=_source ) {
194.593 - next.set(v,first[level[v]]);
194.594 - first[level[v]]=v;
194.595 - }
194.596 -
194.597 - Num flo=(*_flow)[e];
194.598 -
194.599 - if ( flo >= exc ) { //A nonsaturating push.
194.600 -
194.601 - _flow->set(e, flo-exc);
194.602 - excess.set(v, excess[v]+exc);
194.603 - exc=0;
194.604 - break;
194.605 - } else { //A saturating push.
194.606 -
194.607 - excess.set(v, excess[v]+flo);
194.608 - exc-=flo;
194.609 - _flow->set(e,0);
194.610 - }
194.611 - } else if ( newlevel > level[v] ) newlevel = level[v];
194.612 - } //for in edges vw
194.613 -
194.614 - } // if w still has excess after the out edge for cycle
194.615 -
194.616 - excess.set(w, exc);
194.617 -
194.618 - return newlevel;
194.619 - }
194.620 -
194.621 -
194.622 -
194.623 - void preflowPreproc(VecNode& first, NNMap& next,
194.624 - VecNode& level_list, NNMap& left, NNMap& right)
194.625 - {
194.626 - for(NodeIt v(*_g); v!=INVALID; ++v) level.set(v,_node_num);
194.627 - std::queue<Node> bfs_queue;
194.628 -
194.629 - if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) {
194.630 - //Reverse_bfs from t in the residual graph,
194.631 - //to find the starting level.
194.632 - level.set(_target,0);
194.633 - bfs_queue.push(_target);
194.634 -
194.635 - while ( !bfs_queue.empty() ) {
194.636 -
194.637 - Node v=bfs_queue.front();
194.638 - bfs_queue.pop();
194.639 - int l=level[v]+1;
194.640 -
194.641 - for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
194.642 - if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
194.643 - Node w=_g->source(e);
194.644 - if ( level[w] == _node_num && w != _source ) {
194.645 - bfs_queue.push(w);
194.646 - Node z=level_list[l];
194.647 - if ( z!=INVALID ) left.set(z,w);
194.648 - right.set(w,z);
194.649 - level_list[l]=w;
194.650 - level.set(w, l);
194.651 - }
194.652 - }
194.653 -
194.654 - for(OutEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
194.655 - if ( 0 >= (*_flow)[e] ) continue;
194.656 - Node w=_g->target(e);
194.657 - if ( level[w] == _node_num && w != _source ) {
194.658 - bfs_queue.push(w);
194.659 - Node z=level_list[l];
194.660 - if ( z!=INVALID ) left.set(z,w);
194.661 - right.set(w,z);
194.662 - level_list[l]=w;
194.663 - level.set(w, l);
194.664 - }
194.665 - }
194.666 - } //while
194.667 - } //if
194.668 -
194.669 -
194.670 - switch (flow_prop) {
194.671 - case NO_FLOW:
194.672 - for(EdgeIt e(*_g); e!=INVALID; ++e) _flow->set(e,0);
194.673 - case ZERO_FLOW:
194.674 - for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
194.675 -
194.676 - //Reverse_bfs from t, to find the starting level.
194.677 - level.set(_target,0);
194.678 - bfs_queue.push(_target);
194.679 -
194.680 - while ( !bfs_queue.empty() ) {
194.681 -
194.682 - Node v=bfs_queue.front();
194.683 - bfs_queue.pop();
194.684 - int l=level[v]+1;
194.685 -
194.686 - for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
194.687 - Node w=_g->source(e);
194.688 - if ( level[w] == _node_num && w != _source ) {
194.689 - bfs_queue.push(w);
194.690 - Node z=level_list[l];
194.691 - if ( z!=INVALID ) left.set(z,w);
194.692 - right.set(w,z);
194.693 - level_list[l]=w;
194.694 - level.set(w, l);
194.695 - }
194.696 - }
194.697 - }
194.698 -
194.699 - //the starting flow
194.700 - for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
194.701 - Num c=(*_capacity)[e];
194.702 - if ( c <= 0 ) continue;
194.703 - Node w=_g->target(e);
194.704 - if ( level[w] < _node_num ) {
194.705 - if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
194.706 - next.set(w,first[level[w]]);
194.707 - first[level[w]]=w;
194.708 - }
194.709 - _flow->set(e, c);
194.710 - excess.set(w, excess[w]+c);
194.711 - }
194.712 - }
194.713 - break;
194.714 -
194.715 - case GEN_FLOW:
194.716 - for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
194.717 - {
194.718 - Num exc=0;
194.719 - for(InEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc+=(*_flow)[e];
194.720 - for(OutEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc-=(*_flow)[e];
194.721 - excess.set(_target,exc);
194.722 - }
194.723 -
194.724 - //the starting flow
194.725 - for(OutEdgeIt e(*_g,_source); e!=INVALID; ++e) {
194.726 - Num rem=(*_capacity)[e]-(*_flow)[e];
194.727 - if ( rem <= 0 ) continue;
194.728 - Node w=_g->target(e);
194.729 - if ( level[w] < _node_num ) {
194.730 - if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
194.731 - next.set(w,first[level[w]]);
194.732 - first[level[w]]=w;
194.733 - }
194.734 - _flow->set(e, (*_capacity)[e]);
194.735 - excess.set(w, excess[w]+rem);
194.736 - }
194.737 - }
194.738 -
194.739 - for(InEdgeIt e(*_g,_source); e!=INVALID; ++e) {
194.740 - if ( (*_flow)[e] <= 0 ) continue;
194.741 - Node w=_g->source(e);
194.742 - if ( level[w] < _node_num ) {
194.743 - if ( excess[w] <= 0 && w!=_target ) {
194.744 - next.set(w,first[level[w]]);
194.745 - first[level[w]]=w;
194.746 - }
194.747 - excess.set(w, excess[w]+(*_flow)[e]);
194.748 - _flow->set(e, 0);
194.749 - }
194.750 - }
194.751 - break;
194.752 -
194.753 - case PRE_FLOW:
194.754 - //the starting flow
194.755 - for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
194.756 - Num rem=(*_capacity)[e]-(*_flow)[e];
194.757 - if ( rem <= 0 ) continue;
194.758 - Node w=_g->target(e);
194.759 - if ( level[w] < _node_num ) _flow->set(e, (*_capacity)[e]);
194.760 - }
194.761 -
194.762 - for(InEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
194.763 - if ( (*_flow)[e] <= 0 ) continue;
194.764 - Node w=_g->source(e);
194.765 - if ( level[w] < _node_num ) _flow->set(e, 0);
194.766 - }
194.767 -
194.768 - //computing the excess
194.769 - for(NodeIt w(*_g); w!=INVALID; ++w) {
194.770 - Num exc=0;
194.771 - for(InEdgeIt e(*_g,w); e!=INVALID; ++e) exc+=(*_flow)[e];
194.772 - for(OutEdgeIt e(*_g,w); e!=INVALID; ++e) exc-=(*_flow)[e];
194.773 - excess.set(w,exc);
194.774 -
194.775 - //putting the active nodes into the stack
194.776 - int lev=level[w];
194.777 - if ( exc > 0 && lev < _node_num && Node(w) != _target ) {
194.778 - next.set(w,first[lev]);
194.779 - first[lev]=w;
194.780 - }
194.781 - }
194.782 - break;
194.783 - } //switch
194.784 - } //preflowPreproc
194.785 -
194.786 -
194.787 - void relabel(Node w, int newlevel, VecNode& first, NNMap& next,
194.788 - VecNode& level_list, NNMap& left,
194.789 - NNMap& right, int& b, int& k, bool what_heur )
194.790 - {
194.791 -
194.792 - int lev=level[w];
194.793 -
194.794 - Node right_n=right[w];
194.795 - Node left_n=left[w];
194.796 -
194.797 - //unlacing starts
194.798 - if ( right_n!=INVALID ) {
194.799 - if ( left_n!=INVALID ) {
194.800 - right.set(left_n, right_n);
194.801 - left.set(right_n, left_n);
194.802 - } else {
194.803 - level_list[lev]=right_n;
194.804 - left.set(right_n, INVALID);
194.805 - }
194.806 - } else {
194.807 - if ( left_n!=INVALID ) {
194.808 - right.set(left_n, INVALID);
194.809 - } else {
194.810 - level_list[lev]=INVALID;
194.811 - }
194.812 - }
194.813 - //unlacing ends
194.814 -
194.815 - if ( level_list[lev]==INVALID ) {
194.816 -
194.817 - //gapping starts
194.818 - for (int i=lev; i!=k ; ) {
194.819 - Node v=level_list[++i];
194.820 - while ( v!=INVALID ) {
194.821 - level.set(v,_node_num);
194.822 - v=right[v];
194.823 - }
194.824 - level_list[i]=INVALID;
194.825 - if ( !what_heur ) first[i]=INVALID;
194.826 - }
194.827 -
194.828 - level.set(w,_node_num);
194.829 - b=lev-1;
194.830 - k=b;
194.831 - //gapping ends
194.832 -
194.833 - } else {
194.834 -
194.835 - if ( newlevel == _node_num ) level.set(w,_node_num);
194.836 - else {
194.837 - level.set(w,++newlevel);
194.838 - next.set(w,first[newlevel]);
194.839 - first[newlevel]=w;
194.840 - if ( what_heur ) b=newlevel;
194.841 - if ( k < newlevel ) ++k; //now k=newlevel
194.842 - Node z=level_list[newlevel];
194.843 - if ( z!=INVALID ) left.set(z,w);
194.844 - right.set(w,z);
194.845 - left.set(w,INVALID);
194.846 - level_list[newlevel]=w;
194.847 - }
194.848 - }
194.849 - } //relabel
194.850 -
194.851 - };
194.852 -
194.853 - ///Function type interface for Preflow algorithm.
194.854 -
194.855 - /// \ingroup flowalgs
194.856 - ///Function type interface for Preflow algorithm.
194.857 - ///\sa Preflow
194.858 - template<class GR, class CM, class FM>
194.859 - Preflow<GR,typename CM::Value,CM,FM> preflow(const GR &g,
194.860 - typename GR::Node source,
194.861 - typename GR::Node target,
194.862 - const CM &cap,
194.863 - FM &flow
194.864 - )
194.865 - {
194.866 - return Preflow<GR,typename CM::Value,CM,FM>(g,source,target,cap,flow);
194.867 - }
194.868 -
194.869 -} //namespace lemon
194.870 -
194.871 -#endif //LEMON_PREFLOW_H
195.1 --- a/src/lemon/radix_heap.h Sat May 21 21:04:57 2005 +0000
195.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
195.3 @@ -1,412 +0,0 @@
195.4 -/* -*- C++ -*-
195.5 - * src/lemon/radix_heap.h - Part of LEMON, a generic C++ optimization library
195.6 - *
195.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
195.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
195.9 - *
195.10 - * Permission to use, modify and distribute this software is granted
195.11 - * provided that this copyright notice appears in all copies. For
195.12 - * precise terms see the accompanying LICENSE file.
195.13 - *
195.14 - * This software is provided "AS IS" with no warranty of any kind,
195.15 - * express or implied, and with no claim as to its suitability for any
195.16 - * purpose.
195.17 - *
195.18 - */
195.19 -
195.20 -#ifndef LEMON_RADIX_HEAP_H
195.21 -#define LEMON_RADIX_HEAP_H
195.22 -
195.23 -///\ingroup auxdat
195.24 -///\file
195.25 -///\brief Radix Heap implementation.
195.26 -
195.27 -#include <vector>
195.28 -#include <lemon/error.h>
195.29 -
195.30 -namespace lemon {
195.31 -
195.32 - /// \addtogroup auxdat
195.33 - /// @{
195.34 -
195.35 - /// \brief Exception thrown by RadixHeap.
195.36 - ///
195.37 - /// This Exception is thrown when a smaller priority
195.38 - /// is inserted into the \e RadixHeap then the last time erased.
195.39 - /// \see RadixHeap
195.40 - /// \author Balazs Dezso
195.41 -
195.42 - class UnderFlowPriorityError : public RuntimeError {
195.43 - public:
195.44 - virtual const char* exceptionName() const {
195.45 - return "lemon::UnderFlowPriorityError";
195.46 - }
195.47 - };
195.48 -
195.49 - /// \brief A Radix Heap implementation.
195.50 - ///
195.51 - /// This class implements the \e radix \e heap data structure. A \e heap
195.52 - /// is a data structure for storing items with specified values called \e
195.53 - /// priorities in such a way that finding the item with minimum priority is
195.54 - /// efficient. This heap type can store only items with \e int priority.
195.55 - /// In a heap one can change the priority of an item, add or erase an
195.56 - /// item, but the priority cannot be decreased under the last removed
195.57 - /// item's priority.
195.58 - ///
195.59 - /// \param _Item Type of the items to be stored.
195.60 - /// \param _ItemIntMap A read and writable Item int map, used internally
195.61 - /// to handle the cross references.
195.62 - ///
195.63 - /// \see BinHeap
195.64 - /// \see Dijkstra
195.65 - /// \author Balazs Dezso
195.66 -
195.67 - template <typename _Item, typename _ItemIntMap>
195.68 - class RadixHeap {
195.69 -
195.70 - public:
195.71 - typedef _Item Item;
195.72 - typedef int Prio;
195.73 - typedef _ItemIntMap ItemIntMap;
195.74 -
195.75 - /// \brief Type to represent the items states.
195.76 - ///
195.77 - /// Each Item element have a state associated to it. It may be "in heap",
195.78 - /// "pre heap" or "post heap". The latter two are indifferent from the
195.79 - /// heap's point of view, but may be useful to the user.
195.80 - ///
195.81 - /// The ItemIntMap \e should be initialized in such way that it maps
195.82 - /// PRE_HEAP (-1) to any element to be put in the heap...
195.83 - enum state_enum {
195.84 - IN_HEAP = 0,
195.85 - PRE_HEAP = -1,
195.86 - POST_HEAP = -2
195.87 - };
195.88 -
195.89 - private:
195.90 -
195.91 - struct RadixItem {
195.92 - int prev, next, box;
195.93 - Item item;
195.94 - int prio;
195.95 - RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
195.96 - };
195.97 -
195.98 - struct RadixBox {
195.99 - int first;
195.100 - int min, size;
195.101 - RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
195.102 - };
195.103 -
195.104 - std::vector<RadixItem> data;
195.105 - std::vector<RadixBox> boxes;
195.106 -
195.107 - ItemIntMap &iim;
195.108 -
195.109 -
195.110 - public:
195.111 - /// \brief The constructor.
195.112 - ///
195.113 - /// The constructor.
195.114 - /// \param _iim should be given to the constructor, since it is used
195.115 - /// internally to handle the cross references. The value of the map
195.116 - /// should be PRE_HEAP (-1) for each element.
195.117 - explicit RadixHeap(ItemIntMap &_iim) : iim(_iim) {
195.118 - boxes.push_back(RadixBox(0, 1));
195.119 - boxes.push_back(RadixBox(1, 1));
195.120 - }
195.121 -
195.122 - /// \brief The constructor.
195.123 - ///
195.124 - /// The constructor.
195.125 - ///
195.126 - /// \param _iim It should be given to the constructor, since it is used
195.127 - /// internally to handle the cross references. The value of the map
195.128 - /// should be PRE_HEAP (-1) for each element.
195.129 - ///
195.130 - /// \param capacity It determines the initial capacity of the heap.
195.131 - RadixHeap(ItemIntMap &_iim, int capacity) : iim(_iim) {
195.132 - boxes.push_back(RadixBox(0, 1));
195.133 - boxes.push_back(RadixBox(1, 1));
195.134 - while (upper(boxes.back(), capacity)) {
195.135 - extend();
195.136 - }
195.137 - }
195.138 -
195.139 - /// The number of items stored in the heap.
195.140 - ///
195.141 - /// \brief Returns the number of items stored in the heap.
195.142 - int size() const { return data.size(); }
195.143 - /// \brief Checks if the heap stores no items.
195.144 - ///
195.145 - /// Returns \c true if and only if the heap stores no items.
195.146 - bool empty() const { return data.empty(); }
195.147 -
195.148 - private:
195.149 -
195.150 - bool upper(int box, Prio prio) {
195.151 - return prio < boxes[box].min;
195.152 - }
195.153 -
195.154 - bool lower(int box, Prio prio) {
195.155 - return prio >= boxes[box].min + boxes[box].size;
195.156 - }
195.157 -
195.158 - /// \brief Remove item from the box list.
195.159 - void remove(int index) {
195.160 - if (data[index].prev >= 0) {
195.161 - data[data[index].prev].next = data[index].next;
195.162 - } else {
195.163 - boxes[data[index].box].first = data[index].next;
195.164 - }
195.165 - if (data[index].next >= 0) {
195.166 - data[data[index].next].prev = data[index].prev;
195.167 - }
195.168 - }
195.169 -
195.170 - /// \brief Insert item into the box list.
195.171 - void insert(int box, int index) {
195.172 - if (boxes[box].first == -1) {
195.173 - boxes[box].first = index;
195.174 - data[index].next = data[index].prev = -1;
195.175 - } else {
195.176 - data[index].next = boxes[box].first;
195.177 - data[boxes[box].first].prev = index;
195.178 - data[index].prev = -1;
195.179 - boxes[box].first = index;
195.180 - }
195.181 - data[index].box = box;
195.182 - }
195.183 -
195.184 - /// \brief Add a new box to the box list.
195.185 - void extend() {
195.186 - int min = boxes.back().min + boxes.back().size;
195.187 - int size = 2 * boxes.back().size;
195.188 - boxes.push_back(RadixBox(min, size));
195.189 - }
195.190 -
195.191 - /// \brief Move an item up into the proper box.
195.192 - void bubble_up(int index) {
195.193 - if (!lower(data[index].box, data[index].prio)) return;
195.194 - remove(index);
195.195 - int box = findUp(data[index].box, data[index].prio);
195.196 - insert(box, index);
195.197 - }
195.198 -
195.199 - /// \brief Find up the proper box for the item with the given prio.
195.200 - int findUp(int start, int prio) {
195.201 - while (lower(start, prio)) {
195.202 - if (++start == (int)boxes.size()) {
195.203 - extend();
195.204 - }
195.205 - }
195.206 - return start;
195.207 - }
195.208 -
195.209 - /// \brief Move an item down into the proper box.
195.210 - void bubble_down(int index) {
195.211 - if (!upper(data[index].box, data[index].prio)) return;
195.212 - remove(index);
195.213 - int box = findDown(data[index].box, data[index].prio);
195.214 - insert(box, index);
195.215 - }
195.216 -
195.217 - /// \brief Find up the proper box for the item with the given prio.
195.218 - int findDown(int start, int prio) {
195.219 - while (upper(start, prio)) {
195.220 - if (--start < 0) throw UnderFlowPriorityError();
195.221 - }
195.222 - return start;
195.223 - }
195.224 -
195.225 - /// \brief Find the first not empty box.
195.226 - int findFirst() {
195.227 - int first = 0;
195.228 - while (boxes[first].first == -1) ++first;
195.229 - return first;
195.230 - }
195.231 -
195.232 - /// \brief Gives back the minimal prio of the box.
195.233 - int minValue(int box) {
195.234 - int min = data[boxes[box].first].prio;
195.235 - for (int k = boxes[box].first; k != -1; k = data[k].next) {
195.236 - if (data[k].prio < min) min = data[k].prio;
195.237 - }
195.238 - return min;
195.239 - }
195.240 -
195.241 - /// \brief Rearrange the items of the heap and makes the
195.242 - /// first box not empty.
195.243 - void moveDown() {
195.244 - int box = findFirst();
195.245 - if (box == 0) return;
195.246 - int min = minValue(box);
195.247 - for (int i = 0; i <= box; ++i) {
195.248 - boxes[i].min = min;
195.249 - min += boxes[i].size;
195.250 - }
195.251 - int curr = boxes[box].first, next;
195.252 - while (curr != -1) {
195.253 - next = data[curr].next;
195.254 - bubble_down(curr);
195.255 - curr = next;
195.256 - }
195.257 - }
195.258 -
195.259 - void relocate_last(int index) {
195.260 - if (index != (int)data.size() - 1) {
195.261 - data[index] = data.back();
195.262 - if (data[index].prev != -1) {
195.263 - data[data[index].prev].next = index;
195.264 - } else {
195.265 - boxes[data[index].box].first = index;
195.266 - }
195.267 - if (data[index].next != -1) {
195.268 - data[data[index].next].prev = index;
195.269 - }
195.270 - iim[data[index].item] = index;
195.271 - }
195.272 - data.pop_back();
195.273 - }
195.274 -
195.275 - public:
195.276 -
195.277 - /// \brief Insert an item into the heap with the given heap.
195.278 - ///
195.279 - /// Adds \c i to the heap with priority \c p.
195.280 - /// \param i The item to insert.
195.281 - /// \param p The priority of the item.
195.282 - void push(const Item &i, const Prio &p) {
195.283 - int n = data.size();
195.284 - iim.set(i, n);
195.285 - data.push_back(RadixItem(i, p));
195.286 - while (lower(boxes.size() - 1, p)) {
195.287 - extend();
195.288 - }
195.289 - int box = findDown(boxes.size() - 1, p);
195.290 - insert(box, n);
195.291 - }
195.292 -
195.293 - /// \brief Returns the item with minimum priority.
195.294 - ///
195.295 - /// This method returns the item with minimum priority.
195.296 - /// \pre The heap must be nonempty.
195.297 - Item top() const {
195.298 - const_cast<RadixHeap<Item, ItemIntMap>*>(this)->moveDown();
195.299 - return data[boxes[0].first].item;
195.300 - }
195.301 -
195.302 - /// \brief Returns the minimum priority.
195.303 - ///
195.304 - /// It returns the minimum priority.
195.305 - /// \pre The heap must be nonempty.
195.306 - Prio prio() const {
195.307 - const_cast<RadixHeap<Item, ItemIntMap>*>(this)->moveDown();
195.308 - return data[boxes[0].first].prio;
195.309 - }
195.310 -
195.311 - /// \brief Deletes the item with minimum priority.
195.312 - ///
195.313 - /// This method deletes the item with minimum priority.
195.314 - /// \pre The heap must be non-empty.
195.315 - void pop() {
195.316 - moveDown();
195.317 - int index = boxes[0].first;
195.318 - iim[data[index].item] = POST_HEAP;
195.319 - remove(index);
195.320 - relocate_last(index);
195.321 - }
195.322 -
195.323 - /// \brief Deletes \c i from the heap.
195.324 - ///
195.325 - /// This method deletes item \c i from the heap, if \c i was
195.326 - /// already stored in the heap.
195.327 - /// \param i The item to erase.
195.328 - void erase(const Item &i) {
195.329 - int index = iim[i];
195.330 - iim[i] = POST_HEAP;
195.331 - remove(index);
195.332 - relocate_last(index);
195.333 - }
195.334 -
195.335 - /// \brief Returns the priority of \c i.
195.336 - ///
195.337 - /// This function returns the priority of item \c i.
195.338 - /// \pre \c i must be in the heap.
195.339 - /// \param i The item.
195.340 - Prio operator[](const Item &i) const {
195.341 - int idx = iim[i];
195.342 - return data[idx].prio;
195.343 - }
195.344 -
195.345 - /// \brief \c i gets to the heap with priority \c p independently
195.346 - /// if \c i was already there.
195.347 - ///
195.348 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
195.349 - /// in the heap and sets the priority of \c i to \c p otherwise.
195.350 - /// It may throw an \e UnderFlowPriorityException.
195.351 - /// \param i The item.
195.352 - /// \param p The priority.
195.353 - void set(const Item &i, const Prio &p) {
195.354 - int idx = iim[i];
195.355 - if( idx < 0 ) {
195.356 - push(i, p);
195.357 - }
195.358 - else if( p >= data[idx].prio ) {
195.359 - data[idx].prio = p;
195.360 - bubble_up(idx);
195.361 - } else {
195.362 - data[idx].prio = p;
195.363 - bubble_down(idx);
195.364 - }
195.365 - }
195.366 -
195.367 -
195.368 - /// \brief Decreases the priority of \c i to \c p.
195.369 - ///
195.370 - /// This method decreases the priority of item \c i to \c p.
195.371 - /// \pre \c i must be stored in the heap with priority at least \c p, and
195.372 - /// \c should be greater then the last removed item's priority.
195.373 - /// \param i The item.
195.374 - /// \param p The priority.
195.375 - void decrease(const Item &i, const Prio &p) {
195.376 - int idx = iim[i];
195.377 - data[idx].prio = p;
195.378 - bubble_down(idx);
195.379 - }
195.380 -
195.381 - /// \brief Increases the priority of \c i to \c p.
195.382 - ///
195.383 - /// This method sets the priority of item \c i to \c p.
195.384 - /// \pre \c i must be stored in the heap with priority at most \c
195.385 - /// p relative to \c Compare.
195.386 - /// \param i The item.
195.387 - /// \param p The priority.
195.388 - void increase(const Item &i, const Prio &p) {
195.389 - int idx = iim[i];
195.390 - data[idx].prio = p;
195.391 - bubble_up(idx);
195.392 - }
195.393 -
195.394 - /// \brief Returns if \c item is in, has already been in, or has
195.395 - /// never been in the heap.
195.396 - ///
195.397 - /// This method returns PRE_HEAP if \c item has never been in the
195.398 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
195.399 - /// otherwise. In the latter case it is possible that \c item will
195.400 - /// get back to the heap again.
195.401 - /// \param i The item.
195.402 - state_enum state(const Item &i) const {
195.403 - int s = iim[i];
195.404 - if( s >= 0 ) s = 0;
195.405 - return state_enum(s);
195.406 - }
195.407 -
195.408 - }; // class RadixHeap
195.409 -
195.410 -
195.411 - ///@}
195.412 -
195.413 -} // namespace lemon
195.414 -
195.415 -#endif // LEMON_RADIX_HEAP_H
196.1 --- a/src/lemon/smart_graph.h Sat May 21 21:04:57 2005 +0000
196.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
196.3 @@ -1,414 +0,0 @@
196.4 -/* -*- C++ -*-
196.5 - * src/lemon/smart_graph.h - Part of LEMON, a generic C++ optimization library
196.6 - *
196.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
196.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
196.9 - *
196.10 - * Permission to use, modify and distribute this software is granted
196.11 - * provided that this copyright notice appears in all copies. For
196.12 - * precise terms see the accompanying LICENSE file.
196.13 - *
196.14 - * This software is provided "AS IS" with no warranty of any kind,
196.15 - * express or implied, and with no claim as to its suitability for any
196.16 - * purpose.
196.17 - *
196.18 - */
196.19 -
196.20 -#ifndef LEMON_SMART_GRAPH_H
196.21 -#define LEMON_SMART_GRAPH_H
196.22 -
196.23 -///\ingroup graphs
196.24 -///\file
196.25 -///\brief SmartGraph and SymSmartGraph classes.
196.26 -
196.27 -#include <vector>
196.28 -
196.29 -#include <lemon/invalid.h>
196.30 -
196.31 -#include <lemon/bits/clearable_graph_extender.h>
196.32 -#include <lemon/bits/extendable_graph_extender.h>
196.33 -#include <lemon/bits/iterable_graph_extender.h>
196.34 -#include <lemon/bits/alteration_notifier.h>
196.35 -#include <lemon/bits/default_map.h>
196.36 -
196.37 -#include <lemon/bits/undir_graph_extender.h>
196.38 -
196.39 -#include <lemon/utility.h>
196.40 -
196.41 -namespace lemon {
196.42 -
196.43 - class SmartGraph;
196.44 - ///Base of SmartGraph
196.45 -
196.46 - ///Base of SmartGraph
196.47 - ///
196.48 - class SmartGraphBase {
196.49 -
196.50 - friend class SmatGraph;
196.51 -
196.52 - protected:
196.53 - struct NodeT
196.54 - {
196.55 - int first_in,first_out;
196.56 - NodeT() : first_in(-1), first_out(-1) {}
196.57 - };
196.58 - struct EdgeT
196.59 - {
196.60 - int target, source, next_in, next_out;
196.61 - //FIXME: is this necessary?
196.62 - EdgeT() : next_in(-1), next_out(-1) {}
196.63 - };
196.64 -
196.65 - std::vector<NodeT> nodes;
196.66 -
196.67 - std::vector<EdgeT> edges;
196.68 -
196.69 -
196.70 - public:
196.71 -
196.72 - typedef SmartGraphBase Graph;
196.73 -
196.74 - class Node;
196.75 - class Edge;
196.76 -
196.77 -
196.78 - public:
196.79 -
196.80 - SmartGraphBase() : nodes(), edges() { }
196.81 - SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
196.82 -
196.83 - typedef True NodeNumTag;
196.84 - typedef True EdgeNumTag;
196.85 -
196.86 - ///Number of nodes.
196.87 - int nodeNum() const { return nodes.size(); }
196.88 - ///Number of edges.
196.89 - int edgeNum() const { return edges.size(); }
196.90 -
196.91 - /// Maximum node ID.
196.92 -
196.93 - /// Maximum node ID.
196.94 - ///\sa id(Node)
196.95 - int maxId(Node = INVALID) const { return nodes.size()-1; }
196.96 - /// Maximum edge ID.
196.97 -
196.98 - /// Maximum edge ID.
196.99 - ///\sa id(Edge)
196.100 - int maxId(Edge = INVALID) const { return edges.size()-1; }
196.101 -
196.102 - Node source(Edge e) const { return edges[e.n].source; }
196.103 - Node target(Edge e) const { return edges[e.n].target; }
196.104 -
196.105 - /// Node ID.
196.106 -
196.107 - /// The ID of a valid Node is a nonnegative integer not greater than
196.108 - /// \ref maxNodeId(). The range of the ID's is not surely continuous
196.109 - /// and the greatest node ID can be actually less then \ref maxNodeId().
196.110 - ///
196.111 - /// The ID of the \ref INVALID node is -1.
196.112 - ///\return The ID of the node \c v.
196.113 - static int id(Node v) { return v.n; }
196.114 - /// Edge ID.
196.115 -
196.116 - /// The ID of a valid Edge is a nonnegative integer not greater than
196.117 - /// \ref maxEdgeId(). The range of the ID's is not surely continuous
196.118 - /// and the greatest edge ID can be actually less then \ref maxEdgeId().
196.119 - ///
196.120 - /// The ID of the \ref INVALID edge is -1.
196.121 - ///\return The ID of the edge \c e.
196.122 - static int id(Edge e) { return e.n; }
196.123 -
196.124 - static Node fromId(int id, Node) { return Node(id);}
196.125 -
196.126 - static Edge fromId(int id, Edge) { return Edge(id);}
196.127 -
196.128 - Node addNode() {
196.129 - Node n; n.n=nodes.size();
196.130 - nodes.push_back(NodeT()); //FIXME: Hmmm...
196.131 - return n;
196.132 - }
196.133 -
196.134 - Edge addEdge(Node u, Node v) {
196.135 - Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
196.136 - edges[e.n].source=u.n; edges[e.n].target=v.n;
196.137 - edges[e.n].next_out=nodes[u.n].first_out;
196.138 - edges[e.n].next_in=nodes[v.n].first_in;
196.139 - nodes[u.n].first_out=nodes[v.n].first_in=e.n;
196.140 -
196.141 - return e;
196.142 - }
196.143 -
196.144 - void clear() {
196.145 - edges.clear();
196.146 - nodes.clear();
196.147 - }
196.148 -
196.149 -
196.150 - class Node {
196.151 - friend class SmartGraphBase;
196.152 - friend class SmartGraph;
196.153 -
196.154 - protected:
196.155 - int n;
196.156 - ///\todo It should be removed (or at least define a setToId() instead).
196.157 - ///
196.158 - Node(int nn) {n=nn;}
196.159 - public:
196.160 - Node() {}
196.161 - Node (Invalid) { n=-1; }
196.162 - bool operator==(const Node i) const {return n==i.n;}
196.163 - bool operator!=(const Node i) const {return n!=i.n;}
196.164 - bool operator<(const Node i) const {return n<i.n;}
196.165 - };
196.166 -
196.167 -
196.168 - class Edge {
196.169 - friend class SmartGraphBase;
196.170 - friend class SmartGraph;
196.171 -
196.172 - protected:
196.173 - int n;
196.174 - ///\todo It should be removed (or at least define a setToId() instead).
196.175 - ///
196.176 - Edge(int nn) {n=nn;}
196.177 - public:
196.178 - Edge() { }
196.179 - Edge (Invalid) { n=-1; }
196.180 - bool operator==(const Edge i) const {return n==i.n;}
196.181 - bool operator!=(const Edge i) const {return n!=i.n;}
196.182 - bool operator<(const Edge i) const {return n<i.n;}
196.183 - };
196.184 -
196.185 - void first(Node& node) const {
196.186 - node.n = nodes.size() - 1;
196.187 - }
196.188 -
196.189 - static void next(Node& node) {
196.190 - --node.n;
196.191 - }
196.192 -
196.193 - void first(Edge& edge) const {
196.194 - edge.n = edges.size() - 1;
196.195 - }
196.196 -
196.197 - static void next(Edge& edge) {
196.198 - --edge.n;
196.199 - }
196.200 -
196.201 - void firstOut(Edge& edge, const Node& node) const {
196.202 - edge.n = nodes[node.n].first_out;
196.203 - }
196.204 -
196.205 - void nextOut(Edge& edge) const {
196.206 - edge.n = edges[edge.n].next_out;
196.207 - }
196.208 -
196.209 - void firstIn(Edge& edge, const Node& node) const {
196.210 - edge.n = nodes[node.n].first_in;
196.211 - }
196.212 -
196.213 - void nextIn(Edge& edge) const {
196.214 - edge.n = edges[edge.n].next_in;
196.215 - }
196.216 -
196.217 - Edge _findEdge(Node u,Node v, Edge prev = INVALID)
196.218 - {
196.219 - int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
196.220 - while(e!=-1 && edges[e].target!=v.n) e = edges[e].next_out;
196.221 - prev.n=e;
196.222 - return prev;
196.223 - }
196.224 -
196.225 - Node _split(Node n, bool connect = true)
196.226 - {
196.227 - Node b = addNode();
196.228 - nodes[b.n].first_out=nodes[n.n].first_out;
196.229 - nodes[n.n].first_out=-1;
196.230 - for(int i=nodes[b.n].first_out;i!=-1;i++) edges[i].source=b.n;
196.231 - if(connect) addEdge(n,b);
196.232 - return b;
196.233 - }
196.234 -
196.235 - };
196.236 -
196.237 - typedef AlterableGraphExtender<SmartGraphBase> AlterableSmartGraphBase;
196.238 - typedef IterableGraphExtender<AlterableSmartGraphBase> IterableSmartGraphBase;
196.239 - typedef DefaultMappableGraphExtender<IterableSmartGraphBase> MappableSmartGraphBase;
196.240 - typedef ExtendableGraphExtender<MappableSmartGraphBase> ExtendableSmartGraphBase;
196.241 - typedef ClearableGraphExtender<ExtendableSmartGraphBase> ClearableSmartGraphBase;
196.242 -
196.243 - /// \addtogroup graphs
196.244 - /// @{
196.245 -
196.246 - ///A smart graph class.
196.247 -
196.248 - ///This is a simple and fast graph implementation.
196.249 - ///It is also quite memory efficient, but at the price
196.250 - ///that <b> it does support only limited (only stack-like)
196.251 - ///node and edge deletions</b>.
196.252 - ///It conforms to
196.253 - ///the \ref concept::ExtendableGraph "ExtendableGraph" concept.
196.254 - ///\sa concept::ExtendableGraph.
196.255 - ///
196.256 - ///\author Alpar Juttner
196.257 - class SmartGraph : public ClearableSmartGraphBase {
196.258 - public:
196.259 - /// Finds an edge between two nodes.
196.260 -
196.261 - /// Finds an edge from node \c u to node \c v.
196.262 - ///
196.263 - /// If \c prev is \ref INVALID (this is the default value), then
196.264 - /// it finds the first edge from \c u to \c v. Otherwise it looks for
196.265 - /// the next edge from \c u to \c v after \c prev.
196.266 - /// \return The found edge or \ref INVALID if there is no such an edge.
196.267 - ///
196.268 - /// Thus you can iterate through each edge from \c u to \c v as it follows.
196.269 - /// \code
196.270 - /// for(Edge e=G.findEdge(u,v);e!=INVALID;e=G.findEdge(u,v,e)) {
196.271 - /// ...
196.272 - /// }
196.273 - /// \endcode
196.274 - /// \todo Possibly it should be a global function.
196.275 - Edge findEdge(Node u,Node v, Edge prev = INVALID)
196.276 - {
196.277 - return _findEdge(u,v,prev);
196.278 - }
196.279 -
196.280 - class SnapShot;
196.281 - friend class SnapShot;
196.282 -
196.283 - protected:
196.284 - void restoreSnapShot(const SnapShot &s)
196.285 - {
196.286 - while(s.edge_num>edges.size()) {
196.287 - Parent::getNotifier(Edge()).erase(Edge(edges.size()-1));
196.288 - nodes[edges.back().target].first_in=edges.back().next_in;
196.289 - nodes[edges.back().source].first_out=edges.back().next_out;
196.290 - edges.pop_back();
196.291 - }
196.292 - //nodes.resize(s.nodes_num);
196.293 - while(s.node_num>nodes.size()) {
196.294 - Parent::getNotifier(Node()).erase(Node(nodes.size()-1));
196.295 - nodes.pop_back();
196.296 - }
196.297 - }
196.298 -
196.299 - public:
196.300 -
196.301 - ///Split a node.
196.302 -
196.303 - ///This function splits a node. First a new node is added to the graph,
196.304 - ///then the source of each outgoing edge of \c n is moved to this new node.
196.305 - ///If \c connect is \c true (this is the default value), then a new edge
196.306 - ///from \c n to the newly created node is also added.
196.307 - ///\return The newly created node.
196.308 - ///
196.309 - ///\note The <tt>Edge</tt>s
196.310 - ///referencing a moved edge remain
196.311 - ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
196.312 - ///may be invalidated.
196.313 - ///\warning This functionality cannot be used together with the SnapShot
196.314 - ///feature.
196.315 - ///\todo It could be implemented in a bit faster way.
196.316 - Node split(Node n, bool connect = true)
196.317 - {
196.318 - return _split(n,connect);
196.319 - }
196.320 -
196.321 -
196.322 - ///Class to make a snapshot of the graph and to restrore to it later.
196.323 -
196.324 - ///Class to make a snapshot of the graph and to restrore to it later.
196.325 - ///
196.326 - ///The newly added nodes and edges can be removed using the
196.327 - ///restore() function.
196.328 - ///\note After you restore a state, you cannot restore
196.329 - ///a later state, in other word you cannot add again the edges deleted
196.330 - ///by restore() using another SnapShot instance.
196.331 - ///
196.332 - class SnapShot
196.333 - {
196.334 - SmartGraph *g;
196.335 - protected:
196.336 - friend class SmartGraph;
196.337 - unsigned int node_num;
196.338 - unsigned int edge_num;
196.339 - public:
196.340 - ///Default constructor.
196.341 -
196.342 - ///Default constructor.
196.343 - ///To actually make a snapshot you must call save().
196.344 - ///
196.345 - SnapShot() : g(0) {}
196.346 - ///Constructor that immediately makes a snapshot
196.347 -
196.348 - ///This constructor immediately makes a snapshot of the graph.
196.349 - ///\param _g The graph we make a snapshot of.
196.350 - SnapShot(SmartGraph &_g) :g(&_g) {
196.351 - node_num=g->nodes.size();
196.352 - edge_num=g->edges.size();
196.353 - }
196.354 -
196.355 - ///Make a snapshot.
196.356 -
196.357 - ///Make a snapshot of the graph.
196.358 - ///
196.359 - ///This function can be called more than once. In case of a repeated
196.360 - ///call, the previous snapshot gets lost.
196.361 - ///\param _g The graph we make the snapshot of.
196.362 - void save(SmartGraph &_g)
196.363 - {
196.364 - g=&_g;
196.365 - node_num=g->nodes.size();
196.366 - edge_num=g->edges.size();
196.367 - }
196.368 -
196.369 - ///Undo the changes until a snapshot.
196.370 -
196.371 - ///Undo the changes until a snapshot created by save().
196.372 - ///
196.373 - ///\param s an internal stucture given back by save()
196.374 - ///\note After you restored a state, you cannot restore
196.375 - ///a later state, in other word you cannot add again the edges deleted
196.376 - ///by restore().
196.377 - ///
196.378 - ///\todo This function might be called undo().
196.379 -
196.380 - void restore()
196.381 - {
196.382 - g->restoreSnapShot(*this);
196.383 - }
196.384 - };
196.385 - };
196.386 -
196.387 -
196.388 - /**************** Undirected List Graph ****************/
196.389 -
196.390 - typedef ClearableUndirGraphExtender<
196.391 - ExtendableUndirGraphExtender<
196.392 - MappableUndirGraphExtender<
196.393 - IterableUndirGraphExtender<
196.394 - AlterableUndirGraphExtender<
196.395 - UndirGraphExtender<SmartGraphBase> > > > > > UndirSmartGraphBase;
196.396 -
196.397 - ///A smart undirected graph class.
196.398 -
196.399 - ///This is a simple and fast undirected graph implementation.
196.400 - ///It is also quite memory efficient, but at the price
196.401 - ///that <b> it does support only limited (only stack-like)
196.402 - ///node and edge deletions</b>.
196.403 - ///Except from this it conforms to
196.404 - ///the \ref concept::UndirGraph "UndirGraph" concept.
196.405 - ///\sa concept::UndirGraph.
196.406 - ///
196.407 - ///\todo SnapShot hasn't been implemented yet.
196.408 - ///
196.409 - class UndirSmartGraph : public UndirSmartGraphBase {
196.410 - };
196.411 -
196.412 -
196.413 - /// @}
196.414 -} //namespace lemon
196.415 -
196.416 -
196.417 -#endif //LEMON_SMART_GRAPH_H
197.1 --- a/src/lemon/suurballe.h Sat May 21 21:04:57 2005 +0000
197.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
197.3 @@ -1,209 +0,0 @@
197.4 -/* -*- C++ -*-
197.5 - * src/lemon/suurballe.h - Part of LEMON, a generic C++ optimization library
197.6 - *
197.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
197.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
197.9 - *
197.10 - * Permission to use, modify and distribute this software is granted
197.11 - * provided that this copyright notice appears in all copies. For
197.12 - * precise terms see the accompanying LICENSE file.
197.13 - *
197.14 - * This software is provided "AS IS" with no warranty of any kind,
197.15 - * express or implied, and with no claim as to its suitability for any
197.16 - * purpose.
197.17 - *
197.18 - */
197.19 -
197.20 -#ifndef LEMON_SUURBALLE_H
197.21 -#define LEMON_SUURBALLE_H
197.22 -
197.23 -///\ingroup flowalgs
197.24 -///\file
197.25 -///\brief An algorithm for finding k paths of minimal total length.
197.26 -
197.27 -
197.28 -#include <lemon/maps.h>
197.29 -#include <vector>
197.30 -#include <lemon/min_cost_flow.h>
197.31 -
197.32 -namespace lemon {
197.33 -
197.34 -/// \addtogroup flowalgs
197.35 -/// @{
197.36 -
197.37 - ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes
197.38 - /// of minimal total length
197.39 - ///
197.40 - /// The class \ref lemon::Suurballe implements
197.41 - /// an algorithm for finding k edge-disjoint paths
197.42 - /// from a given source node to a given target node in an
197.43 - /// edge-weighted directed graph having minimal total weight (length).
197.44 - ///
197.45 - ///\warning Length values should be nonnegative.
197.46 - ///
197.47 - ///\param Graph The directed graph type the algorithm runs on.
197.48 - ///\param LengthMap The type of the length map (values should be nonnegative).
197.49 - ///
197.50 - ///\note It it questionable whether it is correct to call this method after
197.51 - ///%Suurballe for it is just a special case of Edmonds' and Karp's algorithm
197.52 - ///for finding minimum cost flows. In fact, this implementation just
197.53 - ///wraps the MinCostFlow algorithms. The paper of both %Suurballe and
197.54 - ///Edmonds-Karp published in 1972, therefore it is possibly right to
197.55 - ///state that they are
197.56 - ///independent results. Most frequently this special case is referred as
197.57 - ///%Suurballe method in the literature, especially in communication
197.58 - ///network context.
197.59 - ///\author Attila Bernath
197.60 - template <typename Graph, typename LengthMap>
197.61 - class Suurballe{
197.62 -
197.63 -
197.64 - typedef typename LengthMap::Value Length;
197.65 -
197.66 - typedef typename Graph::Node Node;
197.67 - typedef typename Graph::NodeIt NodeIt;
197.68 - typedef typename Graph::Edge Edge;
197.69 - typedef typename Graph::OutEdgeIt OutEdgeIt;
197.70 - typedef typename Graph::template EdgeMap<int> EdgeIntMap;
197.71 -
197.72 - typedef ConstMap<Edge,int> ConstMap;
197.73 -
197.74 - const Graph& G;
197.75 -
197.76 - Node s;
197.77 - Node t;
197.78 -
197.79 - //Auxiliary variables
197.80 - //This is the capacity map for the mincostflow problem
197.81 - ConstMap const1map;
197.82 - //This MinCostFlow instance will actually solve the problem
197.83 - MinCostFlow<Graph, LengthMap, ConstMap> min_cost_flow;
197.84 -
197.85 - //Container to store found paths
197.86 - std::vector< std::vector<Edge> > paths;
197.87 -
197.88 - public :
197.89 -
197.90 -
197.91 - /*! \brief The constructor of the class.
197.92 -
197.93 - \param _G The directed graph the algorithm runs on.
197.94 - \param _length The length (weight or cost) of the edges.
197.95 - \param _s Source node.
197.96 - \param _t Target node.
197.97 - */
197.98 - Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) :
197.99 - G(_G), s(_s), t(_t), const1map(1),
197.100 - min_cost_flow(_G, _length, const1map, _s, _t) { }
197.101 -
197.102 - ///Runs the algorithm.
197.103 -
197.104 - ///Runs the algorithm.
197.105 - ///Returns k if there are at least k edge-disjoint paths from s to t.
197.106 - ///Otherwise it returns the number of edge-disjoint paths found
197.107 - ///from s to t.
197.108 - ///
197.109 - ///\param k How many paths are we looking for?
197.110 - ///
197.111 - int run(int k) {
197.112 - int i = min_cost_flow.run(k);
197.113 -
197.114 - //Let's find the paths
197.115 - //We put the paths into stl vectors (as an inner representation).
197.116 - //In the meantime we lose the information stored in 'reversed'.
197.117 - //We suppose the lengths to be positive now.
197.118 -
197.119 - //We don't want to change the flow of min_cost_flow, so we make a copy
197.120 - //The name here suggests that the flow has only 0/1 values.
197.121 - EdgeIntMap reversed(G);
197.122 -
197.123 - for(typename Graph::EdgeIt e(G); e!=INVALID; ++e)
197.124 - reversed[e] = min_cost_flow.getFlow()[e];
197.125 -
197.126 - paths.clear();
197.127 - //total_length=0;
197.128 - paths.resize(k);
197.129 - for (int j=0; j<i; ++j){
197.130 - Node n=s;
197.131 -
197.132 - while (n!=t){
197.133 -
197.134 - OutEdgeIt e(G, n);
197.135 -
197.136 - while (!reversed[e]){
197.137 - ++e;
197.138 - }
197.139 - n = G.target(e);
197.140 - paths[j].push_back(e);
197.141 - //total_length += length[e];
197.142 - reversed[e] = 1-reversed[e];
197.143 - }
197.144 -
197.145 - }
197.146 - return i;
197.147 - }
197.148 -
197.149 -
197.150 - ///Returns the total length of the paths.
197.151 -
197.152 - ///This function gives back the total length of the found paths.
197.153 - Length totalLength(){
197.154 - return min_cost_flow.totalLength();
197.155 - }
197.156 -
197.157 - ///Returns the found flow.
197.158 -
197.159 - ///This function returns a const reference to the EdgeMap \c flow.
197.160 - const EdgeIntMap &getFlow() const { return min_cost_flow.flow;}
197.161 -
197.162 - /// Returns the optimal dual solution
197.163 -
197.164 - ///This function returns a const reference to the NodeMap
197.165 - ///\c potential (the dual solution).
197.166 - const EdgeIntMap &getPotential() const { return min_cost_flow.potential;}
197.167 -
197.168 - ///Checks whether the complementary slackness holds.
197.169 -
197.170 - ///This function checks, whether the given solution is optimal.
197.171 - ///Currently this function only checks optimality,
197.172 - ///doesn't bother with feasibility
197.173 - ///It is meant for testing purposes.
197.174 - bool checkComplementarySlackness(){
197.175 - return min_cost_flow.checkComplementarySlackness();
197.176 - }
197.177 -
197.178 - ///Read the found paths.
197.179 -
197.180 - ///This function gives back the \c j-th path in argument p.
197.181 - ///Assumes that \c run() has been run and nothing changed since then.
197.182 - /// \warning It is assumed that \c p is constructed to
197.183 - ///be a path of graph \c G.
197.184 - ///If \c j is not less than the result of previous \c run,
197.185 - ///then the result here will be an empty path (\c j can be 0 as well).
197.186 - ///
197.187 - ///\param Path The type of the path structure to put the result to (must meet lemon path concept).
197.188 - ///\param p The path to put the result to
197.189 - ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
197.190 - template<typename Path>
197.191 - void getPath(Path& p, size_t j){
197.192 -
197.193 - p.clear();
197.194 - if (j>paths.size()-1){
197.195 - return;
197.196 - }
197.197 - typename Path::Builder B(p);
197.198 - for(typename std::vector<Edge>::iterator i=paths[j].begin();
197.199 - i!=paths[j].end(); ++i ){
197.200 - B.pushBack(*i);
197.201 - }
197.202 -
197.203 - B.commit();
197.204 - }
197.205 -
197.206 - }; //class Suurballe
197.207 -
197.208 - ///@}
197.209 -
197.210 -} //namespace lemon
197.211 -
197.212 -#endif //LEMON_SUURBALLE_H
198.1 --- a/src/lemon/time_measure.h Sat May 21 21:04:57 2005 +0000
198.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
198.3 @@ -1,255 +0,0 @@
198.4 -/* -*- C++ -*-
198.5 - * src/lemon/time_measure.h - Part of LEMON, a generic C++ optimization library
198.6 - *
198.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
198.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
198.9 - *
198.10 - * Permission to use, modify and distribute this software is granted
198.11 - * provided that this copyright notice appears in all copies. For
198.12 - * precise terms see the accompanying LICENSE file.
198.13 - *
198.14 - * This software is provided "AS IS" with no warranty of any kind,
198.15 - * express or implied, and with no claim as to its suitability for any
198.16 - * purpose.
198.17 - *
198.18 - */
198.19 -
198.20 -#ifndef LEMON_TIME_MEASURE_H
198.21 -#define LEMON_TIME_MEASURE_H
198.22 -
198.23 -///\ingroup misc
198.24 -///\file
198.25 -///\brief Tools for measuring cpu usage
198.26 -
198.27 -#include <sys/time.h>
198.28 -#include <sys/times.h>
198.29 -#include <fstream>
198.30 -#include <iostream>
198.31 -#include <unistd.h>
198.32 -
198.33 -namespace lemon {
198.34 -
198.35 - /// \addtogroup misc
198.36 - /// @{
198.37 -
198.38 - /// A class to store (cpu)time instances.
198.39 -
198.40 - /// This class stores five time values.
198.41 - /// - a real time
198.42 - /// - a user cpu time
198.43 - /// - a system cpu time
198.44 - /// - a user cpu time of children
198.45 - /// - a system cpu time of children
198.46 - ///
198.47 - /// TimeStamp's can be added to or substracted from each other and
198.48 - /// they can be pushed to a stream.
198.49 - ///
198.50 - /// In most cases, perhaps \ref Timer class is what you want to use instead.
198.51 - ///
198.52 - ///\author Alpar Juttner
198.53 -
198.54 - class TimeStamp
198.55 - {
198.56 - tms ts;
198.57 - double real_time;
198.58 -
198.59 - public:
198.60 -
198.61 - tms &getTms() {return ts;}
198.62 - const tms &getTms() const {return ts;}
198.63 - ///Read the current time values of the process
198.64 - void stamp()
198.65 - {
198.66 - timeval tv;
198.67 - times(&ts);
198.68 - gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
198.69 - }
198.70 -
198.71 - /// Constructor initializing with zero
198.72 - TimeStamp()
198.73 - { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
198.74 - ///Constructor initializing with the current time values of the process
198.75 - TimeStamp(void *) { stamp();}
198.76 -
198.77 - ///\e
198.78 - TimeStamp &operator+=(const TimeStamp &b)
198.79 - {
198.80 - ts.tms_utime+=b.ts.tms_utime;
198.81 - ts.tms_stime+=b.ts.tms_stime;
198.82 - ts.tms_cutime+=b.ts.tms_cutime;
198.83 - ts.tms_cstime+=b.ts.tms_cstime;
198.84 - real_time+=b.real_time;
198.85 - return *this;
198.86 - }
198.87 - ///\e
198.88 - TimeStamp operator+(const TimeStamp &b) const
198.89 - {
198.90 - TimeStamp t(*this);
198.91 - return t+=b;
198.92 - }
198.93 - ///\e
198.94 - TimeStamp &operator-=(const TimeStamp &b)
198.95 - {
198.96 - ts.tms_utime-=b.ts.tms_utime;
198.97 - ts.tms_stime-=b.ts.tms_stime;
198.98 - ts.tms_cutime-=b.ts.tms_cutime;
198.99 - ts.tms_cstime-=b.ts.tms_cstime;
198.100 - real_time-=b.real_time;
198.101 - return *this;
198.102 - }
198.103 - ///\e
198.104 - TimeStamp operator-(const TimeStamp &b) const
198.105 - {
198.106 - TimeStamp t(*this);
198.107 - return t-=b;
198.108 - }
198.109 - ///The time ellapsed since the last call of stamp()
198.110 - TimeStamp ellapsed() const
198.111 - {
198.112 - TimeStamp t(NULL);
198.113 - return t-*this;
198.114 - }
198.115 -
198.116 - friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
198.117 -
198.118 - ///Gives back the user time of the process
198.119 - double getUserTime() const
198.120 - {
198.121 - return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
198.122 - }
198.123 - ///Gives back the system time of the process
198.124 - double getSystemTime() const
198.125 - {
198.126 - return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
198.127 - }
198.128 - ///Gives back the user time of the process' children
198.129 - double getCUserTime() const
198.130 - {
198.131 - return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
198.132 - }
198.133 - ///Gives back the user time of the process' children
198.134 - double getCSystemTime() const
198.135 - {
198.136 - return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
198.137 - }
198.138 - ///Gives back the real time of the process
198.139 - double getRealTime() const {return real_time;}
198.140 - };
198.141 -
198.142 - ///Class measuring the cpu time and real time usage of the process
198.143 -
198.144 - ///Class measuring the cpu time and real time usage of the process.
198.145 - ///It is quite easy-to-use, here is a short example.
198.146 - ///\code
198.147 - ///#include<lemon/time_measure.h>
198.148 - ///#include<iostream>
198.149 - ///
198.150 - ///int main()
198.151 - ///{
198.152 - ///
198.153 - /// ...
198.154 - ///
198.155 - /// Timer T;
198.156 - /// doSomething();
198.157 - /// std::cout << T << '\n';
198.158 - /// T.reset();
198.159 - /// doSomethingElse();
198.160 - /// std::cout << T << '\n';
198.161 - ///
198.162 - /// ...
198.163 - ///
198.164 - ///}
198.165 - ///\endcode
198.166 - ///
198.167 - ///\todo This shouldn't be Unix (Linux) specific.
198.168 - ///
198.169 - ///\author Alpar Juttner
198.170 - class Timer
198.171 - {
198.172 - TimeStamp start_time;
198.173 -
198.174 - void _reset() {start_time.stamp();}
198.175 -
198.176 - public:
198.177 - ///Constructor. It starts with zero time counters
198.178 - Timer() {_reset();}
198.179 -
198.180 - ///Computes the ellapsed time
198.181 -
198.182 - ///This conversion computes the ellapsed time
198.183 - ///since the construction of \c t or since
198.184 - ///the last \c t.reset().
198.185 - operator TimeStamp () const
198.186 - {
198.187 - TimeStamp t;
198.188 - t.stamp();
198.189 - return t-start_time;
198.190 - }
198.191 -
198.192 - ///Resets the time counters
198.193 -
198.194 - ///Resets the time counters
198.195 - ///
198.196 - void reset()
198.197 - {
198.198 - _reset();
198.199 - }
198.200 -
198.201 -
198.202 - ///Gives back the ellapsed user time of the process
198.203 - double getUserTime() const
198.204 - {
198.205 - return operator TimeStamp().getUserTime();
198.206 - }
198.207 - ///Gives back the ellapsed system time of the process
198.208 - double getSystemTime() const
198.209 - {
198.210 - return operator TimeStamp().getSystemTime();
198.211 - }
198.212 - ///Gives back the ellapsed user time of the process' children
198.213 - double getCUserTime() const
198.214 - {
198.215 - return operator TimeStamp().getCUserTime();
198.216 - }
198.217 - ///Gives back the ellapsed user time of the process' children
198.218 - double getCSystemTime() const
198.219 - {
198.220 - return operator TimeStamp().getCSystemTime();
198.221 - }
198.222 - ///Gives back the ellapsed real time of the process
198.223 - double getRealTime() const
198.224 - {
198.225 - return operator TimeStamp().getRealTime();
198.226 - }
198.227 -
198.228 - };
198.229 -
198.230 - ///Prints the time counters
198.231 -
198.232 - ///Prints the time counters in the following form:
198.233 - ///
198.234 - /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
198.235 - ///
198.236 - /// where the values are the
198.237 - /// \li \c u: user cpu time,
198.238 - /// \li \c s: system cpu time,
198.239 - /// \li \c cu: user cpu time of children,
198.240 - /// \li \c cs: system cpu time of children,
198.241 - /// \li \c real: real time.
198.242 - /// \relates TimeStamp
198.243 - inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
198.244 - {
198.245 - long cls = sysconf(_SC_CLK_TCK);
198.246 - os << "u: " << double(t.getTms().tms_utime)/cls <<
198.247 - "s, s: " << double(t.getTms().tms_stime)/cls <<
198.248 - "s, cu: " << double(t.getTms().tms_cutime)/cls <<
198.249 - "s, cs: " << double(t.getTms().tms_cstime)/cls <<
198.250 - "s, real: " << t.getRealTime() << "s";
198.251 - return os;
198.252 - }
198.253 -
198.254 - /// @}
198.255 -
198.256 -} //namespace lemon
198.257 -
198.258 -#endif //LEMON_TIME_MEASURE_H
199.1 --- a/src/lemon/unionfind.h Sat May 21 21:04:57 2005 +0000
199.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
199.3 @@ -1,724 +0,0 @@
199.4 -/* -*- C++ -*-
199.5 - * src/lemon/unionfind.h - Part of LEMON, a generic C++ optimization library
199.6 - *
199.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
199.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
199.9 - *
199.10 - * Permission to use, modify and distribute this software is granted
199.11 - * provided that this copyright notice appears in all copies. For
199.12 - * precise terms see the accompanying LICENSE file.
199.13 - *
199.14 - * This software is provided "AS IS" with no warranty of any kind,
199.15 - * express or implied, and with no claim as to its suitability for any
199.16 - * purpose.
199.17 - *
199.18 - */
199.19 -
199.20 -#ifndef LEMON_UNION_FIND_H
199.21 -#define LEMON_UNION_FIND_H
199.22 -
199.23 -//!\ingroup auxdat
199.24 -//!\file
199.25 -//!\brief Union-Find data structures.
199.26 -//!
199.27 -//!\bug unionfind_test.cc doesn't work with Intel compiler. It compiles but
199.28 -//!fails to run (Segmentation fault).
199.29 -
199.30 -
199.31 -#include <vector>
199.32 -#include <list>
199.33 -#include <utility>
199.34 -#include <algorithm>
199.35 -
199.36 -#include <lemon/invalid.h>
199.37 -
199.38 -namespace lemon {
199.39 -
199.40 - //! \addtogroup auxdat
199.41 - //! @{
199.42 -
199.43 - /**
199.44 - * \brief A \e Union-Find data structure implementation
199.45 - *
199.46 - * The class implements the \e Union-Find data structure.
199.47 - * The union operation uses rank heuristic, while
199.48 - * the find operation uses path compression.
199.49 - * This is a very simple but efficient implementation, providing
199.50 - * only four methods: join (union), find, insert and size.
199.51 - * For more features see the \ref UnionFindEnum class.
199.52 - *
199.53 - * It is primarily used in Kruskal algorithm for finding minimal
199.54 - * cost spanning tree in a graph.
199.55 - * \sa kruskal()
199.56 - *
199.57 - * \pre The elements are automatically added only if the map
199.58 - * given to the constructor was filled with -1's. Otherwise you
199.59 - * need to add all the elements by the \ref insert() method.
199.60 - * \bug It is not clear what the constructor parameter is used for.
199.61 - */
199.62 -
199.63 - template <typename T, typename TIntMap>
199.64 - class UnionFind {
199.65 -
199.66 - public:
199.67 - typedef T ElementType;
199.68 - typedef std::pair<int,int> PairType;
199.69 -
199.70 - private:
199.71 - std::vector<PairType> data;
199.72 - TIntMap& map;
199.73 -
199.74 - public:
199.75 - UnionFind(TIntMap& m) : map(m) {}
199.76 -
199.77 - /**
199.78 - * \brief Returns the index of the element's component.
199.79 - *
199.80 - * The method returns the index of the element's component.
199.81 - * This is an integer between zero and the number of inserted elements.
199.82 - */
199.83 -
199.84 - int find(T a)
199.85 - {
199.86 - int comp0 = map[a];
199.87 - if (comp0 < 0) {
199.88 - return insert(a);
199.89 - }
199.90 - int comp = comp0;
199.91 - int next;
199.92 - while ( (next = data[comp].first) != comp) {
199.93 - comp = next;
199.94 - }
199.95 - while ( (next = data[comp0].first) != comp) {
199.96 - data[comp0].first = comp;
199.97 - comp0 = next;
199.98 - }
199.99 -
199.100 - return comp;
199.101 - }
199.102 -
199.103 - /**
199.104 - * \brief Inserts a new element into the structure.
199.105 - *
199.106 - * This method inserts a new element into the data structure.
199.107 - *
199.108 - * It is not required to use this method:
199.109 - * if the map given to the constructor was filled
199.110 - * with -1's then it is called automatically
199.111 - * on the first \ref find or \ref join.
199.112 - *
199.113 - * The method returns the index of the new component.
199.114 - */
199.115 -
199.116 - int insert(T a)
199.117 - {
199.118 - int n = data.size();
199.119 - data.push_back(std::make_pair(n, 1));
199.120 - map.set(a,n);
199.121 - return n;
199.122 - }
199.123 -
199.124 - /**
199.125 - * \brief Joining the components of element \e a and element \e b.
199.126 - *
199.127 - * This is the \e union operation of the Union-Find structure.
199.128 - * Joins the component of element \e a and component of
199.129 - * element \e b. If \e a and \e b are in the same component then
199.130 - * it returns false otherwise it returns true.
199.131 - */
199.132 -
199.133 - bool join(T a, T b)
199.134 - {
199.135 - int ca = find(a);
199.136 - int cb = find(b);
199.137 -
199.138 - if ( ca == cb )
199.139 - return false;
199.140 -
199.141 - if ( data[ca].second > data[cb].second ) {
199.142 - data[cb].first = ca;
199.143 - data[ca].second += data[cb].second;
199.144 - }
199.145 - else {
199.146 - data[ca].first = cb;
199.147 - data[cb].second += data[ca].second;
199.148 - }
199.149 - return true;
199.150 - }
199.151 -
199.152 - /**
199.153 - * \brief Returns the size of the component of element \e a.
199.154 - *
199.155 - * Returns the size of the component of element \e a.
199.156 - */
199.157 -
199.158 - int size(T a)
199.159 - {
199.160 - int ca = find(a);
199.161 - return data[ca].second;
199.162 - }
199.163 -
199.164 - };
199.165 -
199.166 -
199.167 -
199.168 -
199.169 - /*******************************************************/
199.170 -
199.171 -
199.172 -#ifdef DEVELOPMENT_DOCS
199.173 -
199.174 - /**
199.175 - * \brief The auxiliary class for the \ref UnionFindEnum class.
199.176 - *
199.177 - * In the \ref UnionFindEnum class all components are represented as
199.178 - * a std::list.
199.179 - * Items of these lists are UnionFindEnumItem structures.
199.180 - *
199.181 - * The class has four fields:
199.182 - * - T me - the actual element
199.183 - * - IIter parent - the parent of the element in the union-find structure
199.184 - * - int size - the size of the component of the element.
199.185 - * Only valid if the element
199.186 - * is the leader of the component.
199.187 - * - CIter my_class - pointer into the list of components
199.188 - * pointing to the component of the element.
199.189 - * Only valid if the element is the leader of the component.
199.190 - */
199.191 -
199.192 -#endif
199.193 -
199.194 - template <typename T>
199.195 - struct UnionFindEnumItem {
199.196 -
199.197 - typedef std::list<UnionFindEnumItem> ItemList;
199.198 - typedef std::list<ItemList> ClassList;
199.199 - typedef typename ItemList::iterator IIter;
199.200 - typedef typename ClassList::iterator CIter;
199.201 -
199.202 - T me;
199.203 - IIter parent;
199.204 - int size;
199.205 - CIter my_class;
199.206 -
199.207 - UnionFindEnumItem() {}
199.208 - UnionFindEnumItem(const T &_me, CIter _my_class):
199.209 - me(_me), size(1), my_class(_my_class) {}
199.210 - };
199.211 -
199.212 -
199.213 - /**
199.214 - * \brief A \e Union-Find data structure implementation which
199.215 - * is able to enumerate the components.
199.216 - *
199.217 - * The class implements a \e Union-Find data structure
199.218 - * which is able to enumerate the components and the items in
199.219 - * a component. If you don't need this feature then perhaps it's
199.220 - * better to use the \ref UnionFind class which is more efficient.
199.221 - *
199.222 - * The union operation uses rank heuristic, while
199.223 - * the find operation uses path compression.
199.224 - *
199.225 - * \pre You
199.226 - * need to add all the elements by the \ref insert() method.
199.227 - */
199.228 -
199.229 -
199.230 - template <typename T, template <typename Item> class Map>
199.231 - class UnionFindEnum {
199.232 -
199.233 - typedef std::list<UnionFindEnumItem<T> > ItemList;
199.234 - typedef std::list<ItemList> ClassList;
199.235 - typedef typename ItemList::iterator IIter;
199.236 - typedef typename ItemList::const_iterator IcIter;
199.237 - typedef typename ClassList::iterator CIter;
199.238 - typedef typename ClassList::const_iterator CcIter;
199.239 -
199.240 - public:
199.241 - typedef T ElementType;
199.242 - typedef UnionFindEnumItem<T> ItemType;
199.243 - typedef Map< IIter > MapType;
199.244 -
199.245 - private:
199.246 - MapType& m;
199.247 - ClassList classes;
199.248 -
199.249 - IIter _find(IIter a) const {
199.250 - IIter comp = a;
199.251 - IIter next;
199.252 - while( (next = comp->parent) != comp ) {
199.253 - comp = next;
199.254 - }
199.255 -
199.256 - IIter comp1 = a;
199.257 - while( (next = comp1->parent) != comp ) {
199.258 - comp1->parent = comp->parent;
199.259 - comp1 = next;
199.260 - }
199.261 - return comp;
199.262 - }
199.263 -
199.264 - public:
199.265 - UnionFindEnum(MapType& _m) : m(_m) {}
199.266 -
199.267 -
199.268 - /**
199.269 - * \brief Inserts the given element into a new component.
199.270 - *
199.271 - * This method creates a new component consisting only of the
199.272 - * given element.
199.273 - */
199.274 -
199.275 - void insert(const T &a)
199.276 - {
199.277 -
199.278 -
199.279 - classes.push_back(ItemList());
199.280 - CIter aclass = classes.end();
199.281 - --aclass;
199.282 -
199.283 - ItemList &alist = *aclass;
199.284 - alist.push_back(ItemType(a, aclass));
199.285 - IIter ai = alist.begin();
199.286 -
199.287 - ai->parent = ai;
199.288 - m.set(a, ai);
199.289 -
199.290 - }
199.291 -
199.292 - /**
199.293 - * \brief Inserts the given element into the component of the others.
199.294 - *
199.295 - * This methods inserts the element \e a into the component of the
199.296 - * element \e comp.
199.297 - */
199.298 -
199.299 - void insert(const T &a, const T &comp) {
199.300 -
199.301 - IIter clit = _find(m[comp]);
199.302 - ItemList &c = *clit->my_class;
199.303 - c.push_back(ItemType(a,0));
199.304 - IIter ai = c.end();
199.305 - --ai;
199.306 - ai->parent = clit;
199.307 - m.set(a, ai);
199.308 - ++clit->size;
199.309 - }
199.310 -
199.311 -
199.312 - /**
199.313 - * \brief Finds the leader of the component of the given element.
199.314 - *
199.315 - * The method returns the leader of the component of the given element.
199.316 - */
199.317 -
199.318 - T find(const T &a) const {
199.319 - return _find(m[a])->me;
199.320 - }
199.321 -
199.322 -
199.323 - /**
199.324 - * \brief Joining the component of element \e a and element \e b.
199.325 - *
199.326 - * This is the \e union operation of the Union-Find structure.
199.327 - * Joins the component of element \e a and component of
199.328 - * element \e b. If \e a and \e b are in the same component then
199.329 - * returns false else returns true.
199.330 - */
199.331 -
199.332 - bool join(T a, T b) {
199.333 -
199.334 - IIter ca = _find(m[a]);
199.335 - IIter cb = _find(m[b]);
199.336 -
199.337 - if ( ca == cb ) {
199.338 - return false;
199.339 - }
199.340 -
199.341 - if ( ca->size > cb->size ) {
199.342 -
199.343 - cb->parent = ca->parent;
199.344 - ca->size += cb->size;
199.345 -
199.346 - ItemList &alist = *ca->my_class;
199.347 - alist.splice(alist.end(),*cb->my_class);
199.348 -
199.349 - classes.erase(cb->my_class);
199.350 - cb->my_class = 0;
199.351 - }
199.352 - else {
199.353 -
199.354 - ca->parent = cb->parent;
199.355 - cb->size += ca->size;
199.356 -
199.357 - ItemList &blist = *cb->my_class;
199.358 - blist.splice(blist.end(),*ca->my_class);
199.359 -
199.360 - classes.erase(ca->my_class);
199.361 - ca->my_class = 0;
199.362 - }
199.363 -
199.364 - return true;
199.365 - }
199.366 -
199.367 -
199.368 - /**
199.369 - * \brief Returns the size of the component of element \e a.
199.370 - *
199.371 - * Returns the size of the component of element \e a.
199.372 - */
199.373 -
199.374 - int size(const T &a) const {
199.375 - return _find(m[a])->size;
199.376 - }
199.377 -
199.378 -
199.379 - /**
199.380 - * \brief Splits up the component of the element.
199.381 - *
199.382 - * Splitting the component of the element into sigleton
199.383 - * components (component of size one).
199.384 - */
199.385 -
199.386 - void split(const T &a) {
199.387 -
199.388 - IIter ca = _find(m[a]);
199.389 -
199.390 - if ( ca->size == 1 )
199.391 - return;
199.392 -
199.393 - CIter aclass = ca->my_class;
199.394 -
199.395 - for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
199.396 - classes.push_back(ItemList());
199.397 - CIter nl = --classes.end();
199.398 - nl->splice(nl->end(), *aclass, curr);
199.399 -
199.400 - curr->size=1;
199.401 - curr->parent=curr;
199.402 - curr->my_class = nl;
199.403 - }
199.404 -
199.405 - ca->size=1;
199.406 - return;
199.407 - }
199.408 -
199.409 -
199.410 - /**
199.411 - * \brief Sets the given element to the leader element of its component.
199.412 - *
199.413 - * Sets the given element to the leader element of its component.
199.414 - */
199.415 -
199.416 - void makeRep(const T &a) {
199.417 -
199.418 - IIter ia = m[a];
199.419 - IIter la = _find(ia);
199.420 - if (la == ia) return;
199.421 -
199.422 - ia->my_class = la->my_class;
199.423 - la->my_class = 0;
199.424 -
199.425 - ia->size = la->size;
199.426 -
199.427 - CIter l = ia->my_class;
199.428 - l->splice(l->begin(),*l,ia);
199.429 -
199.430 - ia->parent = ia;
199.431 - la->parent = ia;
199.432 - }
199.433 -
199.434 - /**
199.435 - * \brief Moves the given element to an other component.
199.436 - *
199.437 - * This method moves the element \e a from its component
199.438 - * to the component of \e comp.
199.439 - * If \e a and \e comp are in the same component then
199.440 - * it returns false otherwise it returns true.
199.441 - */
199.442 -
199.443 - bool move(const T &a, const T &comp) {
199.444 -
199.445 - IIter ai = m[a];
199.446 - IIter lai = _find(ai);
199.447 - IIter clit = _find(m[comp]);
199.448 -
199.449 - if (lai == clit)
199.450 - return false;
199.451 -
199.452 - ItemList &cl = *clit->my_class,
199.453 - &al = *lai->my_class;
199.454 -
199.455 - bool is_leader = (lai == ai);
199.456 - bool singleton = false;
199.457 -
199.458 - if (is_leader) {
199.459 - ++lai;
199.460 - }
199.461 -
199.462 - cl.splice(cl.end(), al, ai);
199.463 -
199.464 - if (is_leader) {
199.465 - if (ai->size == 1) {
199.466 - classes.erase(ai->my_class);
199.467 - singleton = true;
199.468 - }
199.469 - else {
199.470 - lai->size = ai->size;
199.471 - lai->my_class = ai->my_class;
199.472 - }
199.473 - }
199.474 - if (!singleton) {
199.475 - for (IIter i = lai; i != al.end(); ++i)
199.476 - i->parent = lai;
199.477 - --lai->size;
199.478 - }
199.479 -
199.480 - ai->parent = clit;
199.481 - ai->my_class = 0;
199.482 - ++clit->size;
199.483 -
199.484 - return true;
199.485 - }
199.486 -
199.487 -
199.488 - /**
199.489 - * \brief Removes the given element from the structure.
199.490 - *
199.491 - * Removes the given element from the structure.
199.492 - *
199.493 - * Removes the element from its component and if the component becomes
199.494 - * empty then removes that component from the component list.
199.495 - */
199.496 - void erase(const T &a) {
199.497 -
199.498 - IIter ma = m[a];
199.499 - if (ma == 0) return;
199.500 -
199.501 - IIter la = _find(ma);
199.502 - if (la == ma) {
199.503 - if (ma -> size == 1){
199.504 - classes.erase(ma->my_class);
199.505 - m.set(a,0);
199.506 - return;
199.507 - }
199.508 - ++la;
199.509 - la->size = ma->size;
199.510 - la->my_class = ma->my_class;
199.511 - }
199.512 -
199.513 - for (IIter i = la; i != la->my_class->end(); ++i) {
199.514 - i->parent = la;
199.515 - }
199.516 -
199.517 - la->size--;
199.518 - la->my_class->erase(ma);
199.519 - m.set(a,0);
199.520 - }
199.521 -
199.522 - /**
199.523 - * \brief Removes the component of the given element from the structure.
199.524 - *
199.525 - * Removes the component of the given element from the structure.
199.526 - */
199.527 -
199.528 - void eraseClass(const T &a) {
199.529 - IIter ma = m[a];
199.530 - if (ma == 0) return;
199.531 -# ifdef DEBUG
199.532 - CIter c = _find(ma)->my_class;
199.533 - for (IIter i=c->begin(); i!=c->end(); ++i)
199.534 - m.set(i->me, 0);
199.535 -# endif
199.536 - classes.erase(_find(ma)->my_class);
199.537 - }
199.538 -
199.539 -
199.540 - class ClassIt {
199.541 - friend class UnionFindEnum;
199.542 -
199.543 - CcIter i;
199.544 - public:
199.545 - ClassIt(Invalid): i(0) {}
199.546 - ClassIt() {}
199.547 -
199.548 - operator const T& () const {
199.549 - ItemList const &ll = *i;
199.550 - return (ll.begin())->me; }
199.551 - bool operator == (ClassIt it) const {
199.552 - return (i == it.i);
199.553 - }
199.554 - bool operator != (ClassIt it) const {
199.555 - return (i != it.i);
199.556 - }
199.557 - bool operator < (ClassIt it) const {
199.558 - return (i < it.i);
199.559 - }
199.560 -
199.561 - bool valid() const { return i != 0; }
199.562 - private:
199.563 - void first(const ClassList &l) { i = l.begin(); validate(l); }
199.564 - void next(const ClassList &l) {
199.565 - ++i;
199.566 - validate(l);
199.567 - }
199.568 - void validate(const ClassList &l) {
199.569 - if ( i == l.end() )
199.570 - i = 0;
199.571 - }
199.572 - };
199.573 -
199.574 - /**
199.575 - * \brief Sets the iterator to point to the first component.
199.576 - *
199.577 - * Sets the iterator to point to the first component.
199.578 - *
199.579 - * With the \ref first, \ref valid and \ref next methods you can
199.580 - * iterate through the components. For example:
199.581 - * \code
199.582 - * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
199.583 - * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
199.584 - * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
199.585 - * for (U.first(iter); U.valid(iter); U.next(iter)) {
199.586 - * // iter is convertible to Graph::Node
199.587 - * cout << iter << endl;
199.588 - * }
199.589 - * \endcode
199.590 - */
199.591 -
199.592 - ClassIt& first(ClassIt& it) const {
199.593 - it.first(classes);
199.594 - return it;
199.595 - }
199.596 -
199.597 - /**
199.598 - * \brief Returns whether the iterator is valid.
199.599 - *
199.600 - * Returns whether the iterator is valid.
199.601 - *
199.602 - * With the \ref first, \ref valid and \ref next methods you can
199.603 - * iterate through the components. See the example here: \ref first.
199.604 - */
199.605 -
199.606 - bool valid(ClassIt const &it) const {
199.607 - return it.valid();
199.608 - }
199.609 -
199.610 - /**
199.611 - * \brief Steps the iterator to the next component.
199.612 - *
199.613 - * Steps the iterator to the next component.
199.614 - *
199.615 - * With the \ref first, \ref valid and \ref next methods you can
199.616 - * iterate through the components. See the example here: \ref first.
199.617 - */
199.618 -
199.619 - ClassIt& next(ClassIt& it) const {
199.620 - it.next(classes);
199.621 - return it;
199.622 - }
199.623 -
199.624 -
199.625 - class ItemIt {
199.626 - friend class UnionFindEnum;
199.627 -
199.628 - IcIter i;
199.629 - const ItemList *l;
199.630 - public:
199.631 - ItemIt(Invalid): i(0) {}
199.632 - ItemIt() {}
199.633 -
199.634 - operator const T& () const { return i->me; }
199.635 - bool operator == (ItemIt it) const {
199.636 - return (i == it.i);
199.637 - }
199.638 - bool operator != (ItemIt it) const {
199.639 - return (i != it.i);
199.640 - }
199.641 - bool operator < (ItemIt it) const {
199.642 - return (i < it.i);
199.643 - }
199.644 -
199.645 - bool valid() const { return i != 0; }
199.646 - private:
199.647 - void first(const ItemList &il) { l=&il; i = l->begin(); validate(); }
199.648 - void next() {
199.649 - ++i;
199.650 - validate();
199.651 - }
199.652 - void validate() {
199.653 - if ( i == l->end() )
199.654 - i = 0;
199.655 - }
199.656 - };
199.657 -
199.658 -
199.659 -
199.660 - /**
199.661 - * \brief Sets the iterator to point to the first element of the component.
199.662 - *
199.663 - * \anchor first2
199.664 - * Sets the iterator to point to the first element of the component.
199.665 - *
199.666 - * With the \ref first2 "first", \ref valid2 "valid"
199.667 - * and \ref next2 "next" methods you can
199.668 - * iterate through the elements of a component. For example
199.669 - * (iterating through the component of the node \e node):
199.670 - * \code
199.671 - * Graph::Node node = ...;
199.672 - * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
199.673 - * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
199.674 - * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
199.675 - * for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
199.676 - * // iiter is convertible to Graph::Node
199.677 - * cout << iiter << endl;
199.678 - * }
199.679 - * \endcode
199.680 - */
199.681 -
199.682 - ItemIt& first(ItemIt& it, const T& a) const {
199.683 - it.first( * _find(m[a])->my_class );
199.684 - return it;
199.685 - }
199.686 -
199.687 - /**
199.688 - * \brief Returns whether the iterator is valid.
199.689 - *
199.690 - * \anchor valid2
199.691 - * Returns whether the iterator is valid.
199.692 - *
199.693 - * With the \ref first2 "first", \ref valid2 "valid"
199.694 - * and \ref next2 "next" methods you can
199.695 - * iterate through the elements of a component.
199.696 - * See the example here: \ref first2 "first".
199.697 - */
199.698 -
199.699 - bool valid(ItemIt const &it) const {
199.700 - return it.valid();
199.701 - }
199.702 -
199.703 - /**
199.704 - * \brief Steps the iterator to the next component.
199.705 - *
199.706 - * \anchor next2
199.707 - * Steps the iterator to the next component.
199.708 - *
199.709 - * With the \ref first2 "first", \ref valid2 "valid"
199.710 - * and \ref next2 "next" methods you can
199.711 - * iterate through the elements of a component.
199.712 - * See the example here: \ref first2 "first".
199.713 - */
199.714 -
199.715 - ItemIt& next(ItemIt& it) const {
199.716 - it.next();
199.717 - return it;
199.718 - }
199.719 -
199.720 - };
199.721 -
199.722 -
199.723 - //! @}
199.724 -
199.725 -} //namespace lemon
199.726 -
199.727 -#endif //LEMON_UNION_FIND_H
200.1 --- a/src/lemon/utility.h Sat May 21 21:04:57 2005 +0000
200.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
200.3 @@ -1,153 +0,0 @@
200.4 -/* -*- C++ -*-
200.5 - *
200.6 - * src/lemon/utility.h - Part of LEMON, a generic C++ optimization library
200.7 - *
200.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
200.9 - * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
200.10 - * EGRES).
200.11 - *
200.12 - * Permission to use, modify and distribute this software is granted
200.13 - * provided that this copyright notice appears in all copies. For
200.14 - * precise terms see the accompanying LICENSE file.
200.15 - *
200.16 - * This software is provided "AS IS" with no warranty of any kind,
200.17 - * express or implied, and with no claim as to its suitability for any
200.18 - * purpose.
200.19 - *
200.20 - * This file contains a modified version of the enable_if library from BOOST.
200.21 - * See the appropriate copyright notice below.
200.22 - */
200.23 -
200.24 -// Boost enable_if library
200.25 -
200.26 -// Copyright 2003 © The Trustees of Indiana University.
200.27 -
200.28 -// Use, modification, and distribution is subject to the Boost Software
200.29 -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
200.30 -// http://www.boost.org/LICENSE_1_0.txt)
200.31 -
200.32 -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
200.33 -// Jeremiah Willcock (jewillco at osl.iu.edu)
200.34 -// Andrew Lumsdaine (lums at osl.iu.edu)
200.35 -
200.36 -
200.37 -#ifndef LEMON_UTILITY_H
200.38 -#define LEMON_UTILITY_H
200.39 -
200.40 -namespace lemon
200.41 -{
200.42 -
200.43 - /// Basic type for defining "tags". A "YES" condition for enable_if.
200.44 -
200.45 - /// \todo This should go to a separate "basic_types.h" (or something)
200.46 - /// file.
200.47 - struct True {
200.48 - static const bool value = true;
200.49 - };
200.50 -
200.51 - /// Basic type for defining "tags". A "NO" condition for enable_if.
200.52 - struct False {
200.53 - static const bool value = false;
200.54 - };
200.55 -
200.56 - template <typename T>
200.57 - struct Wrap {
200.58 - const T &value;
200.59 - Wrap(const T &t) : value(t) {}
200.60 - };
200.61 -
200.62 - /**************** dummy class to avoid ambiguity ****************/
200.63 -
200.64 - template<int T> struct dummy { dummy(int) {} };
200.65 -
200.66 - /**************** enable_if from BOOST ****************/
200.67 -
200.68 - template <bool B, class T = void>
200.69 - struct enable_if_c {
200.70 - typedef T type;
200.71 - };
200.72 -
200.73 - template <class T>
200.74 - struct enable_if_c<false, T> {};
200.75 -
200.76 - template <class Cond, class T = void>
200.77 - struct enable_if : public enable_if_c<Cond::value, T> {};
200.78 -
200.79 - template <bool B, class T>
200.80 - struct lazy_enable_if_c {
200.81 - typedef typename T::type type;
200.82 - };
200.83 -
200.84 - template <class T>
200.85 - struct lazy_enable_if_c<false, T> {};
200.86 -
200.87 - template <class Cond, class T>
200.88 - struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
200.89 -
200.90 -
200.91 - template <bool B, class T = void>
200.92 - struct disable_if_c {
200.93 - typedef T type;
200.94 - };
200.95 -
200.96 - template <class T>
200.97 - struct disable_if_c<true, T> {};
200.98 -
200.99 - template <class Cond, class T = void>
200.100 - struct disable_if : public disable_if_c<Cond::value, T> {};
200.101 -
200.102 - template <bool B, class T>
200.103 - struct lazy_disable_if_c {
200.104 - typedef typename T::type type;
200.105 - };
200.106 -
200.107 - template <class T>
200.108 - struct lazy_disable_if_c<true, T> {};
200.109 -
200.110 - template <class Cond, class T>
200.111 - struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
200.112 -
200.113 - // smart referencing
200.114 -
200.115 - template <typename _Type, typename Enable = void>
200.116 - struct SmartReference {
200.117 - typedef _Type& Type;
200.118 - };
200.119 -
200.120 - template <typename _Type>
200.121 - struct SmartReference<
200.122 - _Type,
200.123 - typename enable_if<typename _Type::NeedCopy, void>::type
200.124 - > {
200.125 - typedef _Type Type;
200.126 - };
200.127 -
200.128 - template <typename _Type, typename Enable = void>
200.129 - struct SmartConstReference {
200.130 - typedef const _Type& Type;
200.131 - };
200.132 -
200.133 - template <typename _Type>
200.134 - struct SmartConstReference<
200.135 - _Type,
200.136 - typename enable_if<typename _Type::NeedCopy, void>::type
200.137 - > {
200.138 - typedef const _Type Type;
200.139 - };
200.140 -
200.141 - template <typename _Type, typename Enable = void>
200.142 - struct SmartParameter {
200.143 - typedef _Type& Type;
200.144 - };
200.145 -
200.146 - template <typename _Type>
200.147 - struct SmartParameter<
200.148 - _Type,
200.149 - typename enable_if<typename _Type::NeedCopy, void>::type
200.150 - > {
200.151 - typedef const _Type& Type;
200.152 - };
200.153 -
200.154 -} // namespace lemon
200.155 -
200.156 -#endif
201.1 --- a/src/lemon/xy.h Sat May 21 21:04:57 2005 +0000
201.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
201.3 @@ -1,518 +0,0 @@
201.4 -/* -*- C++ -*-
201.5 - * src/lemon/xy.h - Part of LEMON, a generic C++ optimization library
201.6 - *
201.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
201.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
201.9 - *
201.10 - * Permission to use, modify and distribute this software is granted
201.11 - * provided that this copyright notice appears in all copies. For
201.12 - * precise terms see the accompanying LICENSE file.
201.13 - *
201.14 - * This software is provided "AS IS" with no warranty of any kind,
201.15 - * express or implied, and with no claim as to its suitability for any
201.16 - * purpose.
201.17 - *
201.18 - */
201.19 -
201.20 -#ifndef LEMON_XY_H
201.21 -#define LEMON_XY_H
201.22 -
201.23 -#include <iostream>
201.24 -#include <lemon/utility.h>
201.25 -
201.26 -///\ingroup misc
201.27 -///\file
201.28 -///\brief A simple two dimensional vector and a bounding box implementation
201.29 -///
201.30 -/// The class \ref lemon::xy "xy" implements
201.31 -///a two dimensional vector with the usual
201.32 -/// operations.
201.33 -///
201.34 -/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
201.35 -/// the rectangular bounding box of a set of \ref lemon::xy "xy"'s.
201.36 -///
201.37 -///\author Attila Bernath
201.38 -
201.39 -
201.40 -namespace lemon {
201.41 -
201.42 - /// \addtogroup misc
201.43 - /// @{
201.44 -
201.45 - /// A simple two dimensional vector (plainvector) implementation
201.46 -
201.47 - /// A simple two dimensional vector (plainvector) implementation
201.48 - ///with the usual vector
201.49 - /// operators.
201.50 - ///
201.51 - ///\author Attila Bernath
201.52 - template<typename T>
201.53 - class xy {
201.54 -
201.55 - public:
201.56 -
201.57 - typedef T Value;
201.58 -
201.59 - T x,y;
201.60 -
201.61 - ///Default constructor
201.62 - xy() {}
201.63 -
201.64 - ///Constructing the instance from coordinates
201.65 - xy(T a, T b) : x(a), y(b) { }
201.66 -
201.67 -
201.68 - ///Conversion constructor
201.69 - template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
201.70 -
201.71 - ///Gives back the square of the norm of the vector
201.72 - T normSquare() const {
201.73 - return x*x+y*y;
201.74 - }
201.75 -
201.76 - ///Increments the left hand side by u
201.77 - xy<T>& operator +=(const xy<T>& u) {
201.78 - x += u.x;
201.79 - y += u.y;
201.80 - return *this;
201.81 - }
201.82 -
201.83 - ///Decrements the left hand side by u
201.84 - xy<T>& operator -=(const xy<T>& u) {
201.85 - x -= u.x;
201.86 - y -= u.y;
201.87 - return *this;
201.88 - }
201.89 -
201.90 - ///Multiplying the left hand side with a scalar
201.91 - xy<T>& operator *=(const T &u) {
201.92 - x *= u;
201.93 - y *= u;
201.94 - return *this;
201.95 - }
201.96 -
201.97 - ///Dividing the left hand side by a scalar
201.98 - xy<T>& operator /=(const T &u) {
201.99 - x /= u;
201.100 - y /= u;
201.101 - return *this;
201.102 - }
201.103 -
201.104 - ///Returns the scalar product of two vectors
201.105 - T operator *(const xy<T>& u) const {
201.106 - return x*u.x+y*u.y;
201.107 - }
201.108 -
201.109 - ///Returns the sum of two vectors
201.110 - xy<T> operator+(const xy<T> &u) const {
201.111 - xy<T> b=*this;
201.112 - return b+=u;
201.113 - }
201.114 -
201.115 - ///Returns the neg of the vectors
201.116 - xy<T> operator-() const {
201.117 - xy<T> b=*this;
201.118 - b.x=-b.x; b.y=-b.y;
201.119 - return b;
201.120 - }
201.121 -
201.122 - ///Returns the difference of two vectors
201.123 - xy<T> operator-(const xy<T> &u) const {
201.124 - xy<T> b=*this;
201.125 - return b-=u;
201.126 - }
201.127 -
201.128 - ///Returns a vector multiplied by a scalar
201.129 - xy<T> operator*(const T &u) const {
201.130 - xy<T> b=*this;
201.131 - return b*=u;
201.132 - }
201.133 -
201.134 - ///Returns a vector divided by a scalar
201.135 - xy<T> operator/(const T &u) const {
201.136 - xy<T> b=*this;
201.137 - return b/=u;
201.138 - }
201.139 -
201.140 - ///Testing equality
201.141 - bool operator==(const xy<T> &u) const {
201.142 - return (x==u.x) && (y==u.y);
201.143 - }
201.144 -
201.145 - ///Testing inequality
201.146 - bool operator!=(xy u) const {
201.147 - return (x!=u.x) || (y!=u.y);
201.148 - }
201.149 -
201.150 - };
201.151 -
201.152 - ///Returns a vector multiplied by a scalar
201.153 -
201.154 - ///Returns a vector multiplied by a scalar
201.155 - ///\relates xy
201.156 - template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
201.157 - return x*u;
201.158 - }
201.159 -
201.160 - ///Read a plainvector from a stream
201.161 -
201.162 - ///Read a plainvector from a stream
201.163 - ///\relates xy
201.164 - ///
201.165 - template<typename T>
201.166 - inline std::istream& operator>>(std::istream &is, xy<T> &z) {
201.167 - char c;
201.168 - if (is >> c) {
201.169 - if (c != '(') is.putback(c);
201.170 - } else {
201.171 - is.clear();
201.172 - }
201.173 - if (!(is >> z.x)) return is;
201.174 - if (is >> c) {
201.175 - if (c != ',') is.putback(c);
201.176 - } else {
201.177 - is.clear();
201.178 - }
201.179 - if (!(is >> z.y)) return is;
201.180 - if (is >> c) {
201.181 - if (c != ')') is.putback(c);
201.182 - } else {
201.183 - is.clear();
201.184 - }
201.185 - return is;
201.186 - }
201.187 -
201.188 - ///Write a plainvector to a stream
201.189 -
201.190 - ///Write a plainvector to a stream
201.191 - ///\relates xy
201.192 - ///
201.193 - template<typename T>
201.194 - inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
201.195 - {
201.196 - os << "(" << z.x << ", " << z.y << ")";
201.197 - return os;
201.198 - }
201.199 -
201.200 - ///Rotate by 90 degrees
201.201 -
201.202 - ///Returns its parameter rotated by 90 degrees in positive direction.
201.203 - ///\relates xy
201.204 - ///
201.205 - template<typename T>
201.206 - inline xy<T> rot90(const xy<T> &z)
201.207 - {
201.208 - return xy<T>(-z.y,z.x);
201.209 - }
201.210 -
201.211 - ///Rotate by 270 degrees
201.212 -
201.213 - ///Returns its parameter rotated by 90 degrees in negative direction.
201.214 - ///\relates xy
201.215 - ///
201.216 - template<typename T>
201.217 - inline xy<T> rot270(const xy<T> &z)
201.218 - {
201.219 - return xy<T>(z.y,-z.x);
201.220 - }
201.221 -
201.222 -
201.223 -
201.224 - /// A class to calculate or store the bounding box of plainvectors.
201.225 -
201.226 - /// A class to calculate or store the bounding box of plainvectors.
201.227 - ///
201.228 - ///\author Attila Bernath
201.229 - template<typename T>
201.230 - class BoundingBox {
201.231 - xy<T> bottom_left, top_right;
201.232 - bool _empty;
201.233 - public:
201.234 -
201.235 - ///Default constructor: creates an empty bounding box
201.236 - BoundingBox() { _empty = true; }
201.237 -
201.238 - ///Constructing the instance from one point
201.239 - BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
201.240 -
201.241 - ///Were any points added?
201.242 - bool empty() const {
201.243 - return _empty;
201.244 - }
201.245 -
201.246 - ///Makes the BoundingBox empty
201.247 - void clear() {
201.248 - _empty=1;
201.249 - }
201.250 -
201.251 - ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined)
201.252 - xy<T> bottomLeft() const {
201.253 - return bottom_left;
201.254 - }
201.255 -
201.256 - ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined)
201.257 - xy<T> topRight() const {
201.258 - return top_right;
201.259 - }
201.260 -
201.261 - ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined)
201.262 - xy<T> bottomRight() const {
201.263 - return xy<T>(top_right.x,bottom_left.y);
201.264 - }
201.265 -
201.266 - ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined)
201.267 - xy<T> topLeft() const {
201.268 - return xy<T>(bottom_left.x,top_right.y);
201.269 - }
201.270 -
201.271 - ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined)
201.272 - T bottom() const {
201.273 - return bottom_left.y;
201.274 - }
201.275 -
201.276 - ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined)
201.277 - T top() const {
201.278 - return top_right.y;
201.279 - }
201.280 -
201.281 - ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined)
201.282 - T left() const {
201.283 - return bottom_left.x;
201.284 - }
201.285 -
201.286 - ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined)
201.287 - T right() const {
201.288 - return top_right.x;
201.289 - }
201.290 -
201.291 - ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined)
201.292 - T height() const {
201.293 - return top_right.y-bottom_left.y;
201.294 - }
201.295 -
201.296 - ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined)
201.297 - T width() const {
201.298 - return top_right.x-bottom_left.x;
201.299 - }
201.300 -
201.301 - ///Checks whether a point is inside a bounding box
201.302 - bool inside(const xy<T>& u){
201.303 - if (_empty)
201.304 - return false;
201.305 - else{
201.306 - return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
201.307 - (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
201.308 - }
201.309 - }
201.310 -
201.311 - ///Increments a bounding box with a point
201.312 - BoundingBox& operator +=(const xy<T>& u){
201.313 - if (_empty){
201.314 - bottom_left=top_right=u;
201.315 - _empty = false;
201.316 - }
201.317 - else{
201.318 - if (bottom_left.x > u.x) bottom_left.x = u.x;
201.319 - if (bottom_left.y > u.y) bottom_left.y = u.y;
201.320 - if (top_right.x < u.x) top_right.x = u.x;
201.321 - if (top_right.y < u.y) top_right.y = u.y;
201.322 - }
201.323 - return *this;
201.324 - }
201.325 -
201.326 - ///Sums a bounding box and a point
201.327 - BoundingBox operator +(const xy<T>& u){
201.328 - BoundingBox b = *this;
201.329 - return b += u;
201.330 - }
201.331 -
201.332 - ///Increments a bounding box with an other bounding box
201.333 - BoundingBox& operator +=(const BoundingBox &u){
201.334 - if ( !u.empty() ){
201.335 - *this += u.bottomLeft();
201.336 - *this += u.topRight();
201.337 - }
201.338 - return *this;
201.339 - }
201.340 -
201.341 - ///Sums two bounding boxes
201.342 - BoundingBox operator +(const BoundingBox& u){
201.343 - BoundingBox b = *this;
201.344 - return b += u;
201.345 - }
201.346 -
201.347 - };//class Boundingbox
201.348 -
201.349 -
201.350 - ///Map of x-coordinates of an xy<>-map
201.351 -
201.352 - ///\ingroup maps
201.353 - ///
201.354 - template<class M>
201.355 - class XMap
201.356 - {
201.357 - typename SmartReference<M>::Type _map;
201.358 - public:
201.359 - typedef True NeedCopy;
201.360 -
201.361 - typedef typename M::Value::Value Value;
201.362 - typedef typename M::Key Key;
201.363 - ///\e
201.364 - XMap(typename SmartParameter<M>::Type map) : _map(map) {}
201.365 - Value operator[](Key k) const {return _map[k].x;}
201.366 - void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
201.367 - };
201.368 -
201.369 - ///Returns an \ref XMap class
201.370 -
201.371 - ///This function just returns an \ref XMap class.
201.372 - ///
201.373 - ///\ingroup maps
201.374 - ///\relates XMap
201.375 - template<class M>
201.376 - inline XMap<M> xMap(M &m)
201.377 - {
201.378 - return XMap<M>(m);
201.379 - }
201.380 -
201.381 - template<class M>
201.382 - inline XMap<M> xMap(const M &m)
201.383 - {
201.384 - return XMap<M>(m);
201.385 - }
201.386 -
201.387 - ///Constant (read only) version of \ref XMap
201.388 -
201.389 - ///\ingroup maps
201.390 - ///
201.391 - template<class M>
201.392 - class ConstXMap
201.393 - {
201.394 - typename SmartConstReference<M>::Type _map;
201.395 - public:
201.396 - typedef True NeedCopy;
201.397 -
201.398 - typedef typename M::Value::Value Value;
201.399 - typedef typename M::Key Key;
201.400 - ///\e
201.401 - ConstXMap(const M &map) : _map(map) {}
201.402 - Value operator[](Key k) const {return _map[k].x;}
201.403 - };
201.404 -
201.405 - ///Returns a \ref ConstXMap class
201.406 -
201.407 - ///This function just returns an \ref ConstXMap class.
201.408 - ///
201.409 - ///\ingroup maps
201.410 - ///\relates ConstXMap
201.411 - template<class M>
201.412 - inline ConstXMap<M> xMap(const M &m)
201.413 - {
201.414 - return ConstXMap<M>(m);
201.415 - }
201.416 -
201.417 - ///Map of y-coordinates of an xy<>-map
201.418 -
201.419 - ///\ingroup maps
201.420 - ///
201.421 - template<class M>
201.422 - class YMap
201.423 - {
201.424 - typename SmartReference<M>::Type _map;
201.425 - public:
201.426 - typedef True NeedCopy;
201.427 -
201.428 - typedef typename M::Value::Value Value;
201.429 - typedef typename M::Key Key;
201.430 - ///\e
201.431 - YMap(typename SmartParameter<M>::Type map) : _map(map) {}
201.432 - Value operator[](Key k) const {return _map[k].y;}
201.433 - void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
201.434 - };
201.435 -
201.436 - ///Returns an \ref YMap class
201.437 -
201.438 - ///This function just returns an \ref YMap class.
201.439 - ///
201.440 - ///\ingroup maps
201.441 - ///\relates YMap
201.442 - template<class M>
201.443 - inline YMap<M> yMap(M &m)
201.444 - {
201.445 - return YMap<M>(m);
201.446 - }
201.447 -
201.448 - template<class M>
201.449 - inline YMap<M> yMap(const M &m)
201.450 - {
201.451 - return YMap<M>(m);
201.452 - }
201.453 -
201.454 - ///Constant (read only) version of \ref YMap
201.455 -
201.456 - ///\ingroup maps
201.457 - ///
201.458 - template<class M>
201.459 - class ConstYMap
201.460 - {
201.461 - typename SmartConstReference<M>::Type _map;
201.462 - public:
201.463 - typedef True NeedCopy;
201.464 -
201.465 - typedef typename M::Value::Value Value;
201.466 - typedef typename M::Key Key;
201.467 - ///\e
201.468 - ConstYMap(const M &map) : _map(map) {}
201.469 - Value operator[](Key k) const {return _map[k].y;}
201.470 - };
201.471 -
201.472 - ///Returns a \ref ConstYMap class
201.473 -
201.474 - ///This function just returns an \ref ConstYMap class.
201.475 - ///
201.476 - ///\ingroup maps
201.477 - ///\relates ConstYMap
201.478 - template<class M>
201.479 - inline ConstYMap<M> yMap(const M &m)
201.480 - {
201.481 - return ConstYMap<M>(m);
201.482 - }
201.483 -
201.484 -
201.485 - ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
201.486 -
201.487 - ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
201.488 - ///\ingroup maps
201.489 - ///
201.490 - template<class M>
201.491 - class NormSquareMap
201.492 - {
201.493 - typename SmartConstReference<M>::Type _map;
201.494 - public:
201.495 - typedef True NeedCopy;
201.496 -
201.497 - typedef typename M::Value::Value Value;
201.498 - typedef typename M::Key Key;
201.499 - ///\e
201.500 - NormSquareMap(const M &map) : _map(map) {}
201.501 - Value operator[](Key k) const {return _map[k].normSquare();}
201.502 - };
201.503 -
201.504 - ///Returns a \ref NormSquareMap class
201.505 -
201.506 - ///This function just returns an \ref NormSquareMap class.
201.507 - ///
201.508 - ///\ingroup maps
201.509 - ///\relates NormSquareMap
201.510 - template<class M>
201.511 - inline NormSquareMap<M> normSquareMap(const M &m)
201.512 - {
201.513 - return NormSquareMap<M>(m);
201.514 - }
201.515 -
201.516 - /// @}
201.517 -
201.518 -
201.519 -} //namespace lemon
201.520 -
201.521 -#endif //LEMON_XY_H
202.1 --- a/src/test/Makefile.am Sat May 21 21:04:57 2005 +0000
202.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
202.3 @@ -1,69 +0,0 @@
202.4 -AM_CPPFLAGS = -I$(top_srcdir)/src
202.5 -LDADD = $(top_builddir)/src/lemon/libemon.la
202.6 -
202.7 -EXTRA_DIST = preflow_graph.dim dijkstra_test.lgf
202.8 -
202.9 -noinst_HEADERS = \
202.10 - test_tools.h \
202.11 - graph_test.h \
202.12 - sym_graph_test.h \
202.13 - map_test.h \
202.14 - graph_utils_test.h \
202.15 - heap_test.h
202.16 -
202.17 -check_PROGRAMS = \
202.18 - bfs_test \
202.19 - dfs_test \
202.20 - dijkstra_test \
202.21 - graph_test \
202.22 - graph_adaptor_test \
202.23 - graph_utils_test \
202.24 - kruskal_test \
202.25 - max_matching_test \
202.26 - maps_test \
202.27 - min_cost_flow_test \
202.28 - suurballe_test \
202.29 - path_test \
202.30 - preflow_test \
202.31 - test_tools_fail \
202.32 - test_tools_pass \
202.33 - time_measure_test \
202.34 - unionfind_test \
202.35 - undir_graph_test \
202.36 - xy_test \
202.37 - heap_test
202.38 -
202.39 -if HAVE_GLPK
202.40 -check_PROGRAMS += lp_test
202.41 -else !HAVE_GLPK
202.42 -if HAVE_CPLEX
202.43 -check_PROGRAMS += lp_test
202.44 -endif HAVE_CPLEX
202.45 -endif !HAVE_GLPK
202.46 -
202.47 -TESTS = $(check_PROGRAMS)
202.48 -XFAIL_TESTS = test_tools_fail$(EXEEXT)
202.49 -
202.50 -bfs_test_SOURCES = bfs_test.cc
202.51 -dfs_test_SOURCES = dfs_test.cc
202.52 -dijkstra_test_SOURCES = dijkstra_test.cc
202.53 -graph_test_SOURCES = graph_test.cc
202.54 -graph_utils_test_SOURCES = graph_utils_test.cc
202.55 -graph_adaptor_test_SOURCES = graph_adaptor_test.cc
202.56 -kruskal_test_SOURCES = kruskal_test.cc
202.57 -maps_test_SOURCES = maps_test.cc
202.58 -min_cost_flow_test_SOURCES = min_cost_flow_test.cc
202.59 -max_matching_test_SOURCES = max_matching_test.cc
202.60 -suurballe_test_SOURCES = suurballe_test.cc
202.61 -path_test_SOURCES = path_test.cc
202.62 -preflow_test_SOURCES = preflow_test.cc
202.63 -time_measure_test_SOURCES = time_measure_test.cc
202.64 -test_tools_fail_SOURCES = test_tools_fail.cc
202.65 -test_tools_pass_SOURCES = test_tools_pass.cc
202.66 -unionfind_test_SOURCES = unionfind_test.cc
202.67 -xy_test_SOURCES = xy_test.cc
202.68 -undir_graph_test_SOURCES = undir_graph_test.cc
202.69 -heap_test_SOURCES = heap_test.cc
202.70 -
202.71 -lp_test_SOURCES = lp_test.cc
202.72 -lp_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
203.1 --- a/src/test/bfs_test.cc Sat May 21 21:04:57 2005 +0000
203.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
203.3 @@ -1,135 +0,0 @@
203.4 -/* -*- C++ -*-
203.5 - * src/test/bfs_test.cc - Part of LEMON, a generic C++ optimization library
203.6 - *
203.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
203.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
203.9 - *
203.10 - * Permission to use, modify and distribute this software is granted
203.11 - * provided that this copyright notice appears in all copies. For
203.12 - * precise terms see the accompanying LICENSE file.
203.13 - *
203.14 - * This software is provided "AS IS" with no warranty of any kind,
203.15 - * express or implied, and with no claim as to its suitability for any
203.16 - * purpose.
203.17 - *
203.18 - */
203.19 -
203.20 -#include "test_tools.h"
203.21 -#include <lemon/smart_graph.h>
203.22 -#include <lemon/bfs.h>
203.23 -#include <lemon/path.h>
203.24 -#include<lemon/concept/graph.h>
203.25 -
203.26 -using namespace lemon;
203.27 -
203.28 -const int PET_SIZE =5;
203.29 -
203.30 -
203.31 -void check_Bfs_Compile()
203.32 -{
203.33 - typedef concept::StaticGraph Graph;
203.34 -
203.35 - typedef Graph::Edge Edge;
203.36 - typedef Graph::Node Node;
203.37 - typedef Graph::EdgeIt EdgeIt;
203.38 - typedef Graph::NodeIt NodeIt;
203.39 -
203.40 - typedef Bfs<Graph> BType;
203.41 -
203.42 - Graph G;
203.43 - Node n;
203.44 - Edge e;
203.45 - int l;
203.46 - bool b;
203.47 - BType::DistMap d(G);
203.48 - BType::PredMap p(G);
203.49 - // BType::PredNodeMap pn(G);
203.50 -
203.51 - BType bfs_test(G);
203.52 -
203.53 - bfs_test.run(n);
203.54 -
203.55 - l = bfs_test.dist(n);
203.56 - e = bfs_test.pred(n);
203.57 - n = bfs_test.predNode(n);
203.58 - d = bfs_test.distMap();
203.59 - p = bfs_test.predMap();
203.60 - // pn = bfs_test.predNodeMap();
203.61 - b = bfs_test.reached(n);
203.62 -
203.63 - DirPath<Graph> pp(G);
203.64 - bfs_test.getPath(pp,n);
203.65 -}
203.66 -
203.67 -void check_Bfs_Function_Compile()
203.68 -{
203.69 - typedef int VType;
203.70 - typedef concept::StaticGraph Graph;
203.71 -
203.72 - typedef Graph::Edge Edge;
203.73 - typedef Graph::Node Node;
203.74 - typedef Graph::EdgeIt EdgeIt;
203.75 - typedef Graph::NodeIt NodeIt;
203.76 - typedef concept::ReadMap<Edge,VType> LengthMap;
203.77 -
203.78 - bfs(Graph(),Node()).run();
203.79 - bfs(Graph()).source(Node()).run();
203.80 - bfs(Graph())
203.81 - .predMap(concept::WriteMap<Node,Edge>())
203.82 - .distMap(concept::WriteMap<Node,VType>())
203.83 - .reachedMap(concept::ReadWriteMap<Node,bool>())
203.84 - .processedMap(concept::WriteMap<Node,bool>())
203.85 - .run(Node());
203.86 -
203.87 -}
203.88 -
203.89 -int main()
203.90 -{
203.91 -
203.92 - typedef SmartGraph Graph;
203.93 -
203.94 - typedef Graph::Edge Edge;
203.95 - typedef Graph::Node Node;
203.96 - typedef Graph::EdgeIt EdgeIt;
203.97 - typedef Graph::NodeIt NodeIt;
203.98 - typedef Graph::EdgeMap<int> LengthMap;
203.99 -
203.100 - Graph G;
203.101 - Node s, t;
203.102 - PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
203.103 -
203.104 - s=ps.outer[2];
203.105 - t=ps.inner[0];
203.106 -
203.107 - Bfs<Graph> bfs_test(G);
203.108 - bfs_test.run(s);
203.109 -
203.110 - check(bfs_test.dist(t)==3,"Bfs found a wrong path. " << bfs_test.dist(t));
203.111 -
203.112 - DirPath<Graph> p(G);
203.113 - check(bfs_test.getPath(p,t),"getPath() failed to set the path.");
203.114 - check(p.length()==3,"getPath() found a wrong path.");
203.115 -
203.116 -
203.117 - for(EdgeIt e(G); e==INVALID; ++e) {
203.118 - Node u=G.source(e);
203.119 - Node v=G.target(e);
203.120 - check( !bfs_test.reached(u) ||
203.121 - (bfs_test.dist(v) > bfs_test.dist(u)+1),
203.122 - "Wrong output.");
203.123 - }
203.124 -
203.125 - for(NodeIt v(G); v==INVALID; ++v) {
203.126 - check(bfs_test.reached(v),"Each node should be reached.");
203.127 - if ( bfs_test.pred(v)!=INVALID ) {
203.128 - Edge e=bfs_test.pred(v);
203.129 - Node u=G.source(e);
203.130 - check(u==bfs_test.predNode(v),"Wrong tree.");
203.131 - check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
203.132 - "Wrong distance. Difference: "
203.133 - << std::abs(bfs_test.dist(v) - bfs_test.dist(u)
203.134 - - 1));
203.135 - }
203.136 - }
203.137 -}
203.138 -
204.1 --- a/src/test/dfs_test.cc Sat May 21 21:04:57 2005 +0000
204.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
204.3 @@ -1,124 +0,0 @@
204.4 -/* -*- C++ -*-
204.5 - * src/test/dfs_test.cc - Part of LEMON, a generic C++ optimization library
204.6 - *
204.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
204.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
204.9 - *
204.10 - * Permission to use, modify and distribute this software is granted
204.11 - * provided that this copyright notice appears in all copies. For
204.12 - * precise terms see the accompanying LICENSE file.
204.13 - *
204.14 - * This software is provided "AS IS" with no warranty of any kind,
204.15 - * express or implied, and with no claim as to its suitability for any
204.16 - * purpose.
204.17 - *
204.18 - */
204.19 -
204.20 -#include "test_tools.h"
204.21 -#include <lemon/smart_graph.h>
204.22 -#include <lemon/dfs.h>
204.23 -#include <lemon/path.h>
204.24 -#include <lemon/concept/graph.h>
204.25 -
204.26 -using namespace lemon;
204.27 -
204.28 -const int PET_SIZE =5;
204.29 -
204.30 -
204.31 -void check_Dfs_SmartGraph_Compile()
204.32 -{
204.33 - typedef concept::StaticGraph Graph;
204.34 -
204.35 - typedef Graph::Edge Edge;
204.36 - typedef Graph::Node Node;
204.37 - typedef Graph::EdgeIt EdgeIt;
204.38 - typedef Graph::NodeIt NodeIt;
204.39 -
204.40 - typedef Dfs<Graph> DType;
204.41 -
204.42 - Graph G;
204.43 - Node n;
204.44 - Edge e;
204.45 - int l;
204.46 - bool b;
204.47 - DType::DistMap d(G);
204.48 - DType::PredMap p(G);
204.49 - // DType::PredNodeMap pn(G);
204.50 -
204.51 - DType dfs_test(G);
204.52 -
204.53 - dfs_test.run(n);
204.54 -
204.55 - l = dfs_test.dist(n);
204.56 - e = dfs_test.pred(n);
204.57 - n = dfs_test.predNode(n);
204.58 - d = dfs_test.distMap();
204.59 - p = dfs_test.predMap();
204.60 - // pn = dfs_test.predNodeMap();
204.61 - b = dfs_test.reached(n);
204.62 -
204.63 - DirPath<Graph> pp(G);
204.64 - dfs_test.getPath(pp,n);
204.65 -}
204.66 -
204.67 -
204.68 -void check_Dfs_Function_Compile()
204.69 -{
204.70 - typedef int VType;
204.71 - typedef concept::StaticGraph Graph;
204.72 -
204.73 - typedef Graph::Edge Edge;
204.74 - typedef Graph::Node Node;
204.75 - typedef Graph::EdgeIt EdgeIt;
204.76 - typedef Graph::NodeIt NodeIt;
204.77 - typedef concept::ReadMap<Edge,VType> LengthMap;
204.78 -
204.79 - dfs(Graph(),Node()).run();
204.80 - dfs(Graph()).source(Node()).run();
204.81 - dfs(Graph())
204.82 - .predMap(concept::WriteMap<Node,Edge>())
204.83 - .distMap(concept::WriteMap<Node,VType>())
204.84 - .reachedMap(concept::ReadWriteMap<Node,bool>())
204.85 - .processedMap(concept::WriteMap<Node,bool>())
204.86 - .run(Node());
204.87 -
204.88 -}
204.89 -
204.90 -int main()
204.91 -{
204.92 -
204.93 - typedef SmartGraph Graph;
204.94 -
204.95 - typedef Graph::Edge Edge;
204.96 - typedef Graph::Node Node;
204.97 - typedef Graph::EdgeIt EdgeIt;
204.98 - typedef Graph::NodeIt NodeIt;
204.99 - typedef Graph::EdgeMap<int> LengthMap;
204.100 -
204.101 - Graph G;
204.102 - Node s, t;
204.103 - PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
204.104 -
204.105 - s=ps.outer[2];
204.106 - t=ps.inner[0];
204.107 -
204.108 - Dfs<Graph> dfs_test(G);
204.109 - dfs_test.run(s);
204.110 -
204.111 - DirPath<Graph> p(G);
204.112 - check(dfs_test.getPath(p,t),"getPath() failed to set the path.");
204.113 - check(p.length()==dfs_test.dist(t),"getPath() found a wrong path.");
204.114 -
204.115 - for(NodeIt v(G); v!=INVALID; ++v) {
204.116 - check(dfs_test.reached(v),"Each node should be reached.");
204.117 - if ( dfs_test.pred(v)!=INVALID ) {
204.118 - Edge e=dfs_test.pred(v);
204.119 - Node u=G.source(e);
204.120 - check(u==dfs_test.predNode(v),"Wrong tree.");
204.121 - check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
204.122 - "Wrong distance. (" << dfs_test.dist(u) << "->"
204.123 - <<dfs_test.dist(v) << ')');
204.124 - }
204.125 - }
204.126 -}
204.127 -
205.1 --- a/src/test/dijkstra_test.cc Sat May 21 21:04:57 2005 +0000
205.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
205.3 @@ -1,155 +0,0 @@
205.4 -/* -*- C++ -*-
205.5 - * src/test/dijkstra_test.cc - Part of LEMON, a generic C++ optimization library
205.6 - *
205.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
205.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
205.9 - *
205.10 - * Permission to use, modify and distribute this software is granted
205.11 - * provided that this copyright notice appears in all copies. For
205.12 - * precise terms see the accompanying LICENSE file.
205.13 - *
205.14 - * This software is provided "AS IS" with no warranty of any kind,
205.15 - * express or implied, and with no claim as to its suitability for any
205.16 - * purpose.
205.17 - *
205.18 - */
205.19 -
205.20 -#include "test_tools.h"
205.21 -#include <lemon/smart_graph.h>
205.22 -#include <lemon/dijkstra.h>
205.23 -#include <lemon/path.h>
205.24 -#include <lemon/maps.h>
205.25 -#include <lemon/concept/graph.h>
205.26 -#include <lemon/concept/maps.h>
205.27 -using namespace lemon;
205.28 -
205.29 -const int PET_SIZE =5;
205.30 -
205.31 -
205.32 -void check_Dijkstra_BinHeap_Compile()
205.33 -{
205.34 - typedef int VType;
205.35 - typedef concept::StaticGraph Graph;
205.36 -
205.37 - typedef Graph::Edge Edge;
205.38 - typedef Graph::Node Node;
205.39 - typedef Graph::EdgeIt EdgeIt;
205.40 - typedef Graph::NodeIt NodeIt;
205.41 - typedef concept::ReadMap<Edge,VType> LengthMap;
205.42 -
205.43 - typedef Dijkstra<Graph, LengthMap> DType;
205.44 -
205.45 - Graph G;
205.46 - Node n;
205.47 - Edge e;
205.48 - VType l;
205.49 - bool b;
205.50 - DType::DistMap d(G);
205.51 - DType::PredMap p(G);
205.52 - // DType::PredNodeMap pn(G);
205.53 - LengthMap cap;
205.54 -
205.55 - DType dijkstra_test(G,cap);
205.56 -
205.57 - dijkstra_test.run(n);
205.58 -
205.59 - l = dijkstra_test.dist(n);
205.60 - e = dijkstra_test.pred(n);
205.61 - n = dijkstra_test.predNode(n);
205.62 - d = dijkstra_test.distMap();
205.63 - p = dijkstra_test.predMap();
205.64 - // pn = dijkstra_test.predNodeMap();
205.65 - b = dijkstra_test.reached(n);
205.66 -
205.67 - DirPath<Graph> pp(G);
205.68 - dijkstra_test.getPath(pp,n);
205.69 -}
205.70 -
205.71 -void check_Dijkstra_Function_Compile()
205.72 -{
205.73 - typedef int VType;
205.74 - typedef concept::StaticGraph Graph;
205.75 -
205.76 - typedef Graph::Edge Edge;
205.77 - typedef Graph::Node Node;
205.78 - typedef Graph::EdgeIt EdgeIt;
205.79 - typedef Graph::NodeIt NodeIt;
205.80 - typedef concept::ReadMap<Edge,VType> LengthMap;
205.81 -
205.82 - dijkstra(Graph(),LengthMap(),Node()).run();
205.83 - dijkstra(Graph(),LengthMap()).source(Node()).run();
205.84 - dijkstra(Graph(),LengthMap())
205.85 - .predMap(concept::WriteMap<Node,Edge>())
205.86 - .distMap(concept::WriteMap<Node,VType>())
205.87 - .run(Node());
205.88 -
205.89 -}
205.90 -
205.91 -
205.92 -int main()
205.93 -{
205.94 -
205.95 - typedef SmartGraph Graph;
205.96 -
205.97 - typedef Graph::Edge Edge;
205.98 - typedef Graph::Node Node;
205.99 - typedef Graph::EdgeIt EdgeIt;
205.100 - typedef Graph::NodeIt NodeIt;
205.101 - typedef Graph::EdgeMap<int> LengthMap;
205.102 -
205.103 - Graph G;
205.104 - Node s, t;
205.105 - LengthMap cap(G);
205.106 - PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
205.107 -
205.108 - for(int i=0;i<PET_SIZE;i++) {
205.109 - cap[ps.outcir[i]]=4;
205.110 - cap[ps.incir[i]]=1;
205.111 - cap[ps.chords[i]]=10;
205.112 - }
205.113 - s=ps.outer[0];
205.114 - t=ps.inner[1];
205.115 -
205.116 - Dijkstra<Graph, LengthMap>
205.117 - dijkstra_test(G, cap);
205.118 - dijkstra_test.run(s);
205.119 -
205.120 - check(dijkstra_test.dist(t)==13,"Dijkstra found a wrong path.");
205.121 -
205.122 -
205.123 - DirPath<Graph> p(G);
205.124 - check(dijkstra_test.getPath(p,t),"getPath() failed to set the path.");
205.125 - check(p.length()==4,"getPath() found a wrong path.");
205.126 -
205.127 -
205.128 - for(EdgeIt e(G); e!=INVALID; ++e) {
205.129 - Node u=G.source(e);
205.130 - Node v=G.target(e);
205.131 - check( !dijkstra_test.reached(u) ||
205.132 - (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= cap[e]),
205.133 - "dist(target)-dist(source)- edge_length= "
205.134 - << dijkstra_test.dist(v) - dijkstra_test.dist(u)
205.135 - - cap[e]);
205.136 - }
205.137 -
205.138 - ///\bug This works only for integer lengths
205.139 - for(NodeIt v(G); v!=INVALID; ++v){
205.140 - check(dijkstra_test.reached(v),"Each node should be reached.");
205.141 - if ( dijkstra_test.pred(v)!=INVALID ) {
205.142 - Edge e=dijkstra_test.pred(v);
205.143 - Node u=G.source(e);
205.144 - check(u==dijkstra_test.predNode(v),"Wrong tree.");
205.145 - check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == cap[e],
205.146 - "Wrong distance! Difference: "
205.147 - << std::abs(dijkstra_test.dist(v) - dijkstra_test.dist(u)
205.148 - - cap[e]));
205.149 - }
205.150 - }
205.151 -
205.152 -
205.153 - {
205.154 - NullMap<Node,Edge> myPredMap;
205.155 - dijkstra(G,cap).predMap(myPredMap).run(s);
205.156 - }
205.157 - return 0;
205.158 -}
206.1 --- a/src/test/dijkstra_test.lgf Sat May 21 21:04:57 2005 +0000
206.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
206.3 @@ -1,7914 +0,0 @@
206.4 -@nodeset
206.5 -id
206.6 -999
206.7 -998
206.8 -997
206.9 -996
206.10 -995
206.11 -994
206.12 -993
206.13 -992
206.14 -991
206.15 -990
206.16 -989
206.17 -988
206.18 -987
206.19 -986
206.20 -985
206.21 -984
206.22 -983
206.23 -982
206.24 -981
206.25 -980
206.26 -979
206.27 -978
206.28 -977
206.29 -976
206.30 -975
206.31 -974
206.32 -973
206.33 -972
206.34 -971
206.35 -970
206.36 -969
206.37 -968
206.38 -967
206.39 -966
206.40 -965
206.41 -964
206.42 -963
206.43 -962
206.44 -961
206.45 -960
206.46 -959
206.47 -958
206.48 -957
206.49 -956
206.50 -955
206.51 -954
206.52 -953
206.53 -952
206.54 -951
206.55 -950
206.56 -949
206.57 -948
206.58 -947
206.59 -946
206.60 -945
206.61 -944
206.62 -943
206.63 -942
206.64 -941
206.65 -940
206.66 -939
206.67 -938
206.68 -937
206.69 -936
206.70 -935
206.71 -934
206.72 -933
206.73 -932
206.74 -931
206.75 -930
206.76 -929
206.77 -928
206.78 -927
206.79 -926
206.80 -925
206.81 -924
206.82 -923
206.83 -922
206.84 -921
206.85 -920
206.86 -919
206.87 -918
206.88 -917
206.89 -916
206.90 -915
206.91 -914
206.92 -913
206.93 -912
206.94 -911
206.95 -910
206.96 -909
206.97 -908
206.98 -907
206.99 -906
206.100 -905
206.101 -904
206.102 -903
206.103 -902
206.104 -901
206.105 -900
206.106 -899
206.107 -898
206.108 -897
206.109 -896
206.110 -895
206.111 -894
206.112 -893
206.113 -892
206.114 -891
206.115 -890
206.116 -889
206.117 -888
206.118 -887
206.119 -886
206.120 -885
206.121 -884
206.122 -883
206.123 -882
206.124 -881
206.125 -880
206.126 -879
206.127 -878
206.128 -877
206.129 -876
206.130 -875
206.131 -874
206.132 -873
206.133 -872
206.134 -871
206.135 -870
206.136 -869
206.137 -868
206.138 -867
206.139 -866
206.140 -865
206.141 -864
206.142 -863
206.143 -862
206.144 -861
206.145 -860
206.146 -859
206.147 -858
206.148 -857
206.149 -856
206.150 -855
206.151 -854
206.152 -853
206.153 -852
206.154 -851
206.155 -850
206.156 -849
206.157 -848
206.158 -847
206.159 -846
206.160 -845
206.161 -844
206.162 -843
206.163 -842
206.164 -841
206.165 -840
206.166 -839
206.167 -838
206.168 -837
206.169 -836
206.170 -835
206.171 -834
206.172 -833
206.173 -832
206.174 -831
206.175 -830
206.176 -829
206.177 -828
206.178 -827
206.179 -826
206.180 -825
206.181 -824
206.182 -823
206.183 -822
206.184 -821
206.185 -820
206.186 -819
206.187 -818
206.188 -817
206.189 -816
206.190 -815
206.191 -814
206.192 -813
206.193 -812
206.194 -811
206.195 -810
206.196 -809
206.197 -808
206.198 -807
206.199 -806
206.200 -805
206.201 -804
206.202 -803
206.203 -802
206.204 -801
206.205 -800
206.206 -799
206.207 -798
206.208 -797
206.209 -796
206.210 -795
206.211 -794
206.212 -793
206.213 -792
206.214 -791
206.215 -790
206.216 -789
206.217 -788
206.218 -787
206.219 -786
206.220 -785
206.221 -784
206.222 -783
206.223 -782
206.224 -781
206.225 -780
206.226 -779
206.227 -778
206.228 -777
206.229 -776
206.230 -775
206.231 -774
206.232 -773
206.233 -772
206.234 -771
206.235 -770
206.236 -769
206.237 -768
206.238 -767
206.239 -766
206.240 -765
206.241 -764
206.242 -763
206.243 -762
206.244 -761
206.245 -760
206.246 -759
206.247 -758
206.248 -757
206.249 -756
206.250 -755
206.251 -754
206.252 -753
206.253 -752
206.254 -751
206.255 -750
206.256 -749
206.257 -748
206.258 -747
206.259 -746
206.260 -745
206.261 -744
206.262 -743
206.263 -742
206.264 -741
206.265 -740
206.266 -739
206.267 -738
206.268 -737
206.269 -736
206.270 -735
206.271 -734
206.272 -733
206.273 -732
206.274 -731
206.275 -730
206.276 -729
206.277 -728
206.278 -727
206.279 -726
206.280 -725
206.281 -724
206.282 -723
206.283 -722
206.284 -721
206.285 -720
206.286 -719
206.287 -718
206.288 -717
206.289 -716
206.290 -715
206.291 -714
206.292 -713
206.293 -712
206.294 -711
206.295 -710
206.296 -709
206.297 -708
206.298 -707
206.299 -706
206.300 -705
206.301 -704
206.302 -703
206.303 -702
206.304 -701
206.305 -700
206.306 -699
206.307 -698
206.308 -697
206.309 -696
206.310 -695
206.311 -694
206.312 -693
206.313 -692
206.314 -691
206.315 -690
206.316 -689
206.317 -688
206.318 -687
206.319 -686
206.320 -685
206.321 -684
206.322 -683
206.323 -682
206.324 -681
206.325 -680
206.326 -679
206.327 -678
206.328 -677
206.329 -676
206.330 -675
206.331 -674
206.332 -673
206.333 -672
206.334 -671
206.335 -670
206.336 -669
206.337 -668
206.338 -667
206.339 -666
206.340 -665
206.341 -664
206.342 -663
206.343 -662
206.344 -661
206.345 -660
206.346 -659
206.347 -658
206.348 -657
206.349 -656
206.350 -655
206.351 -654
206.352 -653
206.353 -652
206.354 -651
206.355 -650
206.356 -649
206.357 -648
206.358 -647
206.359 -646
206.360 -645
206.361 -644
206.362 -643
206.363 -642
206.364 -641
206.365 -640
206.366 -639
206.367 -638
206.368 -637
206.369 -636
206.370 -635
206.371 -634
206.372 -633
206.373 -632
206.374 -631
206.375 -630
206.376 -629
206.377 -628
206.378 -627
206.379 -626
206.380 -625
206.381 -624
206.382 -623
206.383 -622
206.384 -621
206.385 -620
206.386 -619
206.387 -618
206.388 -617
206.389 -616
206.390 -615
206.391 -614
206.392 -613
206.393 -612
206.394 -611
206.395 -610
206.396 -609
206.397 -608
206.398 -607
206.399 -606
206.400 -605
206.401 -604
206.402 -603
206.403 -602
206.404 -601
206.405 -600
206.406 -599
206.407 -598
206.408 -597
206.409 -596
206.410 -595
206.411 -594
206.412 -593
206.413 -592
206.414 -591
206.415 -590
206.416 -589
206.417 -588
206.418 -587
206.419 -586
206.420 -585
206.421 -584
206.422 -583
206.423 -582
206.424 -581
206.425 -580
206.426 -579
206.427 -578
206.428 -577
206.429 -576
206.430 -575
206.431 -574
206.432 -573
206.433 -572
206.434 -571
206.435 -570
206.436 -569
206.437 -568
206.438 -567
206.439 -566
206.440 -565
206.441 -564
206.442 -563
206.443 -562
206.444 -561
206.445 -560
206.446 -559
206.447 -558
206.448 -557
206.449 -556
206.450 -555
206.451 -554
206.452 -553
206.453 -552
206.454 -551
206.455 -550
206.456 -549
206.457 -548
206.458 -547
206.459 -546
206.460 -545
206.461 -544
206.462 -543
206.463 -542
206.464 -541
206.465 -540
206.466 -539
206.467 -538
206.468 -537
206.469 -536
206.470 -535
206.471 -534
206.472 -533
206.473 -532
206.474 -531
206.475 -530
206.476 -529
206.477 -528
206.478 -527
206.479 -526
206.480 -525
206.481 -524
206.482 -523
206.483 -522
206.484 -521
206.485 -520
206.486 -519
206.487 -518
206.488 -517
206.489 -516
206.490 -515
206.491 -514
206.492 -513
206.493 -512
206.494 -511
206.495 -510
206.496 -509
206.497 -508
206.498 -507
206.499 -506
206.500 -505
206.501 -504
206.502 -503
206.503 -502
206.504 -501
206.505 -500
206.506 -499
206.507 -498
206.508 -497
206.509 -496
206.510 -495
206.511 -494
206.512 -493
206.513 -492
206.514 -491
206.515 -490
206.516 -489
206.517 -488
206.518 -487
206.519 -486
206.520 -485
206.521 -484
206.522 -483
206.523 -482
206.524 -481
206.525 -480
206.526 -479
206.527 -478
206.528 -477
206.529 -476
206.530 -475
206.531 -474
206.532 -473
206.533 -472
206.534 -471
206.535 -470
206.536 -469
206.537 -468
206.538 -467
206.539 -466
206.540 -465
206.541 -464
206.542 -463
206.543 -462
206.544 -461
206.545 -460
206.546 -459
206.547 -458
206.548 -457
206.549 -456
206.550 -455
206.551 -454
206.552 -453
206.553 -452
206.554 -451
206.555 -450
206.556 -449
206.557 -448
206.558 -447
206.559 -446
206.560 -445
206.561 -444
206.562 -443
206.563 -442
206.564 -441
206.565 -440
206.566 -439
206.567 -438
206.568 -437
206.569 -436
206.570 -435
206.571 -434
206.572 -433
206.573 -432
206.574 -431
206.575 -430
206.576 -429
206.577 -428
206.578 -427
206.579 -426
206.580 -425
206.581 -424
206.582 -423
206.583 -422
206.584 -421
206.585 -420
206.586 -419
206.587 -418
206.588 -417
206.589 -416
206.590 -415
206.591 -414
206.592 -413
206.593 -412
206.594 -411
206.595 -410
206.596 -409
206.597 -408
206.598 -407
206.599 -406
206.600 -405
206.601 -404
206.602 -403
206.603 -402
206.604 -401
206.605 -400
206.606 -399
206.607 -398
206.608 -397
206.609 -396
206.610 -395
206.611 -394
206.612 -393
206.613 -392
206.614 -391
206.615 -390
206.616 -389
206.617 -388
206.618 -387
206.619 -386
206.620 -385
206.621 -384
206.622 -383
206.623 -382
206.624 -381
206.625 -380
206.626 -379
206.627 -378
206.628 -377
206.629 -376
206.630 -375
206.631 -374
206.632 -373
206.633 -372
206.634 -371
206.635 -370
206.636 -369
206.637 -368
206.638 -367
206.639 -366
206.640 -365
206.641 -364
206.642 -363
206.643 -362
206.644 -361
206.645 -360
206.646 -359
206.647 -358
206.648 -357
206.649 -356
206.650 -355
206.651 -354
206.652 -353
206.653 -352
206.654 -351
206.655 -350
206.656 -349
206.657 -348
206.658 -347
206.659 -346
206.660 -345
206.661 -344
206.662 -343
206.663 -342
206.664 -341
206.665 -340
206.666 -339
206.667 -338
206.668 -337
206.669 -336
206.670 -335
206.671 -334
206.672 -333
206.673 -332
206.674 -331
206.675 -330
206.676 -329
206.677 -328
206.678 -327
206.679 -326
206.680 -325
206.681 -324
206.682 -323
206.683 -322
206.684 -321
206.685 -320
206.686 -319
206.687 -318
206.688 -317
206.689 -316
206.690 -315
206.691 -314
206.692 -313
206.693 -312
206.694 -311
206.695 -310
206.696 -309
206.697 -308
206.698 -307
206.699 -306
206.700 -305
206.701 -304
206.702 -303
206.703 -302
206.704 -301
206.705 -300
206.706 -299
206.707 -298
206.708 -297
206.709 -296
206.710 -295
206.711 -294
206.712 -293
206.713 -292
206.714 -291
206.715 -290
206.716 -289
206.717 -288
206.718 -287
206.719 -286
206.720 -285
206.721 -284
206.722 -283
206.723 -282
206.724 -281
206.725 -280
206.726 -279
206.727 -278
206.728 -277
206.729 -276
206.730 -275
206.731 -274
206.732 -273
206.733 -272
206.734 -271
206.735 -270
206.736 -269
206.737 -268
206.738 -267
206.739 -266
206.740 -265
206.741 -264
206.742 -263
206.743 -262
206.744 -261
206.745 -260
206.746 -259
206.747 -258
206.748 -257
206.749 -256
206.750 -255
206.751 -254
206.752 -253
206.753 -252
206.754 -251
206.755 -250
206.756 -249
206.757 -248
206.758 -247
206.759 -246
206.760 -245
206.761 -244
206.762 -243
206.763 -242
206.764 -241
206.765 -240
206.766 -239
206.767 -238
206.768 -237
206.769 -236
206.770 -235
206.771 -234
206.772 -233
206.773 -232
206.774 -231
206.775 -230
206.776 -229
206.777 -228
206.778 -227
206.779 -226
206.780 -225
206.781 -224
206.782 -223
206.783 -222
206.784 -221
206.785 -220
206.786 -219
206.787 -218
206.788 -217
206.789 -216
206.790 -215
206.791 -214
206.792 -213
206.793 -212
206.794 -211
206.795 -210
206.796 -209
206.797 -208
206.798 -207
206.799 -206
206.800 -205
206.801 -204
206.802 -203
206.803 -202
206.804 -201
206.805 -200
206.806 -199
206.807 -198
206.808 -197
206.809 -196
206.810 -195
206.811 -194
206.812 -193
206.813 -192
206.814 -191
206.815 -190
206.816 -189
206.817 -188
206.818 -187
206.819 -186
206.820 -185
206.821 -184
206.822 -183
206.823 -182
206.824 -181
206.825 -180
206.826 -179
206.827 -178
206.828 -177
206.829 -176
206.830 -175
206.831 -174
206.832 -173
206.833 -172
206.834 -171
206.835 -170
206.836 -169
206.837 -168
206.838 -167
206.839 -166
206.840 -165
206.841 -164
206.842 -163
206.843 -162
206.844 -161
206.845 -160
206.846 -159
206.847 -158
206.848 -157
206.849 -156
206.850 -155
206.851 -154
206.852 -153
206.853 -152
206.854 -151
206.855 -150
206.856 -149
206.857 -148
206.858 -147
206.859 -146
206.860 -145
206.861 -144
206.862 -143
206.863 -142
206.864 -141
206.865 -140
206.866 -139
206.867 -138
206.868 -137
206.869 -136
206.870 -135
206.871 -134
206.872 -133
206.873 -132
206.874 -131
206.875 -130
206.876 -129
206.877 -128
206.878 -127
206.879 -126
206.880 -125
206.881 -124
206.882 -123
206.883 -122
206.884 -121
206.885 -120
206.886 -119
206.887 -118
206.888 -117
206.889 -116
206.890 -115
206.891 -114
206.892 -113
206.893 -112
206.894 -111
206.895 -110
206.896 -109
206.897 -108
206.898 -107
206.899 -106
206.900 -105
206.901 -104
206.902 -103
206.903 -102
206.904 -101
206.905 -100
206.906 -99
206.907 -98
206.908 -97
206.909 -96
206.910 -95
206.911 -94
206.912 -93
206.913 -92
206.914 -91
206.915 -90
206.916 -89
206.917 -88
206.918 -87
206.919 -86
206.920 -85
206.921 -84
206.922 -83
206.923 -82
206.924 -81
206.925 -80
206.926 -79
206.927 -78
206.928 -77
206.929 -76
206.930 -75
206.931 -74
206.932 -73
206.933 -72
206.934 -71
206.935 -70
206.936 -69
206.937 -68
206.938 -67
206.939 -66
206.940 -65
206.941 -64
206.942 -63
206.943 -62
206.944 -61
206.945 -60
206.946 -59
206.947 -58
206.948 -57
206.949 -56
206.950 -55
206.951 -54
206.952 -53
206.953 -52
206.954 -51
206.955 -50
206.956 -49
206.957 -48
206.958 -47
206.959 -46
206.960 -45
206.961 -44
206.962 -43
206.963 -42
206.964 -41
206.965 -40
206.966 -39
206.967 -38
206.968 -37
206.969 -36
206.970 -35
206.971 -34
206.972 -33
206.973 -32
206.974 -31
206.975 -30
206.976 -29
206.977 -28
206.978 -27
206.979 -26
206.980 -25
206.981 -24
206.982 -23
206.983 -22
206.984 -21
206.985 -20
206.986 -19
206.987 -18
206.988 -17
206.989 -16
206.990 -15
206.991 -14
206.992 -13
206.993 -12
206.994 -11
206.995 -10
206.996 -9
206.997 -8
206.998 -7
206.999 -6
206.1000 -5
206.1001 -4
206.1002 -3
206.1003 -2
206.1004 -1
206.1005 -0
206.1006 -@edgeset
206.1007 - id capacity
206.1008 -75 377 6906 27
206.1009 -417 515 6905 69
206.1010 -603 249 6904 80
206.1011 -246 344 6903 69
206.1012 -382 827 6902 19
206.1013 -714 879 6901 76
206.1014 -13 481 6900 22
206.1015 -863 754 6899 97
206.1016 -19 530 6898 64
206.1017 -122 597 6897 78
206.1018 -861 579 6896 17
206.1019 -266 888 6895 65
206.1020 -905 105 6894 81
206.1021 -516 501 6893 35
206.1022 -948 430 6892 86
206.1023 -398 535 6891 66
206.1024 -727 258 6890 70
206.1025 -223 322 6889 15
206.1026 -933 864 6888 84
206.1027 -17 604 6887 89
206.1028 -691 520 6886 26
206.1029 -782 843 6885 59
206.1030 -604 457 6884 36
206.1031 -70 492 6883 38
206.1032 -895 195 6882 56
206.1033 -277 968 6881 55
206.1034 -935 550 6880 67
206.1035 -457 306 6879 50
206.1036 -260 946 6878 29
206.1037 -84 636 6877 91
206.1038 -677 665 6876 32
206.1039 -385 234 6875 90
206.1040 -964 972 6874 17
206.1041 -296 819 6873 53
206.1042 -227 18 6872 17
206.1043 -418 879 6871 61
206.1044 -243 167 6870 34
206.1045 -359 212 6869 47
206.1046 -310 374 6868 19
206.1047 -970 590 6867 17
206.1048 -431 416 6866 40
206.1049 -261 730 6865 29
206.1050 -152 643 6864 42
206.1051 -800 358 6863 66
206.1052 -139 557 6862 6
206.1053 -711 276 6861 80
206.1054 -954 863 6860 17
206.1055 -838 279 6859 88
206.1056 -784 22 6858 4
206.1057 -173 767 6857 33
206.1058 -686 116 6856 53
206.1059 -87 870 6855 16
206.1060 -284 753 6854 10
206.1061 -801 599 6853 35
206.1062 -281 259 6852 66
206.1063 -412 635 6851 42
206.1064 -583 291 6850 75
206.1065 -257 833 6849 11
206.1066 -254 710 6848 5
206.1067 -651 799 6847 61
206.1068 -245 370 6846 48
206.1069 -117 60 6845 59
206.1070 -153 757 6844 80
206.1071 -339 690 6843 48
206.1072 -624 232 6842 52
206.1073 -343 671 6841 86
206.1074 -457 639 6840 82
206.1075 -123 62 6839 32
206.1076 -910 442 6838 0
206.1077 -429 124 6837 60
206.1078 -310 888 6836 40
206.1079 -303 796 6835 12
206.1080 -66 319 6834 96
206.1081 -457 963 6833 81
206.1082 -560 651 6832 71
206.1083 -32 39 6831 28
206.1084 -577 502 6830 88
206.1085 -620 323 6829 33
206.1086 -318 400 6828 21
206.1087 -235 196 6827 48
206.1088 -92 277 6826 11
206.1089 -477 164 6825 0
206.1090 -356 149 6824 23
206.1091 -311 98 6823 60
206.1092 -612 435 6822 89
206.1093 -537 394 6821 52
206.1094 -179 552 6820 45
206.1095 -923 121 6819 95
206.1096 -203 731 6818 30
206.1097 -918 362 6817 8
206.1098 -112 111 6816 14
206.1099 -15 770 6815 61
206.1100 -51 628 6814 12
206.1101 -663 711 6813 4
206.1102 -41 368 6812 69
206.1103 -841 73 6811 7
206.1104 -431 497 6810 35
206.1105 -389 655 6809 25
206.1106 -369 218 6808 71
206.1107 -250 939 6807 28
206.1108 -341 528 6806 80
206.1109 -141 493 6805 9
206.1110 -916 76 6804 96
206.1111 -343 345 6803 38
206.1112 -294 623 6802 62
206.1113 -575 717 6801 19
206.1114 -842 102 6800 41
206.1115 -437 535 6799 4
206.1116 -279 435 6798 2
206.1117 -410 478 6797 11
206.1118 -35 709 6796 90
206.1119 -417 132 6795 20
206.1120 -730 576 6794 22
206.1121 -722 766 6793 57
206.1122 -906 422 6792 4
206.1123 -615 788 6791 71
206.1124 -566 369 6790 73
206.1125 -100 21 6789 40
206.1126 -957 901 6788 15
206.1127 -769 209 6787 86
206.1128 -576 708 6786 37
206.1129 -556 975 6785 61
206.1130 -810 651 6784 68
206.1131 -343 524 6783 0
206.1132 -634 330 6782 81
206.1133 -418 984 6781 29
206.1134 -348 328 6780 4
206.1135 -119 246 6779 46
206.1136 -691 289 6778 14
206.1137 -501 492 6777 18
206.1138 -733 758 6776 19
206.1139 -324 930 6775 1
206.1140 -126 679 6774 74
206.1141 -194 192 6773 46
206.1142 -345 524 6772 70
206.1143 -656 242 6771 21
206.1144 -82 582 6770 7
206.1145 -956 322 6769 22
206.1146 -797 955 6768 42
206.1147 -734 994 6767 19
206.1148 -827 173 6766 76
206.1149 -251 273 6765 40
206.1150 -487 279 6764 19
206.1151 -667 757 6763 93
206.1152 -282 492 6762 84
206.1153 -659 145 6761 68
206.1154 -260 840 6760 57
206.1155 -366 801 6759 12
206.1156 -960 236 6758 15
206.1157 -821 422 6757 6
206.1158 -900 358 6756 90
206.1159 -993 211 6755 57
206.1160 -521 265 6754 76
206.1161 -265 83 6753 81
206.1162 -346 159 6752 38
206.1163 -304 114 6751 62
206.1164 -39 448 6750 39
206.1165 -565 965 6749 89
206.1166 -813 96 6748 40
206.1167 -64 155 6747 13
206.1168 -147 330 6746 92
206.1169 -945 812 6745 90
206.1170 -182 943 6744 47
206.1171 -923 434 6743 25
206.1172 -44 763 6742 91
206.1173 -666 222 6741 4
206.1174 -482 505 6740 26
206.1175 -869 487 6739 47
206.1176 -941 266 6738 75
206.1177 -825 217 6737 74
206.1178 -517 14 6736 91
206.1179 -868 435 6735 20
206.1180 -509 214 6734 76
206.1181 -671 338 6733 25
206.1182 -540 876 6732 87
206.1183 -717 776 6731 37
206.1184 -17 791 6730 18
206.1185 -221 721 6729 61
206.1186 -49 2 6728 92
206.1187 -202 831 6727 11
206.1188 -579 716 6726 30
206.1189 -220 437 6725 64
206.1190 -876 505 6724 35
206.1191 -462 379 6723 83
206.1192 -99 500 6722 13
206.1193 -984 195 6721 82
206.1194 -70 569 6720 69
206.1195 -719 685 6719 79
206.1196 -170 812 6718 17
206.1197 -115 806 6717 84
206.1198 -278 660 6716 62
206.1199 -932 288 6715 35
206.1200 -125 521 6714 34
206.1201 -879 707 6713 41
206.1202 -304 308 6712 36
206.1203 -626 123 6711 11
206.1204 -883 903 6710 91
206.1205 -873 624 6709 35
206.1206 -5 325 6708 54
206.1207 -146 223 6707 5
206.1208 -371 264 6706 83
206.1209 -767 14 6705 34
206.1210 -814 929 6704 80
206.1211 -399 52 6703 24
206.1212 -184 246 6702 57
206.1213 -219 201 6701 67
206.1214 -279 563 6700 74
206.1215 -298 801 6699 0
206.1216 -102 494 6698 86
206.1217 -959 217 6697 85
206.1218 -249 491 6696 77
206.1219 -84 538 6695 60
206.1220 -877 560 6694 95
206.1221 -805 671 6693 41
206.1222 -45 896 6692 21
206.1223 -637 935 6691 96
206.1224 -761 733 6690 94
206.1225 -307 142 6689 98
206.1226 -276 7 6688 19
206.1227 -725 85 6687 14
206.1228 -953 169 6686 70
206.1229 -977 650 6685 16
206.1230 -889 538 6684 20
206.1231 -775 200 6683 7
206.1232 -960 248 6682 75
206.1233 -202 24 6681 40
206.1234 -591 959 6680 87
206.1235 -134 785 6679 45
206.1236 -922 51 6678 3
206.1237 -915 433 6677 55
206.1238 -519 545 6676 77
206.1239 -112 957 6675 97
206.1240 -337 134 6674 8
206.1241 -952 312 6673 11
206.1242 -224 351 6672 81
206.1243 -64 532 6671 75
206.1244 -174 421 6670 61
206.1245 -733 422 6669 45
206.1246 -618 479 6668 21
206.1247 -888 778 6667 0
206.1248 -588 797 6666 39
206.1249 -822 886 6665 40
206.1250 -822 974 6664 77
206.1251 -960 299 6663 38
206.1252 -819 55 6662 72
206.1253 -110 147 6661 15
206.1254 -998 154 6660 89
206.1255 -943 244 6659 44
206.1256 -700 204 6658 11
206.1257 -981 610 6657 73
206.1258 -910 989 6656 29
206.1259 -912 631 6655 76
206.1260 -675 389 6654 0
206.1261 -243 657 6653 86
206.1262 -908 567 6652 14
206.1263 -993 268 6651 70
206.1264 -909 450 6650 11
206.1265 -39 324 6649 5
206.1266 -594 385 6648 24
206.1267 -620 430 6647 71
206.1268 -358 533 6646 7
206.1269 -242 765 6645 99
206.1270 -731 138 6644 23
206.1271 -89 720 6643 43
206.1272 -299 433 6642 33
206.1273 -818 596 6641 91
206.1274 -125 56 6640 8
206.1275 -939 813 6639 86
206.1276 -954 523 6638 44
206.1277 -896 647 6637 97
206.1278 -768 73 6636 26
206.1279 -627 760 6635 11
206.1280 -417 805 6634 51
206.1281 -287 96 6633 64
206.1282 -836 420 6632 79
206.1283 -539 831 6631 48
206.1284 -243 213 6630 69
206.1285 -290 423 6629 18
206.1286 -875 472 6628 98
206.1287 -574 710 6627 5
206.1288 -312 146 6626 12
206.1289 -955 605 6625 14
206.1290 -708 868 6624 20
206.1291 -676 850 6623 13
206.1292 -588 310 6622 45
206.1293 -617 787 6621 29
206.1294 -790 507 6620 29
206.1295 -951 201 6619 95
206.1296 -762 926 6618 41
206.1297 -563 930 6617 30
206.1298 -541 987 6616 26
206.1299 -736 930 6615 35
206.1300 -18 78 6614 24
206.1301 -540 680 6613 3
206.1302 -522 153 6612 8
206.1303 -280 0 6611 97
206.1304 -306 343 6610 82
206.1305 -274 538 6609 83
206.1306 -996 114 6608 18
206.1307 -942 38 6607 19
206.1308 -56 904 6606 2
206.1309 -851 111 6605 80
206.1310 -398 213 6604 71
206.1311 -526 944 6603 47
206.1312 -153 116 6602 1
206.1313 -657 143 6601 24
206.1314 -805 988 6600 97
206.1315 -423 650 6599 3
206.1316 -75 990 6598 27
206.1317 -133 175 6597 5
206.1318 -793 218 6596 88
206.1319 -897 86 6595 20
206.1320 -268 240 6594 45
206.1321 -828 459 6593 87
206.1322 -972 776 6592 37
206.1323 -155 266 6591 49
206.1324 -338 943 6590 85
206.1325 -660 753 6589 38
206.1326 -814 223 6588 34
206.1327 -957 169 6587 94
206.1328 -131 680 6586 34
206.1329 -845 751 6585 89
206.1330 -781 580 6584 62
206.1331 -683 498 6583 44
206.1332 -509 877 6582 85
206.1333 -323 644 6581 81
206.1334 -189 470 6580 81
206.1335 -529 33 6579 67
206.1336 -54 406 6578 84
206.1337 -488 601 6577 85
206.1338 -928 444 6576 82
206.1339 -171 267 6575 28
206.1340 -81 188 6574 6
206.1341 -621 585 6573 9
206.1342 -233 37 6572 17
206.1343 -173 0 6571 18
206.1344 -437 138 6570 13
206.1345 -627 832 6569 66
206.1346 -804 989 6568 47
206.1347 -157 30 6567 56
206.1348 -176 539 6566 56
206.1349 -79 222 6565 75
206.1350 -602 966 6564 8
206.1351 -547 923 6563 46
206.1352 -36 988 6562 38
206.1353 -861 51 6561 5
206.1354 -306 473 6560 73
206.1355 -842 185 6559 81
206.1356 -959 908 6558 82
206.1357 -490 5 6557 64
206.1358 -317 802 6556 98
206.1359 -255 668 6555 9
206.1360 -42 628 6554 47
206.1361 -935 72 6553 5
206.1362 -936 328 6552 51
206.1363 -578 323 6551 17
206.1364 -287 925 6550 55
206.1365 -277 987 6549 46
206.1366 -902 176 6548 88
206.1367 -203 665 6547 46
206.1368 -134 883 6546 17
206.1369 -39 621 6545 6
206.1370 -556 420 6544 21
206.1371 -743 544 6543 10
206.1372 -4 335 6542 99
206.1373 -398 619 6541 35
206.1374 -937 91 6540 29
206.1375 -811 580 6539 1
206.1376 -510 414 6538 37
206.1377 -782 295 6537 69
206.1378 -261 111 6536 6
206.1379 -200 848 6535 9
206.1380 -875 105 6534 48
206.1381 -209 107 6533 81
206.1382 -715 641 6532 73
206.1383 -528 67 6531 60
206.1384 -511 280 6530 46
206.1385 -165 635 6529 12
206.1386 -119 675 6528 30
206.1387 -183 630 6527 72
206.1388 -262 973 6526 52
206.1389 -743 612 6525 6
206.1390 -998 669 6524 32
206.1391 -466 74 6523 66
206.1392 -574 132 6522 49
206.1393 -786 145 6521 18
206.1394 -645 334 6520 1
206.1395 -959 824 6519 34
206.1396 -44 573 6518 4
206.1397 -657 206 6517 93
206.1398 -361 459 6516 92
206.1399 -942 736 6515 51
206.1400 -595 658 6514 74
206.1401 -941 172 6513 53
206.1402 -986 305 6512 89
206.1403 -810 170 6511 78
206.1404 -510 671 6510 14
206.1405 -250 299 6509 68
206.1406 -367 109 6508 91
206.1407 -746 15 6507 38
206.1408 -723 401 6506 29
206.1409 -77 774 6505 41
206.1410 -485 212 6504 34
206.1411 -866 640 6503 65
206.1412 -135 103 6502 95
206.1413 -499 647 6501 17
206.1414 -371 454 6500 30
206.1415 -190 771 6499 25
206.1416 -93 526 6498 88
206.1417 -614 92 6497 62
206.1418 -626 876 6496 2
206.1419 -562 71 6495 64
206.1420 -571 693 6494 59
206.1421 -537 698 6493 61
206.1422 -455 779 6492 73
206.1423 -193 875 6491 63
206.1424 -682 40 6490 12
206.1425 -245 376 6489 18
206.1426 -434 262 6488 9
206.1427 -215 597 6487 47
206.1428 -804 376 6486 98
206.1429 -378 54 6485 6
206.1430 -995 973 6484 99
206.1431 -919 886 6483 3
206.1432 -903 95 6482 8
206.1433 -834 508 6481 26
206.1434 -664 946 6480 51
206.1435 -113 84 6479 43
206.1436 -664 618 6478 81
206.1437 -221 490 6477 21
206.1438 -322 924 6476 41
206.1439 -80 72 6475 42
206.1440 -86 956 6474 38
206.1441 -791 952 6473 7
206.1442 -587 820 6472 1
206.1443 -562 750 6471 6
206.1444 -862 74 6470 16
206.1445 -465 626 6469 55
206.1446 -128 592 6468 44
206.1447 -565 806 6467 44
206.1448 -852 985 6466 89
206.1449 -116 42 6465 24
206.1450 -4 307 6464 99
206.1451 -132 60 6463 29
206.1452 -69 946 6462 20
206.1453 -676 899 6461 2
206.1454 -448 619 6460 70
206.1455 -33 101 6459 39
206.1456 -786 6 6458 33
206.1457 -821 544 6457 56
206.1458 -942 656 6456 71
206.1459 -735 246 6455 73
206.1460 -246 699 6454 11
206.1461 -114 90 6453 87
206.1462 -46 179 6452 6
206.1463 -279 324 6451 39
206.1464 -518 303 6450 22
206.1465 -94 58 6449 41
206.1466 -461 774 6448 24
206.1467 -887 849 6447 96
206.1468 -410 976 6446 87
206.1469 -546 624 6445 20
206.1470 -609 239 6444 48
206.1471 -911 810 6443 13
206.1472 -855 668 6442 6
206.1473 -20 165 6441 76
206.1474 -244 812 6440 76
206.1475 -283 168 6439 42
206.1476 -924 281 6438 63
206.1477 -872 86 6437 57
206.1478 -352 671 6436 47
206.1479 -384 718 6435 86
206.1480 -429 355 6434 93
206.1481 -141 65 6433 69
206.1482 -502 300 6432 5
206.1483 -352 5 6431 83
206.1484 -644 338 6430 77
206.1485 -886 790 6429 96
206.1486 -195 59 6428 35
206.1487 -415 96 6427 5
206.1488 -952 614 6426 51
206.1489 -363 925 6425 96
206.1490 -290 239 6424 95
206.1491 -765 642 6423 28
206.1492 -294 221 6422 63
206.1493 -667 58 6421 15
206.1494 -547 814 6420 70
206.1495 -731 601 6419 75
206.1496 -962 307 6418 69
206.1497 -481 532 6417 78
206.1498 -689 551 6416 46
206.1499 -685 14 6415 58
206.1500 -597 666 6414 7
206.1501 -420 649 6413 52
206.1502 -163 488 6412 47
206.1503 -243 441 6411 62
206.1504 -213 950 6410 11
206.1505 -294 66 6409 81
206.1506 -775 911 6408 76
206.1507 -980 317 6407 48
206.1508 -536 873 6406 79
206.1509 -347 516 6405 0
206.1510 -17 548 6404 8
206.1511 -160 54 6403 17
206.1512 -46 842 6402 25
206.1513 -491 508 6401 91
206.1514 -884 302 6400 3
206.1515 -154 48 6399 91
206.1516 -593 287 6398 51
206.1517 -444 688 6397 79
206.1518 -356 789 6396 44
206.1519 -968 915 6395 18
206.1520 -493 911 6394 33
206.1521 -212 920 6393 85
206.1522 -333 337 6392 11
206.1523 -205 889 6391 55
206.1524 -254 112 6390 60
206.1525 -760 398 6389 72
206.1526 -598 725 6388 56
206.1527 -899 350 6387 14
206.1528 -874 254 6386 8
206.1529 -4 858 6385 38
206.1530 -990 474 6384 47
206.1531 -583 742 6383 28
206.1532 -447 558 6382 87
206.1533 -777 947 6381 12
206.1534 -713 878 6380 95
206.1535 -673 168 6379 49
206.1536 -375 411 6378 16
206.1537 -95 61 6377 69
206.1538 -396 699 6376 2
206.1539 -384 913 6375 87
206.1540 -731 193 6374 1
206.1541 -183 403 6373 40
206.1542 -611 750 6372 13
206.1543 -69 177 6371 67
206.1544 -710 456 6370 6
206.1545 -756 332 6369 4
206.1546 -350 461 6368 29
206.1547 -362 675 6367 27
206.1548 -785 154 6366 69
206.1549 -720 856 6365 1
206.1550 -790 605 6364 65
206.1551 -652 272 6363 54
206.1552 -572 464 6362 57
206.1553 -720 607 6361 54
206.1554 -124 22 6360 35
206.1555 -870 742 6359 95
206.1556 -786 17 6358 40
206.1557 -520 580 6357 98
206.1558 -297 686 6356 57
206.1559 -251 359 6355 6
206.1560 -333 104 6354 93
206.1561 -807 975 6353 13
206.1562 -857 30 6352 8
206.1563 -584 182 6351 85
206.1564 -280 405 6350 59
206.1565 -724 547 6349 25
206.1566 -437 418 6348 8
206.1567 -893 410 6347 26
206.1568 -327 512 6346 22
206.1569 -254 133 6345 4
206.1570 -129 793 6344 91
206.1571 -945 56 6343 52
206.1572 -847 227 6342 94
206.1573 -777 256 6341 27
206.1574 -857 342 6340 30
206.1575 -129 169 6339 55
206.1576 -7 817 6338 28
206.1577 -897 43 6337 54
206.1578 -379 176 6336 56
206.1579 -339 128 6335 7
206.1580 -736 392 6334 12
206.1581 -828 576 6333 18
206.1582 -971 676 6332 9
206.1583 -913 969 6331 7
206.1584 -172 749 6330 91
206.1585 -352 267 6329 72
206.1586 -774 744 6328 12
206.1587 -867 977 6327 11
206.1588 -47 493 6326 51
206.1589 -736 947 6325 3
206.1590 -815 941 6324 60
206.1591 -899 85 6323 90
206.1592 -706 27 6322 85
206.1593 -220 150 6321 5
206.1594 -481 191 6320 74
206.1595 -522 607 6319 82
206.1596 -767 11 6318 57
206.1597 -483 592 6317 90
206.1598 -545 478 6316 81
206.1599 -5 436 6315 31
206.1600 -856 695 6314 92
206.1601 -58 50 6313 91
206.1602 -876 798 6312 19
206.1603 -959 317 6311 48
206.1604 -583 920 6310 73
206.1605 -595 242 6309 95
206.1606 -419 671 6308 75
206.1607 -113 86 6307 28
206.1608 -42 508 6306 93
206.1609 -740 390 6305 54
206.1610 -644 4 6304 14
206.1611 -251 722 6303 79
206.1612 -481 706 6302 18
206.1613 -396 747 6301 91
206.1614 -677 779 6300 37
206.1615 -571 203 6299 98
206.1616 -584 471 6298 17
206.1617 -578 345 6297 30
206.1618 -118 397 6296 7
206.1619 -386 391 6295 30
206.1620 -281 350 6294 9
206.1621 -16 617 6293 39
206.1622 -958 263 6292 77
206.1623 -968 541 6291 8
206.1624 -575 387 6290 71
206.1625 -732 811 6289 10
206.1626 -125 870 6288 98
206.1627 -948 235 6287 0
206.1628 -5 768 6286 45
206.1629 -40 205 6285 73
206.1630 -733 703 6284 10
206.1631 -353 622 6283 26
206.1632 -722 685 6282 5
206.1633 -154 365 6281 99
206.1634 -576 612 6280 39
206.1635 -940 120 6279 84
206.1636 -635 979 6278 60
206.1637 -466 546 6277 17
206.1638 -563 727 6276 94
206.1639 -501 627 6275 96
206.1640 -80 838 6274 30
206.1641 -937 208 6273 38
206.1642 -319 67 6272 63
206.1643 -753 597 6271 56
206.1644 -492 549 6270 57
206.1645 -140 235 6269 63
206.1646 -433 430 6268 30
206.1647 -818 233 6267 16
206.1648 -100 977 6266 90
206.1649 -789 658 6265 6
206.1650 -630 925 6264 42
206.1651 -141 749 6263 14
206.1652 -469 62 6262 61
206.1653 -47 990 6261 56
206.1654 -313 941 6260 26
206.1655 -805 331 6259 35
206.1656 -196 135 6258 70
206.1657 -256 266 6257 61
206.1658 -318 841 6256 71
206.1659 -732 640 6255 31
206.1660 -176 277 6254 15
206.1661 -687 526 6253 48
206.1662 -72 50 6252 67
206.1663 -48 305 6251 42
206.1664 -610 909 6250 73
206.1665 -196 644 6249 50
206.1666 -868 92 6248 60
206.1667 -424 895 6247 93
206.1668 -201 407 6246 93
206.1669 -362 152 6245 58
206.1670 -750 669 6244 55
206.1671 -475 817 6243 48
206.1672 -745 249 6242 61
206.1673 -395 688 6241 2
206.1674 -264 225 6240 43
206.1675 -551 898 6239 41
206.1676 -197 669 6238 32
206.1677 -487 2 6237 44
206.1678 -255 351 6236 22
206.1679 -483 29 6235 83
206.1680 -851 67 6234 61
206.1681 -568 874 6233 27
206.1682 -560 591 6232 73
206.1683 -463 584 6231 34
206.1684 -326 25 6230 13
206.1685 -228 86 6229 71
206.1686 -667 883 6228 35
206.1687 -651 220 6227 70
206.1688 -321 385 6226 23
206.1689 -961 226 6225 77
206.1690 -193 336 6224 63
206.1691 -282 544 6223 28
206.1692 -7 380 6222 0
206.1693 -559 219 6221 9
206.1694 -939 417 6220 13
206.1695 -202 358 6219 9
206.1696 -663 645 6218 56
206.1697 -834 477 6217 1
206.1698 -158 459 6216 32
206.1699 -889 140 6215 36
206.1700 -792 349 6214 76
206.1701 -164 274 6213 91
206.1702 -161 911 6212 27
206.1703 -801 960 6211 44
206.1704 -59 38 6210 61
206.1705 -712 536 6209 73
206.1706 -167 545 6208 53
206.1707 -18 686 6207 82
206.1708 -318 969 6206 67
206.1709 -791 591 6205 26
206.1710 -74 857 6204 9
206.1711 -362 635 6203 62
206.1712 -951 827 6202 0
206.1713 -921 828 6201 36
206.1714 -502 882 6200 74
206.1715 -990 198 6199 34
206.1716 -858 709 6198 54
206.1717 -717 153 6197 14
206.1718 -377 406 6196 69
206.1719 -734 172 6195 52
206.1720 -222 469 6194 71
206.1721 -808 625 6193 71
206.1722 -998 642 6192 41
206.1723 -945 618 6191 3
206.1724 -684 394 6190 41
206.1725 -489 801 6189 51
206.1726 -556 396 6188 13
206.1727 -747 449 6187 14
206.1728 -233 172 6186 34
206.1729 -703 810 6185 64
206.1730 -843 4 6184 51
206.1731 -982 300 6183 41
206.1732 -24 381 6182 80
206.1733 -223 612 6181 5
206.1734 -593 906 6180 26
206.1735 -405 380 6179 19
206.1736 -946 990 6178 93
206.1737 -276 800 6177 80
206.1738 -362 697 6176 51
206.1739 -805 131 6175 53
206.1740 -704 97 6174 85
206.1741 -919 604 6173 86
206.1742 -768 757 6172 95
206.1743 -705 790 6171 80
206.1744 -525 66 6170 63
206.1745 -389 262 6169 18
206.1746 -190 123 6168 45
206.1747 -103 295 6167 67
206.1748 -566 983 6166 91
206.1749 -33 670 6165 55
206.1750 -493 998 6164 10
206.1751 -847 902 6163 78
206.1752 -966 157 6162 15
206.1753 -724 170 6161 6
206.1754 -804 441 6160 17
206.1755 -138 729 6159 13
206.1756 -828 788 6158 19
206.1757 -312 756 6157 8
206.1758 -312 356 6156 53
206.1759 -671 455 6155 53
206.1760 -96 316 6154 53
206.1761 -744 633 6153 64
206.1762 -987 87 6152 88
206.1763 -728 882 6151 24
206.1764 -712 43 6150 91
206.1765 -941 936 6149 66
206.1766 -31 112 6148 30
206.1767 -399 550 6147 51
206.1768 -900 3 6146 99
206.1769 -139 993 6145 64
206.1770 -682 893 6144 57
206.1771 -546 765 6143 35
206.1772 -204 638 6142 75
206.1773 -839 322 6141 25
206.1774 -106 253 6140 1
206.1775 -824 356 6139 77
206.1776 -562 793 6138 90
206.1777 -546 516 6137 63
206.1778 -9 359 6136 49
206.1779 -100 65 6135 76
206.1780 -127 223 6134 45
206.1781 -126 595 6133 13
206.1782 -316 497 6132 34
206.1783 -69 242 6131 36
206.1784 -896 246 6130 73
206.1785 -562 860 6129 28
206.1786 -277 277 6128 26
206.1787 -156 132 6127 1
206.1788 -293 737 6126 53
206.1789 -842 305 6125 90
206.1790 -628 319 6124 97
206.1791 -97 795 6123 0
206.1792 -255 976 6122 81
206.1793 -996 632 6121 24
206.1794 -385 450 6120 17
206.1795 -582 20 6119 33
206.1796 -145 245 6118 28
206.1797 -395 478 6117 12
206.1798 -432 626 6116 86
206.1799 -985 937 6115 45
206.1800 -524 971 6114 21
206.1801 -819 190 6113 53
206.1802 -343 563 6112 84
206.1803 -182 73 6111 25
206.1804 -429 839 6110 61
206.1805 -774 48 6109 80
206.1806 -767 164 6108 43
206.1807 -852 257 6107 75
206.1808 -689 411 6106 96
206.1809 -966 237 6105 44
206.1810 -780 683 6104 46
206.1811 -626 688 6103 70
206.1812 -490 583 6102 47
206.1813 -234 647 6101 16
206.1814 -791 807 6100 75
206.1815 -883 365 6099 65
206.1816 -906 687 6098 0
206.1817 -845 787 6097 91
206.1818 -174 515 6096 16
206.1819 -554 986 6095 72
206.1820 -994 755 6094 18
206.1821 -104 229 6093 15
206.1822 -935 315 6092 13
206.1823 -839 407 6091 25
206.1824 -442 99 6090 44
206.1825 -678 646 6089 90
206.1826 -899 92 6088 97
206.1827 -272 752 6087 6
206.1828 -528 439 6086 67
206.1829 -231 537 6085 62
206.1830 -525 31 6084 55
206.1831 -914 18 6083 88
206.1832 -908 880 6082 16
206.1833 -307 812 6081 9
206.1834 -452 536 6080 39
206.1835 -553 929 6079 76
206.1836 -340 916 6078 77
206.1837 -312 389 6077 62
206.1838 -902 51 6076 74
206.1839 -506 60 6075 29
206.1840 -13 669 6074 70
206.1841 -137 720 6073 61
206.1842 -67 72 6072 0
206.1843 -276 698 6071 60
206.1844 -606 633 6070 85
206.1845 -13 985 6069 89
206.1846 -526 151 6068 21
206.1847 -337 882 6067 2
206.1848 -991 447 6066 41
206.1849 -390 590 6065 39
206.1850 -948 95 6064 49
206.1851 -648 604 6063 87
206.1852 -374 405 6062 7
206.1853 -64 744 6061 79
206.1854 -648 956 6060 66
206.1855 -833 685 6059 59
206.1856 -269 185 6058 48
206.1857 -434 617 6057 18
206.1858 -857 13 6056 34
206.1859 -494 903 6055 60
206.1860 -490 617 6054 44
206.1861 -198 805 6053 30
206.1862 -661 278 6052 27
206.1863 -787 121 6051 30
206.1864 -271 76 6050 41
206.1865 -500 105 6049 81
206.1866 -567 298 6048 56
206.1867 -604 842 6047 83
206.1868 -110 746 6046 57
206.1869 -285 157 6045 36
206.1870 -812 141 6044 0
206.1871 -526 26 6043 29
206.1872 -156 965 6042 53
206.1873 -44 893 6041 87
206.1874 -971 600 6040 51
206.1875 -807 251 6039 77
206.1876 -456 729 6038 93
206.1877 -95 257 6037 96
206.1878 -588 213 6036 49
206.1879 -15 359 6035 82
206.1880 -115 712 6034 47
206.1881 -61 753 6033 28
206.1882 -71 664 6032 36
206.1883 -292 356 6031 11
206.1884 -349 745 6030 7
206.1885 -521 837 6029 16
206.1886 -472 970 6028 35
206.1887 -43 469 6027 36
206.1888 -854 667 6026 50
206.1889 -646 352 6025 57
206.1890 -958 186 6024 90
206.1891 -89 915 6023 5
206.1892 -307 257 6022 98
206.1893 -611 38 6021 77
206.1894 -907 910 6020 94
206.1895 -867 811 6019 82
206.1896 -500 991 6018 4
206.1897 -802 854 6017 42
206.1898 -314 933 6016 18
206.1899 -166 672 6015 20
206.1900 -271 845 6014 68
206.1901 -657 65 6013 86
206.1902 -219 209 6012 78
206.1903 -127 836 6011 69
206.1904 -99 114 6010 70
206.1905 -820 778 6009 3
206.1906 -136 621 6008 36
206.1907 -920 238 6007 69
206.1908 -260 981 6006 48
206.1909 -827 519 6005 14
206.1910 -779 819 6004 89
206.1911 -855 87 6003 61
206.1912 -373 85 6002 43
206.1913 -721 991 6001 9
206.1914 -336 664 6000 2
206.1915 -157 671 5999 27
206.1916 -382 669 5998 68
206.1917 -256 210 5997 21
206.1918 -462 338 5996 66
206.1919 -699 253 5995 43
206.1920 -731 281 5994 4
206.1921 -1 174 5993 92
206.1922 -94 346 5992 48
206.1923 -326 63 5991 65
206.1924 -993 749 5990 38
206.1925 -2 595 5989 17
206.1926 -459 467 5988 77
206.1927 -871 555 5987 12
206.1928 -85 226 5986 79
206.1929 -971 385 5985 76
206.1930 -106 123 5984 96
206.1931 -828 441 5983 73
206.1932 -283 831 5982 90
206.1933 -313 265 5981 76
206.1934 -153 206 5980 33
206.1935 -128 403 5979 99
206.1936 -911 649 5978 54
206.1937 -329 331 5977 58
206.1938 -840 31 5976 78
206.1939 -262 794 5975 11
206.1940 -682 237 5974 86
206.1941 -609 823 5973 27
206.1942 -565 139 5972 54
206.1943 -58 434 5971 96
206.1944 -803 342 5970 15
206.1945 -754 447 5969 2
206.1946 -317 955 5968 21
206.1947 -300 801 5967 58
206.1948 -236 672 5966 48
206.1949 -557 248 5965 57
206.1950 -414 586 5964 57
206.1951 -684 733 5963 7
206.1952 -704 575 5962 4
206.1953 -91 809 5961 50
206.1954 -894 133 5960 25
206.1955 -492 809 5959 4
206.1956 -153 634 5958 43
206.1957 -129 93 5957 1
206.1958 -424 909 5956 6
206.1959 -661 998 5955 67
206.1960 -853 506 5954 14
206.1961 -157 29 5953 73
206.1962 -765 536 5952 97
206.1963 -676 251 5951 61
206.1964 -324 207 5950 19
206.1965 -175 611 5949 40
206.1966 -540 419 5948 33
206.1967 -184 953 5947 2
206.1968 -911 384 5946 70
206.1969 -492 536 5945 76
206.1970 -477 412 5944 80
206.1971 -492 750 5943 69
206.1972 -285 367 5942 39
206.1973 -43 415 5941 8
206.1974 -595 795 5940 35
206.1975 -192 62 5939 14
206.1976 -465 315 5938 63
206.1977 -569 319 5937 35
206.1978 -847 941 5936 27
206.1979 -123 955 5935 41
206.1980 -662 111 5934 1
206.1981 -383 305 5933 98
206.1982 -951 301 5932 20
206.1983 -619 737 5931 24
206.1984 -733 202 5930 44
206.1985 -746 513 5929 40
206.1986 -995 279 5928 72
206.1987 -378 82 5927 89
206.1988 -986 854 5926 72
206.1989 -844 403 5925 72
206.1990 -806 30 5924 46
206.1991 -3 776 5923 27
206.1992 -563 965 5922 43
206.1993 -534 793 5921 33
206.1994 -689 44 5920 88
206.1995 -234 677 5919 98
206.1996 -196 829 5918 75
206.1997 -228 175 5917 61
206.1998 -450 997 5916 39
206.1999 -373 262 5915 14
206.2000 -253 182 5914 3
206.2001 -810 847 5913 80
206.2002 -172 99 5912 43
206.2003 -748 445 5911 2
206.2004 -367 899 5910 84
206.2005 -848 236 5909 45
206.2006 -654 132 5908 3
206.2007 -177 225 5907 96
206.2008 -735 250 5906 77
206.2009 -80 103 5905 7
206.2010 -334 235 5904 11
206.2011 -748 363 5903 44
206.2012 -653 410 5902 63
206.2013 -546 183 5901 42
206.2014 -662 390 5900 38
206.2015 -103 417 5899 51
206.2016 -907 70 5898 19
206.2017 -975 189 5897 47
206.2018 -146 701 5896 44
206.2019 -868 957 5895 65
206.2020 -871 676 5894 74
206.2021 -952 804 5893 58
206.2022 -227 214 5892 9
206.2023 -792 41 5891 10
206.2024 -972 862 5890 88
206.2025 -347 325 5889 55
206.2026 -880 716 5888 19
206.2027 -487 34 5887 93
206.2028 -743 786 5886 82
206.2029 -280 909 5885 27
206.2030 -872 159 5884 99
206.2031 -590 492 5883 91
206.2032 -172 987 5882 72
206.2033 -179 223 5881 43
206.2034 -537 324 5880 81
206.2035 -608 363 5879 62
206.2036 -681 264 5878 46
206.2037 -248 101 5877 39
206.2038 -877 552 5876 74
206.2039 -750 280 5875 46
206.2040 -667 77 5874 40
206.2041 -505 193 5873 28
206.2042 -763 290 5872 41
206.2043 -899 614 5871 99
206.2044 -961 194 5870 64
206.2045 -98 158 5869 92
206.2046 -162 73 5868 92
206.2047 -549 648 5867 43
206.2048 -271 280 5866 37
206.2049 -203 54 5865 12
206.2050 -883 126 5864 8
206.2051 -902 864 5863 16
206.2052 -676 424 5862 74
206.2053 -420 351 5861 86
206.2054 -35 712 5860 93
206.2055 -85 2 5859 86
206.2056 -424 493 5858 93
206.2057 -368 62 5857 61
206.2058 -226 244 5856 27
206.2059 -928 42 5855 6
206.2060 -261 921 5854 31
206.2061 -440 420 5853 98
206.2062 -72 877 5852 22
206.2063 -639 925 5851 25
206.2064 -710 75 5850 38
206.2065 -508 927 5849 95
206.2066 -431 322 5848 66
206.2067 -817 334 5847 5
206.2068 -202 210 5846 14
206.2069 -121 748 5845 29
206.2070 -501 338 5844 66
206.2071 -542 754 5843 82
206.2072 -952 970 5842 36
206.2073 -849 871 5841 43
206.2074 -148 434 5840 92
206.2075 -604 289 5839 20
206.2076 -988 603 5838 7
206.2077 -123 914 5837 61
206.2078 -462 844 5836 61
206.2079 -409 631 5835 8
206.2080 -584 845 5834 61
206.2081 -783 453 5833 95
206.2082 -99 935 5832 58
206.2083 -436 504 5831 10
206.2084 -144 726 5830 70
206.2085 -686 124 5829 54
206.2086 -689 464 5828 61
206.2087 -70 998 5827 86
206.2088 -212 534 5826 66
206.2089 -786 461 5825 5
206.2090 -392 660 5824 82
206.2091 -517 369 5823 80
206.2092 -431 487 5822 68
206.2093 -777 401 5821 66
206.2094 -602 157 5820 29
206.2095 -659 927 5819 45
206.2096 -465 751 5818 99
206.2097 -464 203 5817 61
206.2098 -72 608 5816 85
206.2099 -800 227 5815 42
206.2100 -291 23 5814 39
206.2101 -881 117 5813 87
206.2102 -85 21 5812 8
206.2103 -243 370 5811 65
206.2104 -230 833 5810 17
206.2105 -175 461 5809 94
206.2106 -548 378 5808 19
206.2107 -594 760 5807 0
206.2108 -380 432 5806 39
206.2109 -204 31 5805 27
206.2110 -905 519 5804 50
206.2111 -96 787 5803 40
206.2112 -650 432 5802 79
206.2113 -536 479 5801 84
206.2114 -372 231 5800 1
206.2115 -82 748 5799 5
206.2116 -618 192 5798 62
206.2117 -328 609 5797 95
206.2118 -400 120 5796 21
206.2119 -512 762 5795 17
206.2120 -731 99 5794 29
206.2121 -354 613 5793 80
206.2122 -953 954 5792 44
206.2123 -247 829 5791 11
206.2124 -482 958 5790 16
206.2125 -555 427 5789 28
206.2126 -583 673 5788 46
206.2127 -489 740 5787 29
206.2128 -357 37 5786 92
206.2129 -662 877 5785 88
206.2130 -486 489 5784 78
206.2131 -659 364 5783 37
206.2132 -124 331 5782 40
206.2133 -871 949 5781 70
206.2134 -530 874 5780 76
206.2135 -754 826 5779 92
206.2136 -933 173 5778 97
206.2137 -702 362 5777 9
206.2138 -160 40 5776 13
206.2139 -387 107 5775 69
206.2140 -124 403 5774 17
206.2141 -33 975 5773 82
206.2142 -381 695 5772 53
206.2143 -74 940 5771 25
206.2144 -48 838 5770 34
206.2145 -652 953 5769 77
206.2146 -810 879 5768 82
206.2147 -322 961 5767 23
206.2148 -932 436 5766 54
206.2149 -704 519 5765 77
206.2150 -427 348 5764 26
206.2151 -279 293 5763 9
206.2152 -755 280 5762 65
206.2153 -101 913 5761 30
206.2154 -884 564 5760 2
206.2155 -74 955 5759 39
206.2156 -917 590 5758 84
206.2157 -525 688 5757 48
206.2158 -916 768 5756 38
206.2159 -170 510 5755 22
206.2160 -55 171 5754 27
206.2161 -12 439 5753 14
206.2162 -366 345 5752 52
206.2163 -349 280 5751 65
206.2164 -609 630 5750 21
206.2165 -364 553 5749 81
206.2166 -901 354 5748 15
206.2167 -919 98 5747 39
206.2168 -258 161 5746 60
206.2169 -339 951 5745 74
206.2170 -731 129 5744 11
206.2171 -94 623 5743 4
206.2172 -64 870 5742 64
206.2173 -649 436 5741 1
206.2174 -77 406 5740 73
206.2175 -198 653 5739 24
206.2176 -256 764 5738 46
206.2177 -936 784 5737 98
206.2178 -210 862 5736 66
206.2179 -822 631 5735 91
206.2180 -505 72 5734 60
206.2181 -753 396 5733 63
206.2182 -433 627 5732 2
206.2183 -29 278 5731 41
206.2184 -753 495 5730 57
206.2185 -889 781 5729 87
206.2186 -980 481 5728 94
206.2187 -921 320 5727 31
206.2188 -231 741 5726 72
206.2189 -558 312 5725 38
206.2190 -675 970 5724 31
206.2191 -769 607 5723 75
206.2192 -349 614 5722 31
206.2193 -782 842 5721 40
206.2194 -713 693 5720 27
206.2195 -300 936 5719 86
206.2196 -160 623 5718 90
206.2197 -578 592 5717 5
206.2198 -429 338 5716 69
206.2199 -341 70 5715 67
206.2200 -363 565 5714 88
206.2201 -992 432 5713 90
206.2202 -771 914 5712 41
206.2203 -149 128 5711 56
206.2204 -757 411 5710 6
206.2205 -313 955 5709 41
206.2206 -30 850 5708 13
206.2207 -253 367 5707 58
206.2208 -268 18 5706 14
206.2209 -505 788 5705 8
206.2210 -132 976 5704 97
206.2211 -517 487 5703 37
206.2212 -786 852 5702 22
206.2213 -716 498 5701 62
206.2214 -456 655 5700 39
206.2215 -104 274 5699 44
206.2216 -483 557 5698 28
206.2217 -348 433 5697 77
206.2218 -229 60 5696 98
206.2219 -811 109 5695 76
206.2220 -489 608 5694 37
206.2221 -635 149 5693 61
206.2222 -354 598 5692 73
206.2223 -842 229 5691 6
206.2224 -380 948 5690 26
206.2225 -717 161 5689 35
206.2226 -123 505 5688 62
206.2227 -372 791 5687 13
206.2228 -950 222 5686 11
206.2229 -501 389 5685 41
206.2230 -459 758 5684 32
206.2231 -550 883 5683 85
206.2232 -368 661 5682 28
206.2233 -281 809 5681 51
206.2234 -787 908 5680 46
206.2235 -655 730 5679 66
206.2236 -713 486 5678 59
206.2237 -569 15 5677 75
206.2238 -833 701 5676 42
206.2239 -630 95 5675 44
206.2240 -875 467 5674 4
206.2241 -221 573 5673 90
206.2242 -851 769 5672 18
206.2243 -901 49 5671 8
206.2244 -177 798 5670 49
206.2245 -244 69 5669 13
206.2246 -471 842 5668 94
206.2247 -314 329 5667 14
206.2248 -606 972 5666 73
206.2249 -627 406 5665 20
206.2250 -894 133 5664 75
206.2251 -803 727 5663 65
206.2252 -720 93 5662 37
206.2253 -250 593 5661 94
206.2254 -729 361 5660 72
206.2255 -227 190 5659 93
206.2256 -512 797 5658 77
206.2257 -357 409 5657 15
206.2258 -565 532 5656 70
206.2259 -272 448 5655 97
206.2260 -405 101 5654 73
206.2261 -634 283 5653 9
206.2262 -499 420 5652 8
206.2263 -231 225 5651 46
206.2264 -171 791 5650 52
206.2265 -392 160 5649 50
206.2266 -387 615 5648 71
206.2267 -876 448 5647 15
206.2268 -84 729 5646 79
206.2269 -346 244 5645 29
206.2270 -817 642 5644 86
206.2271 -862 7 5643 77
206.2272 -195 613 5642 13
206.2273 -433 947 5641 26
206.2274 -631 19 5640 5
206.2275 -544 787 5639 77
206.2276 -166 558 5638 0
206.2277 -719 364 5637 51
206.2278 -484 498 5636 79
206.2279 -602 425 5635 73
206.2280 -634 95 5634 52
206.2281 -394 637 5633 95
206.2282 -665 866 5632 66
206.2283 -928 208 5631 76
206.2284 -232 280 5630 80
206.2285 -228 773 5629 8
206.2286 -194 494 5628 37
206.2287 -866 718 5627 44
206.2288 -72 55 5626 23
206.2289 -330 208 5625 88
206.2290 -458 573 5624 96
206.2291 -770 287 5623 23
206.2292 -658 905 5622 72
206.2293 -927 958 5621 73
206.2294 -506 716 5620 69
206.2295 -279 709 5619 0
206.2296 -776 929 5618 3
206.2297 -662 213 5617 32
206.2298 -846 351 5616 79
206.2299 -634 914 5615 74
206.2300 -285 727 5614 87
206.2301 -382 510 5613 68
206.2302 -946 992 5612 11
206.2303 -242 41 5611 73
206.2304 -6 691 5610 42
206.2305 -779 969 5609 22
206.2306 -715 706 5608 50
206.2307 -861 534 5607 11
206.2308 -437 52 5606 81
206.2309 -186 869 5605 21
206.2310 -217 183 5604 34
206.2311 -518 576 5603 90
206.2312 -950 380 5602 43
206.2313 -349 311 5601 70
206.2314 -722 192 5600 23
206.2315 -263 724 5599 22
206.2316 -172 389 5598 6
206.2317 -481 297 5597 85
206.2318 -182 604 5596 42
206.2319 -686 863 5595 25
206.2320 -607 445 5594 96
206.2321 -196 468 5593 69
206.2322 -69 731 5592 56
206.2323 -118 467 5591 60
206.2324 -468 9 5590 62
206.2325 -334 163 5589 45
206.2326 -92 209 5588 9
206.2327 -693 429 5587 69
206.2328 -740 174 5586 29
206.2329 -417 280 5585 49
206.2330 -977 270 5584 7
206.2331 -736 131 5583 41
206.2332 -263 967 5582 12
206.2333 -458 972 5581 95
206.2334 -845 169 5580 65
206.2335 -953 367 5579 13
206.2336 -780 401 5578 24
206.2337 -254 390 5577 39
206.2338 -893 803 5576 95
206.2339 -10 417 5575 32
206.2340 -139 667 5574 44
206.2341 -163 284 5573 24
206.2342 -994 176 5572 47
206.2343 -803 300 5571 80
206.2344 -802 516 5570 61
206.2345 -966 891 5569 89
206.2346 -10 842 5568 17
206.2347 -586 446 5567 52
206.2348 -386 629 5566 36
206.2349 -749 882 5565 88
206.2350 -383 200 5564 87
206.2351 -107 767 5563 97
206.2352 -875 668 5562 16
206.2353 -784 191 5561 19
206.2354 -624 720 5560 0
206.2355 -48 720 5559 83
206.2356 -395 646 5558 95
206.2357 -817 165 5557 42
206.2358 -747 477 5556 20
206.2359 -682 12 5555 63
206.2360 -432 895 5554 36
206.2361 -99 806 5553 27
206.2362 -476 977 5552 23
206.2363 -471 190 5551 9
206.2364 -0 165 5550 15
206.2365 -73 880 5549 57
206.2366 -481 531 5548 65
206.2367 -687 223 5547 57
206.2368 -465 563 5546 7
206.2369 -116 271 5545 6
206.2370 -89 89 5544 24
206.2371 -828 44 5543 33
206.2372 -787 140 5542 62
206.2373 -24 932 5541 0
206.2374 -284 583 5540 47
206.2375 -349 922 5539 92
206.2376 -307 75 5538 59
206.2377 -660 507 5537 79
206.2378 -291 5 5536 22
206.2379 -181 815 5535 34
206.2380 -45 917 5534 2
206.2381 -903 708 5533 26
206.2382 -208 619 5532 4
206.2383 -348 533 5531 76
206.2384 -661 544 5530 74
206.2385 -847 334 5529 93
206.2386 -567 798 5528 4
206.2387 -502 571 5527 64
206.2388 -189 872 5526 36
206.2389 -897 323 5525 11
206.2390 -208 765 5524 13
206.2391 -89 220 5523 14
206.2392 -86 277 5522 69
206.2393 -988 22 5521 85
206.2394 -209 805 5520 68
206.2395 -536 892 5519 81
206.2396 -226 395 5518 28
206.2397 -699 277 5517 6
206.2398 -549 258 5516 31
206.2399 -557 974 5515 29
206.2400 -544 993 5514 68
206.2401 -942 446 5513 11
206.2402 -254 835 5512 0
206.2403 -217 173 5511 9
206.2404 -912 873 5510 77
206.2405 -497 533 5509 67
206.2406 -117 216 5508 31
206.2407 -19 751 5507 52
206.2408 -283 21 5506 14
206.2409 -981 603 5505 99
206.2410 -546 569 5504 1
206.2411 -611 116 5503 60
206.2412 -662 905 5502 68
206.2413 -300 319 5501 3
206.2414 -339 104 5500 30
206.2415 -317 363 5499 41
206.2416 -465 783 5498 37
206.2417 -729 377 5497 9
206.2418 -417 157 5496 73
206.2419 -33 978 5495 30
206.2420 -452 411 5494 43
206.2421 -211 913 5493 93
206.2422 -585 650 5492 94
206.2423 -214 732 5491 36
206.2424 -741 889 5490 96
206.2425 -580 35 5489 2
206.2426 -405 281 5488 85
206.2427 -219 362 5487 73
206.2428 -179 434 5486 31
206.2429 -566 867 5485 38
206.2430 -497 499 5484 58
206.2431 -263 986 5483 24
206.2432 -918 586 5482 62
206.2433 -842 402 5481 37
206.2434 -854 938 5480 47
206.2435 -754 170 5479 16
206.2436 -919 116 5478 17
206.2437 -928 423 5477 18
206.2438 -566 928 5476 4
206.2439 -367 803 5475 61
206.2440 -512 338 5474 6
206.2441 -400 616 5473 23
206.2442 -184 254 5472 34
206.2443 -464 898 5471 7
206.2444 -767 311 5470 98
206.2445 -53 986 5469 9
206.2446 -693 988 5468 83
206.2447 -494 145 5467 99
206.2448 -125 427 5466 36
206.2449 -464 543 5465 19
206.2450 -722 834 5464 85
206.2451 -362 889 5463 11
206.2452 -355 268 5462 21
206.2453 -586 88 5461 71
206.2454 -324 887 5460 69
206.2455 -998 264 5459 71
206.2456 -843 844 5458 35
206.2457 -717 629 5457 19
206.2458 -884 162 5456 36
206.2459 -708 343 5455 66
206.2460 -945 744 5454 74
206.2461 -621 894 5453 35
206.2462 -179 496 5452 0
206.2463 -200 23 5451 76
206.2464 -623 982 5450 26
206.2465 -419 354 5449 32
206.2466 -215 161 5448 15
206.2467 -466 828 5447 12
206.2468 -819 708 5446 83
206.2469 -598 919 5445 17
206.2470 -849 381 5444 76
206.2471 -397 353 5443 32
206.2472 -473 237 5442 44
206.2473 -41 506 5441 97
206.2474 -628 936 5440 57
206.2475 -192 171 5439 20
206.2476 -332 29 5438 20
206.2477 -119 291 5437 74
206.2478 -789 658 5436 64
206.2479 -537 411 5435 22
206.2480 -28 439 5434 74
206.2481 -115 882 5433 45
206.2482 -731 462 5432 92
206.2483 -569 401 5431 43
206.2484 -765 374 5430 41
206.2485 -141 998 5429 43
206.2486 -737 456 5428 86
206.2487 -633 100 5427 21
206.2488 -246 427 5426 33
206.2489 -971 471 5425 25
206.2490 -557 296 5424 50
206.2491 -419 527 5423 91
206.2492 -61 492 5422 38
206.2493 -27 19 5421 16
206.2494 -375 977 5420 80
206.2495 -542 574 5419 62
206.2496 -355 648 5418 40
206.2497 -673 882 5417 10
206.2498 -956 77 5416 38
206.2499 -174 743 5415 27
206.2500 -769 595 5414 41
206.2501 -35 528 5413 13
206.2502 -472 222 5412 35
206.2503 -41 357 5411 3
206.2504 -402 181 5410 65
206.2505 -926 219 5409 83
206.2506 -765 299 5408 18
206.2507 -804 717 5407 68
206.2508 -333 112 5406 71
206.2509 -148 860 5405 78
206.2510 -66 275 5404 40
206.2511 -306 780 5403 73
206.2512 -865 323 5402 56
206.2513 -176 381 5401 43
206.2514 -961 819 5400 63
206.2515 -919 646 5399 47
206.2516 -582 504 5398 16
206.2517 -604 965 5397 96
206.2518 -251 934 5396 47
206.2519 -585 376 5395 18
206.2520 -494 671 5394 8
206.2521 -456 170 5393 76
206.2522 -941 131 5392 44
206.2523 -562 791 5391 68
206.2524 -172 163 5390 21
206.2525 -142 315 5389 4
206.2526 -538 199 5388 33
206.2527 -30 490 5387 97
206.2528 -558 285 5386 35
206.2529 -704 103 5385 66
206.2530 -501 320 5384 9
206.2531 -38 320 5383 3
206.2532 -339 751 5382 51
206.2533 -628 474 5381 37
206.2534 -848 172 5380 38
206.2535 -115 704 5379 3
206.2536 -709 360 5378 60
206.2537 -204 624 5377 50
206.2538 -181 686 5376 47
206.2539 -783 575 5375 85
206.2540 -0 52 5374 20
206.2541 -569 523 5373 46
206.2542 -276 135 5372 69
206.2543 -302 989 5371 71
206.2544 -468 359 5370 78
206.2545 -343 427 5369 73
206.2546 -736 96 5368 40
206.2547 -937 35 5367 50
206.2548 -110 619 5366 2
206.2549 -523 649 5365 39
206.2550 -529 741 5364 78
206.2551 -387 762 5363 43
206.2552 -146 988 5362 29
206.2553 -630 930 5361 97
206.2554 -932 47 5360 83
206.2555 -330 326 5359 12
206.2556 -61 901 5358 60
206.2557 -415 481 5357 79
206.2558 -969 624 5356 82
206.2559 -907 614 5355 58
206.2560 -978 352 5354 99
206.2561 -774 138 5353 14
206.2562 -57 318 5352 24
206.2563 -882 140 5351 51
206.2564 -721 708 5350 69
206.2565 -425 516 5349 60
206.2566 -419 809 5348 26
206.2567 -857 971 5347 64
206.2568 -10 239 5346 44
206.2569 -262 592 5345 6
206.2570 -214 853 5344 92
206.2571 -819 899 5343 20
206.2572 -178 725 5342 71
206.2573 -431 818 5341 17
206.2574 -192 96 5340 16
206.2575 -707 331 5339 29
206.2576 -838 624 5338 0
206.2577 -731 199 5337 56
206.2578 -647 384 5336 84
206.2579 -739 132 5335 74
206.2580 -953 725 5334 4
206.2581 -174 486 5333 39
206.2582 -907 542 5332 64
206.2583 -721 13 5331 74
206.2584 -765 865 5330 23
206.2585 -707 289 5329 48
206.2586 -425 443 5328 86
206.2587 -814 715 5327 10
206.2588 -252 99 5326 8
206.2589 -406 699 5325 90
206.2590 -239 653 5324 78
206.2591 -943 752 5323 77
206.2592 -529 894 5322 26
206.2593 -147 507 5321 18
206.2594 -575 754 5320 95
206.2595 -846 615 5319 5
206.2596 -728 762 5318 28
206.2597 -615 22 5317 61
206.2598 -399 176 5316 56
206.2599 -45 121 5315 84
206.2600 -900 8 5314 16
206.2601 -857 511 5313 29
206.2602 -387 81 5312 41
206.2603 -752 230 5311 38
206.2604 -138 897 5310 57
206.2605 -852 776 5309 72
206.2606 -740 670 5308 11
206.2607 -845 48 5307 11
206.2608 -55 717 5306 21
206.2609 -113 677 5305 35
206.2610 -496 871 5304 14
206.2611 -429 882 5303 4
206.2612 -850 31 5302 47
206.2613 -332 810 5301 63
206.2614 -120 842 5300 61
206.2615 -105 612 5299 28
206.2616 -622 3 5298 11
206.2617 -330 897 5297 89
206.2618 -39 861 5296 78
206.2619 -806 209 5295 94
206.2620 -989 101 5294 61
206.2621 -851 572 5293 6
206.2622 -220 835 5292 57
206.2623 -968 21 5291 51
206.2624 -229 327 5290 21
206.2625 -608 174 5289 1
206.2626 -106 216 5288 48
206.2627 -36 105 5287 29
206.2628 -651 847 5286 29
206.2629 -108 326 5285 23
206.2630 -528 549 5284 81
206.2631 -737 487 5283 13
206.2632 -813 60 5282 63
206.2633 -694 305 5281 25
206.2634 -153 197 5280 73
206.2635 -957 532 5279 62
206.2636 -111 190 5278 50
206.2637 -257 1 5277 7
206.2638 -521 57 5276 38
206.2639 -777 416 5275 54
206.2640 -61 679 5274 57
206.2641 -426 506 5273 79
206.2642 -754 379 5272 92
206.2643 -108 512 5271 11
206.2644 -664 117 5270 54
206.2645 -341 119 5269 19
206.2646 -188 431 5268 84
206.2647 -944 685 5267 85
206.2648 -640 840 5266 73
206.2649 -736 964 5265 74
206.2650 -173 788 5264 71
206.2651 -126 866 5263 63
206.2652 -866 804 5262 67
206.2653 -394 578 5261 64
206.2654 -998 344 5260 44
206.2655 -687 349 5259 32
206.2656 -745 992 5258 15
206.2657 -845 116 5257 24
206.2658 -876 992 5256 30
206.2659 -175 28 5255 90
206.2660 -922 81 5254 56
206.2661 -61 962 5253 4
206.2662 -225 25 5252 26
206.2663 -233 201 5251 47
206.2664 -995 120 5250 39
206.2665 -357 170 5249 31
206.2666 -875 908 5248 94
206.2667 -124 940 5247 90
206.2668 -964 399 5246 96
206.2669 -946 340 5245 70
206.2670 -119 517 5244 25
206.2671 -936 786 5243 86
206.2672 -823 788 5242 83
206.2673 -80 75 5241 99
206.2674 -950 86 5240 23
206.2675 -261 368 5239 63
206.2676 -968 41 5238 48
206.2677 -540 932 5237 75
206.2678 -59 266 5236 15
206.2679 -822 448 5235 1
206.2680 -731 392 5234 82
206.2681 -997 24 5233 18
206.2682 -712 843 5232 11
206.2683 -988 753 5231 74
206.2684 -717 601 5230 13
206.2685 -326 155 5229 68
206.2686 -109 730 5228 29
206.2687 -665 592 5227 42
206.2688 -818 142 5226 48
206.2689 -55 189 5225 23
206.2690 -368 644 5224 9
206.2691 -180 70 5223 73
206.2692 -90 369 5222 28
206.2693 -151 612 5221 72
206.2694 -445 440 5220 27
206.2695 -425 396 5219 39
206.2696 -137 865 5218 21
206.2697 -449 946 5217 44
206.2698 -952 244 5216 84
206.2699 -544 145 5215 76
206.2700 -574 357 5214 68
206.2701 -700 448 5213 18
206.2702 -756 561 5212 8
206.2703 -172 452 5211 93
206.2704 -43 880 5210 70
206.2705 -531 173 5209 1
206.2706 -918 773 5208 28
206.2707 -702 597 5207 68
206.2708 -98 83 5206 49
206.2709 -788 76 5205 40
206.2710 -909 499 5204 97
206.2711 -887 97 5203 87
206.2712 -108 151 5202 94
206.2713 -572 232 5201 58
206.2714 -707 686 5200 12
206.2715 -399 731 5199 51
206.2716 -176 599 5198 61
206.2717 -513 190 5197 21
206.2718 -6 90 5196 60
206.2719 -577 436 5195 31
206.2720 -401 96 5194 87
206.2721 -946 929 5193 2
206.2722 -919 360 5192 77
206.2723 -545 455 5191 53
206.2724 -954 617 5190 86
206.2725 -132 898 5189 30
206.2726 -409 397 5188 22
206.2727 -99 611 5187 66
206.2728 -653 294 5186 50
206.2729 -340 431 5185 42
206.2730 -167 856 5184 17
206.2731 -569 242 5183 45
206.2732 -905 243 5182 2
206.2733 -837 669 5181 37
206.2734 -718 557 5180 59
206.2735 -501 85 5179 82
206.2736 -785 559 5178 72
206.2737 -317 155 5177 30
206.2738 -862 77 5176 44
206.2739 -574 253 5175 31
206.2740 -614 721 5174 17
206.2741 -999 427 5173 59
206.2742 -573 653 5172 66
206.2743 -111 783 5171 6
206.2744 -472 768 5170 11
206.2745 -525 100 5169 21
206.2746 -404 412 5168 71
206.2747 -78 863 5167 46
206.2748 -824 133 5166 45
206.2749 -531 140 5165 28
206.2750 -294 575 5164 96
206.2751 -774 933 5163 61
206.2752 -870 597 5162 42
206.2753 -14 947 5161 46
206.2754 -667 903 5160 63
206.2755 -687 499 5159 94
206.2756 -549 249 5158 12
206.2757 -730 12 5157 32
206.2758 -992 166 5156 25
206.2759 -564 328 5155 29
206.2760 -641 345 5154 23
206.2761 -336 188 5153 52
206.2762 -649 963 5152 90
206.2763 -44 822 5151 85
206.2764 -403 692 5150 34
206.2765 -250 825 5149 98
206.2766 -237 795 5148 13
206.2767 -845 71 5147 81
206.2768 -838 961 5146 73
206.2769 -982 54 5145 42
206.2770 -156 717 5144 92
206.2771 -225 616 5143 30
206.2772 -141 48 5142 68
206.2773 -130 508 5141 60
206.2774 -866 366 5140 64
206.2775 -30 842 5139 15
206.2776 -723 318 5138 1
206.2777 -109 82 5137 39
206.2778 -907 309 5136 0
206.2779 -336 505 5135 85
206.2780 -101 617 5134 82
206.2781 -568 618 5133 93
206.2782 -539 82 5132 8
206.2783 -141 964 5131 1
206.2784 -523 487 5130 26
206.2785 -524 140 5129 83
206.2786 -236 620 5128 30
206.2787 -772 384 5127 61
206.2788 -803 150 5126 20
206.2789 -887 30 5125 57
206.2790 -998 893 5124 23
206.2791 -536 848 5123 53
206.2792 -118 72 5122 2
206.2793 -476 748 5121 39
206.2794 -347 426 5120 61
206.2795 -519 530 5119 99
206.2796 -236 692 5118 28
206.2797 -234 411 5117 46
206.2798 -120 630 5116 96
206.2799 -136 336 5115 91
206.2800 -45 701 5114 88
206.2801 -776 505 5113 46
206.2802 -323 630 5112 41
206.2803 -321 779 5111 64
206.2804 -896 618 5110 12
206.2805 -837 711 5109 82
206.2806 -281 824 5108 28
206.2807 -780 494 5107 0
206.2808 -294 53 5106 11
206.2809 -634 26 5105 98
206.2810 -196 426 5104 9
206.2811 -875 44 5103 26
206.2812 -850 776 5102 45
206.2813 -160 512 5101 0
206.2814 -907 301 5100 42
206.2815 -887 544 5099 5
206.2816 -329 281 5098 55
206.2817 -441 888 5097 50
206.2818 -26 129 5096 48
206.2819 -600 893 5095 65
206.2820 -382 821 5094 43
206.2821 -267 817 5093 32
206.2822 -264 450 5092 2
206.2823 -211 576 5091 68
206.2824 -757 367 5090 25
206.2825 -262 502 5089 1
206.2826 -393 55 5088 55
206.2827 -758 14 5087 88
206.2828 -236 826 5086 41
206.2829 -72 220 5085 42
206.2830 -3 118 5084 21
206.2831 -366 295 5083 11
206.2832 -874 335 5082 0
206.2833 -208 435 5081 5
206.2834 -864 233 5080 45
206.2835 -446 461 5079 49
206.2836 -41 670 5078 86
206.2837 -187 472 5077 63
206.2838 -606 989 5076 52
206.2839 -102 208 5075 16
206.2840 -822 102 5074 6
206.2841 -959 112 5073 63
206.2842 -900 949 5072 49
206.2843 -201 599 5071 66
206.2844 -772 959 5070 34
206.2845 -791 624 5069 41
206.2846 -197 235 5068 40
206.2847 -483 111 5067 85
206.2848 -780 359 5066 58
206.2849 -106 95 5065 50
206.2850 -990 431 5064 27
206.2851 -162 144 5063 86
206.2852 -350 826 5062 5
206.2853 -639 321 5061 69
206.2854 -335 926 5060 42
206.2855 -388 12 5059 98
206.2856 -124 551 5058 59
206.2857 -752 272 5057 71
206.2858 -264 77 5056 70
206.2859 -663 223 5055 67
206.2860 -287 417 5054 11
206.2861 -317 803 5053 82
206.2862 -505 360 5052 81
206.2863 -395 269 5051 71
206.2864 -913 448 5050 30
206.2865 -460 387 5049 94
206.2866 -279 879 5048 26
206.2867 -194 11 5047 37
206.2868 -854 29 5046 48
206.2869 -806 557 5045 60
206.2870 -613 288 5044 37
206.2871 -442 16 5043 96
206.2872 -91 100 5042 81
206.2873 -821 407 5041 11
206.2874 -60 357 5040 48
206.2875 -508 681 5039 45
206.2876 -867 892 5038 18
206.2877 -982 884 5037 8
206.2878 -471 886 5036 34
206.2879 -269 225 5035 4
206.2880 -272 406 5034 19
206.2881 -915 157 5033 17
206.2882 -692 701 5032 35
206.2883 -50 628 5031 26
206.2884 -675 28 5030 76
206.2885 -789 272 5029 55
206.2886 -8 95 5028 64
206.2887 -997 745 5027 88
206.2888 -661 292 5026 51
206.2889 -819 855 5025 20
206.2890 -248 21 5024 99
206.2891 -455 819 5023 35
206.2892 -73 81 5022 22
206.2893 -600 508 5021 64
206.2894 -756 209 5020 37
206.2895 -176 911 5019 88
206.2896 -350 755 5018 78
206.2897 -453 374 5017 1
206.2898 -437 308 5016 33
206.2899 -833 205 5015 84
206.2900 -202 640 5014 57
206.2901 -737 133 5013 79
206.2902 -572 580 5012 38
206.2903 -299 268 5011 47
206.2904 -297 487 5010 84
206.2905 -155 105 5009 57
206.2906 -380 770 5008 82
206.2907 -65 674 5007 89
206.2908 -103 493 5006 1
206.2909 -565 272 5005 60
206.2910 -506 777 5004 63
206.2911 -552 410 5003 46
206.2912 -312 909 5002 16
206.2913 -780 628 5001 27
206.2914 -382 264 5000 0
206.2915 -335 752 4999 14
206.2916 -95 929 4998 77
206.2917 -181 881 4997 31
206.2918 -220 412 4996 96
206.2919 -494 972 4995 53
206.2920 -366 167 4994 5
206.2921 -500 299 4993 95
206.2922 -281 891 4992 23
206.2923 -363 271 4991 53
206.2924 -512 859 4990 39
206.2925 -823 366 4989 4
206.2926 -48 459 4988 23
206.2927 -468 353 4987 91
206.2928 -440 424 4986 96
206.2929 -804 479 4985 72
206.2930 -867 104 4984 12
206.2931 -407 714 4983 86
206.2932 -620 708 4982 21
206.2933 -411 133 4981 91
206.2934 -492 351 4980 85
206.2935 -907 807 4979 68
206.2936 -106 325 4978 77
206.2937 -929 953 4977 57
206.2938 -944 234 4976 2
206.2939 -375 598 4975 63
206.2940 -389 261 4974 93
206.2941 -6 646 4973 46
206.2942 -575 302 4972 78
206.2943 -781 66 4971 20
206.2944 -543 162 4970 91
206.2945 -482 914 4969 58
206.2946 -372 195 4968 80
206.2947 -718 550 4967 17
206.2948 -635 393 4966 98
206.2949 -336 698 4965 56
206.2950 -615 476 4964 98
206.2951 -343 673 4963 38
206.2952 -236 577 4962 43
206.2953 -903 290 4961 79
206.2954 -248 332 4960 23
206.2955 -718 785 4959 6
206.2956 -644 622 4958 11
206.2957 -157 192 4957 65
206.2958 -695 415 4956 8
206.2959 -221 582 4955 29
206.2960 -803 602 4954 72
206.2961 -95 951 4953 27
206.2962 -286 637 4952 10
206.2963 -958 556 4951 33
206.2964 -547 175 4950 65
206.2965 -162 951 4949 52
206.2966 -429 456 4948 7
206.2967 -777 570 4947 48
206.2968 -833 783 4946 46
206.2969 -979 577 4945 47
206.2970 -651 449 4944 41
206.2971 -314 164 4943 70
206.2972 -81 775 4942 80
206.2973 -380 676 4941 32
206.2974 -224 125 4940 41
206.2975 -495 455 4939 38
206.2976 -885 586 4938 73
206.2977 -787 25 4937 65
206.2978 -206 988 4936 94
206.2979 -127 55 4935 85
206.2980 -285 710 4934 32
206.2981 -388 898 4933 33
206.2982 -98 479 4932 23
206.2983 -550 918 4931 70
206.2984 -669 26 4930 15
206.2985 -869 651 4929 72
206.2986 -560 80 4928 60
206.2987 -37 708 4927 9
206.2988 -932 90 4926 58
206.2989 -345 524 4925 7
206.2990 -811 991 4924 84
206.2991 -419 103 4923 89
206.2992 -561 532 4922 29
206.2993 -892 543 4921 54
206.2994 -374 427 4920 88
206.2995 -571 119 4919 80
206.2996 -372 511 4918 30
206.2997 -617 517 4917 52
206.2998 -566 502 4916 10
206.2999 -532 235 4915 58
206.3000 -888 945 4914 53
206.3001 -570 606 4913 39
206.3002 -988 742 4912 85
206.3003 -116 666 4911 66
206.3004 -307 80 4910 51
206.3005 -608 491 4909 80
206.3006 -993 784 4908 19
206.3007 -14 418 4907 75
206.3008 -266 517 4906 5
206.3009 -290 53 4905 3
206.3010 -339 141 4904 64
206.3011 -863 534 4903 31
206.3012 -75 188 4902 58
206.3013 -586 151 4901 87
206.3014 -588 714 4900 80
206.3015 -706 604 4899 69
206.3016 -366 443 4898 61
206.3017 -901 704 4897 97
206.3018 -463 16 4896 74
206.3019 -912 390 4895 97
206.3020 -606 325 4894 95
206.3021 -346 736 4893 47
206.3022 -36 709 4892 78
206.3023 -437 63 4891 48
206.3024 -109 109 4890 99
206.3025 -160 85 4889 88
206.3026 -739 635 4888 34
206.3027 -687 230 4887 46
206.3028 -626 771 4886 43
206.3029 -64 26 4885 55
206.3030 -589 474 4884 30
206.3031 -27 687 4883 26
206.3032 -646 298 4882 31
206.3033 -953 492 4881 59
206.3034 -24 114 4880 32
206.3035 -449 541 4879 94
206.3036 -404 875 4878 42
206.3037 -459 27 4877 5
206.3038 -745 885 4876 6
206.3039 -551 246 4875 56
206.3040 -787 45 4874 47
206.3041 -388 949 4873 56
206.3042 -806 711 4872 38
206.3043 -377 269 4871 69
206.3044 -573 379 4870 92
206.3045 -666 527 4869 57
206.3046 -848 367 4868 4
206.3047 -141 992 4867 94
206.3048 -639 498 4866 71
206.3049 -200 87 4865 19
206.3050 -95 913 4864 76
206.3051 -237 179 4863 39
206.3052 -441 689 4862 58
206.3053 -889 763 4861 42
206.3054 -852 354 4860 80
206.3055 -159 529 4859 90
206.3056 -375 99 4858 81
206.3057 -494 231 4857 70
206.3058 -411 518 4856 50
206.3059 -173 430 4855 43
206.3060 -734 365 4854 10
206.3061 -490 817 4853 85
206.3062 -925 151 4852 79
206.3063 -409 625 4851 55
206.3064 -824 896 4850 3
206.3065 -429 89 4849 69
206.3066 -867 111 4848 78
206.3067 -712 203 4847 88
206.3068 -88 63 4846 8
206.3069 -65 334 4845 23
206.3070 -548 246 4844 43
206.3071 -665 61 4843 24
206.3072 -525 243 4842 56
206.3073 -729 514 4841 51
206.3074 -807 345 4840 58
206.3075 -977 908 4839 39
206.3076 -907 902 4838 56
206.3077 -140 798 4837 15
206.3078 -728 844 4836 62
206.3079 -87 798 4835 2
206.3080 -185 195 4834 51
206.3081 -818 678 4833 88
206.3082 -729 49 4832 13
206.3083 -168 930 4831 79
206.3084 -437 190 4830 92
206.3085 -5 833 4829 82
206.3086 -103 406 4828 6
206.3087 -953 530 4827 76
206.3088 -46 601 4826 41
206.3089 -603 506 4825 64
206.3090 -517 634 4824 90
206.3091 -628 743 4823 36
206.3092 -118 343 4822 8
206.3093 -740 874 4821 56
206.3094 -357 92 4820 73
206.3095 -426 759 4819 43
206.3096 -876 302 4818 90
206.3097 -929 355 4817 15
206.3098 -94 770 4816 90
206.3099 -871 738 4815 44
206.3100 -891 535 4814 8
206.3101 -400 278 4813 88
206.3102 -468 527 4812 51
206.3103 -781 829 4811 37
206.3104 -332 299 4810 38
206.3105 -457 529 4809 93
206.3106 -947 751 4808 55
206.3107 -584 242 4807 94
206.3108 -31 464 4806 83
206.3109 -203 357 4805 22
206.3110 -256 196 4804 98
206.3111 -750 377 4803 49
206.3112 -698 133 4802 93
206.3113 -529 993 4801 68
206.3114 -769 452 4800 44
206.3115 -778 380 4799 87
206.3116 -509 603 4798 50
206.3117 -777 112 4797 36
206.3118 -107 611 4796 55
206.3119 -160 243 4795 82
206.3120 -818 488 4794 94
206.3121 -244 560 4793 50
206.3122 -139 244 4792 5
206.3123 -541 237 4791 16
206.3124 -71 573 4790 75
206.3125 -777 366 4789 99
206.3126 -490 145 4788 26
206.3127 -501 810 4787 73
206.3128 -367 724 4786 67
206.3129 -754 881 4785 94
206.3130 -928 440 4784 34
206.3131 -315 454 4783 57
206.3132 -7 882 4782 10
206.3133 -663 410 4781 59
206.3134 -207 767 4780 46
206.3135 -220 722 4779 29
206.3136 -334 538 4778 28
206.3137 -86 60 4777 98
206.3138 -842 724 4776 13
206.3139 -441 604 4775 61
206.3140 -985 767 4774 82
206.3141 -572 468 4773 61
206.3142 -471 507 4772 30
206.3143 -642 128 4771 34
206.3144 -45 175 4770 45
206.3145 -184 7 4769 98
206.3146 -477 296 4768 88
206.3147 -335 856 4767 24
206.3148 -119 519 4766 24
206.3149 -836 787 4765 40
206.3150 -298 212 4764 45
206.3151 -961 305 4763 41
206.3152 -378 964 4762 10
206.3153 -952 888 4761 82
206.3154 -167 468 4760 59
206.3155 -710 101 4759 86
206.3156 -440 637 4758 70
206.3157 -336 4 4757 14
206.3158 -731 841 4756 21
206.3159 -575 946 4755 28
206.3160 -906 41 4754 53
206.3161 -341 313 4753 33
206.3162 -75 270 4752 58
206.3163 -419 232 4751 42
206.3164 -367 735 4750 78
206.3165 -464 155 4749 45
206.3166 -632 564 4748 27
206.3167 -162 925 4747 10
206.3168 -895 933 4746 60
206.3169 -905 745 4745 15
206.3170 -728 200 4744 66
206.3171 -42 754 4743 56
206.3172 -38 157 4742 26
206.3173 -497 640 4741 65
206.3174 -580 327 4740 5
206.3175 -591 187 4739 90
206.3176 -638 166 4738 83
206.3177 -992 498 4737 46
206.3178 -187 448 4736 26
206.3179 -545 487 4735 99
206.3180 -445 103 4734 17
206.3181 -597 300 4733 68
206.3182 -516 608 4732 0
206.3183 -313 605 4731 54
206.3184 -140 148 4730 91
206.3185 -20 71 4729 98
206.3186 -667 362 4728 95
206.3187 -50 201 4727 64
206.3188 -960 277 4726 80
206.3189 -384 813 4725 64
206.3190 -802 491 4724 9
206.3191 -691 681 4723 84
206.3192 -3 462 4722 8
206.3193 -456 624 4721 20
206.3194 -76 927 4720 17
206.3195 -709 36 4719 12
206.3196 -160 306 4718 35
206.3197 -924 840 4717 61
206.3198 -464 162 4716 8
206.3199 -321 543 4715 57
206.3200 -809 250 4714 58
206.3201 -219 767 4713 11
206.3202 -838 878 4712 68
206.3203 -697 30 4711 54
206.3204 -890 52 4710 38
206.3205 -729 767 4709 36
206.3206 -466 735 4708 54
206.3207 -677 527 4707 23
206.3208 -619 513 4706 45
206.3209 -292 994 4705 14
206.3210 -483 471 4704 51
206.3211 -888 422 4703 58
206.3212 -848 141 4702 38
206.3213 -977 166 4701 14
206.3214 -285 13 4700 80
206.3215 -31 817 4699 16
206.3216 -208 312 4698 26
206.3217 -13 776 4697 78
206.3218 -519 316 4696 5
206.3219 -523 629 4695 32
206.3220 -48 922 4694 80
206.3221 -280 208 4693 59
206.3222 -975 240 4692 4
206.3223 -152 334 4691 87
206.3224 -196 645 4690 69
206.3225 -504 897 4689 25
206.3226 -535 474 4688 82
206.3227 -460 731 4687 19
206.3228 -686 729 4686 49
206.3229 -706 519 4685 99
206.3230 -714 213 4684 47
206.3231 -968 554 4683 76
206.3232 -905 169 4682 30
206.3233 -689 179 4681 82
206.3234 -747 438 4680 95
206.3235 -423 429 4679 69
206.3236 -743 629 4678 96
206.3237 -1 701 4677 7
206.3238 -210 496 4676 77
206.3239 -305 522 4675 97
206.3240 -659 706 4674 99
206.3241 -384 462 4673 74
206.3242 -990 481 4672 6
206.3243 -740 868 4671 21
206.3244 -8 263 4670 94
206.3245 -800 723 4669 32
206.3246 -927 892 4668 67
206.3247 -204 302 4667 74
206.3248 -974 793 4666 79
206.3249 -815 987 4665 90
206.3250 -244 246 4664 64
206.3251 -981 682 4663 27
206.3252 -613 846 4662 39
206.3253 -604 274 4661 24
206.3254 -540 617 4660 73
206.3255 -830 644 4659 20
206.3256 -590 937 4658 87
206.3257 -509 951 4657 72
206.3258 -805 885 4656 22
206.3259 -740 259 4655 15
206.3260 -563 371 4654 57
206.3261 -836 880 4653 26
206.3262 -572 144 4652 36
206.3263 -656 517 4651 0
206.3264 -973 523 4650 6
206.3265 -706 335 4649 71
206.3266 -986 148 4648 24
206.3267 -66 494 4647 8
206.3268 -626 70 4646 70
206.3269 -887 588 4645 6
206.3270 -491 307 4644 17
206.3271 -735 895 4643 72
206.3272 -627 358 4642 26
206.3273 -993 945 4641 91
206.3274 -188 353 4640 68
206.3275 -186 469 4639 26
206.3276 -654 159 4638 72
206.3277 -424 377 4637 91
206.3278 -481 637 4636 44
206.3279 -280 889 4635 73
206.3280 -412 448 4634 39
206.3281 -536 464 4633 75
206.3282 -413 347 4632 10
206.3283 -591 232 4631 63
206.3284 -883 417 4630 80
206.3285 -310 545 4629 0
206.3286 -782 800 4628 53
206.3287 -739 479 4627 23
206.3288 -748 701 4626 94
206.3289 -440 341 4625 20
206.3290 -984 640 4624 86
206.3291 -117 648 4623 87
206.3292 -114 473 4622 12
206.3293 -815 828 4621 82
206.3294 -871 803 4620 70
206.3295 -744 470 4619 57
206.3296 -320 300 4618 52
206.3297 -778 288 4617 4
206.3298 -359 742 4616 99
206.3299 -701 332 4615 30
206.3300 -992 992 4614 45
206.3301 -174 752 4613 86
206.3302 -645 301 4612 0
206.3303 -24 114 4611 29
206.3304 -333 134 4610 94
206.3305 -169 45 4609 12
206.3306 -12 485 4608 42
206.3307 -545 51 4607 54
206.3308 -410 683 4606 41
206.3309 -339 851 4605 65
206.3310 -239 590 4604 70
206.3311 -451 863 4603 81
206.3312 -187 704 4602 52
206.3313 -979 355 4601 62
206.3314 -89 816 4600 69
206.3315 -559 702 4599 16
206.3316 -434 881 4598 15
206.3317 -368 123 4597 46
206.3318 -832 760 4596 13
206.3319 -261 948 4595 7
206.3320 -726 891 4594 10
206.3321 -159 288 4593 78
206.3322 -349 907 4592 26
206.3323 -538 930 4591 20
206.3324 -114 526 4590 89
206.3325 -821 7 4589 52
206.3326 -757 689 4588 12
206.3327 -363 331 4587 6
206.3328 -812 64 4586 53
206.3329 -56 970 4585 57
206.3330 -603 312 4584 53
206.3331 -380 523 4583 56
206.3332 -977 56 4582 81
206.3333 -403 317 4581 81
206.3334 -518 360 4580 42
206.3335 -318 404 4579 29
206.3336 -358 59 4578 6
206.3337 -266 529 4577 39
206.3338 -94 964 4576 55
206.3339 -658 36 4575 75
206.3340 -788 967 4574 45
206.3341 -467 757 4573 22
206.3342 -739 999 4572 40
206.3343 -956 386 4571 57
206.3344 -956 131 4570 88
206.3345 -344 229 4569 20
206.3346 -529 669 4568 95
206.3347 -564 843 4567 9
206.3348 -928 795 4566 17
206.3349 -69 301 4565 43
206.3350 -210 231 4564 86
206.3351 -757 819 4563 32
206.3352 -612 829 4562 72
206.3353 -255 688 4561 78
206.3354 -902 685 4560 0
206.3355 -559 240 4559 61
206.3356 -826 867 4558 81
206.3357 -47 920 4557 96
206.3358 -494 735 4556 63
206.3359 -70 566 4555 85
206.3360 -412 548 4554 85
206.3361 -989 593 4553 45
206.3362 -140 945 4552 14
206.3363 -3 781 4551 35
206.3364 -444 389 4550 35
206.3365 -372 796 4549 34
206.3366 -947 850 4548 73
206.3367 -184 328 4547 77
206.3368 -168 778 4546 55
206.3369 -18 999 4545 42
206.3370 -955 407 4544 65
206.3371 -647 307 4543 42
206.3372 -163 787 4542 84
206.3373 -392 5 4541 13
206.3374 -593 9 4540 55
206.3375 -946 609 4539 7
206.3376 -521 954 4538 42
206.3377 -550 226 4537 76
206.3378 -778 128 4536 1
206.3379 -592 766 4535 14
206.3380 -99 235 4534 6
206.3381 -520 573 4533 30
206.3382 -781 711 4532 48
206.3383 -995 579 4531 77
206.3384 -400 485 4530 79
206.3385 -655 647 4529 64
206.3386 -728 661 4528 42
206.3387 -97 746 4527 97
206.3388 -362 866 4526 77
206.3389 -530 86 4525 18
206.3390 -662 756 4524 49
206.3391 -861 823 4523 57
206.3392 -132 713 4522 73
206.3393 -93 971 4521 78
206.3394 -838 152 4520 59
206.3395 -986 222 4519 74
206.3396 -914 452 4518 92
206.3397 -880 200 4517 63
206.3398 -780 584 4516 73
206.3399 -329 694 4515 83
206.3400 -933 913 4514 86
206.3401 -110 840 4513 80
206.3402 -741 952 4512 72
206.3403 -819 190 4511 3
206.3404 -929 850 4510 25
206.3405 -770 817 4509 85
206.3406 -251 296 4508 7
206.3407 -616 896 4507 3
206.3408 -889 902 4506 9
206.3409 -780 963 4505 45
206.3410 -73 67 4504 39
206.3411 -888 71 4503 82
206.3412 -761 690 4502 36
206.3413 -340 782 4501 92
206.3414 -32 403 4500 88
206.3415 -521 780 4499 15
206.3416 -399 37 4498 51
206.3417 -994 934 4497 63
206.3418 -938 648 4496 72
206.3419 -896 54 4495 10
206.3420 -995 573 4494 70
206.3421 -380 454 4493 18
206.3422 -908 446 4492 12
206.3423 -378 32 4491 42
206.3424 -623 730 4490 30
206.3425 -743 640 4489 51
206.3426 -102 883 4488 12
206.3427 -285 908 4487 40
206.3428 -594 617 4486 5
206.3429 -480 401 4485 4
206.3430 -119 522 4484 90
206.3431 -8 58 4483 61
206.3432 -413 705 4482 47
206.3433 -301 113 4481 52
206.3434 -90 796 4480 75
206.3435 -756 388 4479 87
206.3436 -974 717 4478 64
206.3437 -291 349 4477 81
206.3438 -215 12 4476 69
206.3439 -878 142 4475 11
206.3440 -464 285 4474 36
206.3441 -353 141 4473 11
206.3442 -591 943 4472 59
206.3443 -317 773 4471 11
206.3444 -407 875 4470 21
206.3445 -671 238 4469 33
206.3446 -368 824 4468 78
206.3447 -336 125 4467 68
206.3448 -870 576 4466 7
206.3449 -856 753 4465 33
206.3450 -143 249 4464 41
206.3451 -198 516 4463 11
206.3452 -169 482 4462 76
206.3453 -898 901 4461 27
206.3454 -636 877 4460 90
206.3455 -414 551 4459 73
206.3456 -698 99 4458 30
206.3457 -549 606 4457 3
206.3458 -822 738 4456 46
206.3459 -503 922 4455 1
206.3460 -733 303 4454 71
206.3461 -33 349 4453 94
206.3462 -581 486 4452 2
206.3463 -24 365 4451 27
206.3464 -326 172 4450 26
206.3465 -451 433 4449 22
206.3466 -492 271 4448 71
206.3467 -868 565 4447 14
206.3468 -816 452 4446 72
206.3469 -619 300 4445 31
206.3470 -953 768 4444 77
206.3471 -863 916 4443 69
206.3472 -121 757 4442 45
206.3473 -192 10 4441 55
206.3474 -739 39 4440 69
206.3475 -161 506 4439 87
206.3476 -706 566 4438 95
206.3477 -112 422 4437 62
206.3478 -152 407 4436 5
206.3479 -532 548 4435 19
206.3480 -851 70 4434 66
206.3481 -159 246 4433 9
206.3482 -746 896 4432 74
206.3483 -970 858 4431 92
206.3484 -533 823 4430 45
206.3485 -939 915 4429 57
206.3486 -144 334 4428 45
206.3487 -14 573 4427 59
206.3488 -858 854 4426 96
206.3489 -478 531 4425 62
206.3490 -823 575 4424 68
206.3491 -350 348 4423 69
206.3492 -37 813 4422 41
206.3493 -35 475 4421 77
206.3494 -907 875 4420 43
206.3495 -581 122 4419 59
206.3496 -760 862 4418 79
206.3497 -718 632 4417 12
206.3498 -323 340 4416 15
206.3499 -955 939 4415 38
206.3500 -227 989 4414 65
206.3501 -534 279 4413 47
206.3502 -337 636 4412 31
206.3503 -600 338 4411 0
206.3504 -752 844 4410 12
206.3505 -260 798 4409 32
206.3506 -229 666 4408 82
206.3507 -292 973 4407 4
206.3508 -401 776 4406 39
206.3509 -950 725 4405 36
206.3510 -710 181 4404 72
206.3511 -642 159 4403 69
206.3512 -298 311 4402 19
206.3513 -494 875 4401 73
206.3514 -46 801 4400 84
206.3515 -131 505 4399 49
206.3516 -693 778 4398 3
206.3517 -196 647 4397 93
206.3518 -50 26 4396 89
206.3519 -543 640 4395 45
206.3520 -22 35 4394 24
206.3521 -848 495 4393 6
206.3522 -436 459 4392 34
206.3523 -73 889 4391 80
206.3524 -295 356 4390 44
206.3525 -727 460 4389 91
206.3526 -130 94 4388 43
206.3527 -621 45 4387 49
206.3528 -385 440 4386 14
206.3529 -605 210 4385 50
206.3530 -540 172 4384 52
206.3531 -35 722 4383 17
206.3532 -569 540 4382 41
206.3533 -533 355 4381 36
206.3534 -895 533 4380 77
206.3535 -366 475 4379 56
206.3536 -48 942 4378 59
206.3537 -605 350 4377 50
206.3538 -229 638 4376 23
206.3539 -38 985 4375 78
206.3540 -449 347 4374 6
206.3541 -182 761 4373 50
206.3542 -184 50 4372 46
206.3543 -822 583 4371 3
206.3544 -57 209 4370 63
206.3545 -533 971 4369 52
206.3546 -592 87 4368 31
206.3547 -711 273 4367 44
206.3548 -653 455 4366 37
206.3549 -637 715 4365 19
206.3550 -586 560 4364 58
206.3551 -710 38 4363 26
206.3552 -466 429 4362 99
206.3553 -374 397 4361 36
206.3554 -237 109 4360 76
206.3555 -884 210 4359 52
206.3556 -814 875 4358 94
206.3557 -818 66 4357 88
206.3558 -739 184 4356 5
206.3559 -154 603 4355 1
206.3560 -522 320 4354 5
206.3561 -608 269 4353 87
206.3562 -31 635 4352 24
206.3563 -288 597 4351 9
206.3564 -898 240 4350 13
206.3565 -334 583 4349 35
206.3566 -809 59 4348 6
206.3567 -882 822 4347 99
206.3568 -581 43 4346 7
206.3569 -282 963 4345 58
206.3570 -51 175 4344 63
206.3571 -634 631 4343 91
206.3572 -37 152 4342 57
206.3573 -357 954 4341 74
206.3574 -656 783 4340 38
206.3575 -524 284 4339 56
206.3576 -236 72 4338 52
206.3577 -779 918 4337 92
206.3578 -79 494 4336 30
206.3579 -788 952 4335 29
206.3580 -543 718 4334 23
206.3581 -479 337 4333 41
206.3582 -197 833 4332 59
206.3583 -171 353 4331 68
206.3584 -499 825 4330 70
206.3585 -211 38 4329 13
206.3586 -154 598 4328 28
206.3587 -423 626 4327 45
206.3588 -542 2 4326 70
206.3589 -233 67 4325 29
206.3590 -380 814 4324 24
206.3591 -504 819 4323 6
206.3592 -479 916 4322 28
206.3593 -528 978 4321 2
206.3594 -786 569 4320 67
206.3595 -440 845 4319 28
206.3596 -971 829 4318 5
206.3597 -623 757 4317 73
206.3598 -934 409 4316 88
206.3599 -252 46 4315 30
206.3600 -995 180 4314 85
206.3601 -902 782 4313 87
206.3602 -937 255 4312 2
206.3603 -409 355 4311 95
206.3604 -724 383 4310 74
206.3605 -15 229 4309 34
206.3606 -72 327 4308 46
206.3607 -348 848 4307 34
206.3608 -362 573 4306 68
206.3609 -865 455 4305 68
206.3610 -397 977 4304 25
206.3611 -527 850 4303 9
206.3612 -900 73 4302 96
206.3613 -971 209 4301 52
206.3614 -153 396 4300 68
206.3615 -902 876 4299 70
206.3616 -478 120 4298 94
206.3617 -275 659 4297 72
206.3618 -118 6 4296 98
206.3619 -478 424 4295 49
206.3620 -126 164 4294 46
206.3621 -777 127 4293 87
206.3622 -864 437 4292 62
206.3623 -813 842 4291 92
206.3624 -519 976 4290 81
206.3625 -755 765 4289 25
206.3626 -461 218 4288 42
206.3627 -652 738 4287 20
206.3628 -582 488 4286 15
206.3629 -259 28 4285 64
206.3630 -37 597 4284 35
206.3631 -690 243 4283 34
206.3632 -594 697 4282 91
206.3633 -865 111 4281 5
206.3634 -210 566 4280 29
206.3635 -547 826 4279 76
206.3636 -480 221 4278 29
206.3637 -250 45 4277 80
206.3638 -459 517 4276 7
206.3639 -431 288 4275 32
206.3640 -353 2 4274 22
206.3641 -546 436 4273 34
206.3642 -585 861 4272 9
206.3643 -545 757 4271 72
206.3644 -739 530 4270 65
206.3645 -605 469 4269 66
206.3646 -176 484 4268 6
206.3647 -527 739 4267 23
206.3648 -229 747 4266 79
206.3649 -285 100 4265 2
206.3650 -565 874 4264 7
206.3651 -575 252 4263 80
206.3652 -104 365 4262 96
206.3653 -226 75 4261 3
206.3654 -60 990 4260 80
206.3655 -985 596 4259 13
206.3656 -744 837 4258 42
206.3657 -991 439 4257 64
206.3658 -647 762 4256 29
206.3659 -225 949 4255 94
206.3660 -622 271 4254 71
206.3661 -886 846 4253 99
206.3662 -290 920 4252 47
206.3663 -84 233 4251 87
206.3664 -393 672 4250 16
206.3665 -759 704 4249 7
206.3666 -397 781 4248 24
206.3667 -677 349 4247 75
206.3668 -812 354 4246 34
206.3669 -678 224 4245 42
206.3670 -424 728 4244 60
206.3671 -925 520 4243 73
206.3672 -687 592 4242 59
206.3673 -560 712 4241 20
206.3674 -967 90 4240 69
206.3675 -923 834 4239 63
206.3676 -431 487 4238 36
206.3677 -994 409 4237 71
206.3678 -130 921 4236 86
206.3679 -495 819 4235 13
206.3680 -208 868 4234 25
206.3681 -927 138 4233 49
206.3682 -880 391 4232 23
206.3683 -621 514 4231 12
206.3684 -255 56 4230 59
206.3685 -347 272 4229 4
206.3686 -77 642 4228 49
206.3687 -488 854 4227 43
206.3688 -101 731 4226 86
206.3689 -951 879 4225 63
206.3690 -729 754 4224 28
206.3691 -747 260 4223 28
206.3692 -876 112 4222 4
206.3693 -458 533 4221 25
206.3694 -783 548 4220 36
206.3695 -630 552 4219 90
206.3696 -788 55 4218 26
206.3697 -122 572 4217 58
206.3698 -852 228 4216 38
206.3699 -124 348 4215 15
206.3700 -494 4 4214 22
206.3701 -148 235 4213 98
206.3702 -578 786 4212 87
206.3703 -984 892 4211 41
206.3704 -996 458 4210 67
206.3705 -497 638 4209 15
206.3706 -482 680 4208 84
206.3707 -344 202 4207 66
206.3708 -879 236 4206 27
206.3709 -344 928 4205 72
206.3710 -769 239 4204 63
206.3711 -448 111 4203 34
206.3712 -894 452 4202 56
206.3713 -434 743 4201 59
206.3714 -820 520 4200 98
206.3715 -957 311 4199 49
206.3716 -478 176 4198 1
206.3717 -966 395 4197 13
206.3718 -307 543 4196 46
206.3719 -689 97 4195 53
206.3720 -127 283 4194 57
206.3721 -659 777 4193 32
206.3722 -708 975 4192 55
206.3723 -222 604 4191 45
206.3724 -208 489 4190 61
206.3725 -135 484 4189 86
206.3726 -780 877 4188 47
206.3727 -852 672 4187 51
206.3728 -446 929 4186 65
206.3729 -813 960 4185 61
206.3730 -506 253 4184 56
206.3731 -801 766 4183 46
206.3732 -370 94 4182 95
206.3733 -115 845 4181 48
206.3734 -5 750 4180 1
206.3735 -607 383 4179 7
206.3736 -204 967 4178 35
206.3737 -742 852 4177 92
206.3738 -969 41 4176 40
206.3739 -706 54 4175 63
206.3740 -487 95 4174 30
206.3741 -671 516 4173 70
206.3742 -248 465 4172 43
206.3743 -95 471 4171 25
206.3744 -366 940 4170 11
206.3745 -416 717 4169 39
206.3746 -114 426 4168 40
206.3747 -810 522 4167 46
206.3748 -986 773 4166 77
206.3749 -959 325 4165 26
206.3750 -578 602 4164 21
206.3751 -50 273 4163 81
206.3752 -993 175 4162 42
206.3753 -531 144 4161 15
206.3754 -222 712 4160 72
206.3755 -291 994 4159 95
206.3756 -904 941 4158 30
206.3757 -749 687 4157 30
206.3758 -447 511 4156 82
206.3759 -722 42 4155 2
206.3760 -328 403 4154 38
206.3761 -98 392 4153 52
206.3762 -30 269 4152 5
206.3763 -432 425 4151 46
206.3764 -717 777 4150 30
206.3765 -53 648 4149 93
206.3766 -253 998 4148 38
206.3767 -176 479 4147 15
206.3768 -468 796 4146 30
206.3769 -639 646 4145 72
206.3770 -11 852 4144 39
206.3771 -122 472 4143 23
206.3772 -844 593 4142 6
206.3773 -647 154 4141 59
206.3774 -129 376 4140 71
206.3775 -650 544 4139 66
206.3776 -518 232 4138 79
206.3777 -683 853 4137 7
206.3778 -150 576 4136 70
206.3779 -794 330 4135 82
206.3780 -380 163 4134 62
206.3781 -878 162 4133 88
206.3782 -439 469 4132 27
206.3783 -777 883 4131 19
206.3784 -832 49 4130 51
206.3785 -311 864 4129 47
206.3786 -378 722 4128 13
206.3787 -277 369 4127 83
206.3788 -245 878 4126 53
206.3789 -167 201 4125 35
206.3790 -0 739 4124 41
206.3791 -693 610 4123 50
206.3792 -585 81 4122 43
206.3793 -833 678 4121 66
206.3794 -185 38 4120 94
206.3795 -141 347 4119 52
206.3796 -353 296 4118 93
206.3797 -490 302 4117 10
206.3798 -677 176 4116 3
206.3799 -461 942 4115 7
206.3800 -129 912 4114 16
206.3801 -528 62 4113 30
206.3802 -403 777 4112 10
206.3803 -639 715 4111 75
206.3804 -691 424 4110 64
206.3805 -50 587 4109 4
206.3806 -994 831 4108 78
206.3807 -125 69 4107 86
206.3808 -234 953 4106 81
206.3809 -30 911 4105 21
206.3810 -849 858 4104 33
206.3811 -284 200 4103 60
206.3812 -62 355 4102 12
206.3813 -291 103 4101 76
206.3814 -837 604 4100 94
206.3815 -756 255 4099 64
206.3816 -761 925 4098 5
206.3817 -115 48 4097 86
206.3818 -42 598 4096 89
206.3819 -52 882 4095 20
206.3820 -658 731 4094 18
206.3821 -844 475 4093 56
206.3822 -251 361 4092 22
206.3823 -499 815 4091 77
206.3824 -349 307 4090 45
206.3825 -329 584 4089 8
206.3826 -877 187 4088 99
206.3827 -450 977 4087 64
206.3828 -715 687 4086 7
206.3829 -151 23 4085 98
206.3830 -255 615 4084 39
206.3831 -114 343 4083 81
206.3832 -545 451 4082 59
206.3833 -507 316 4081 75
206.3834 -723 373 4080 14
206.3835 -396 86 4079 2
206.3836 -209 348 4078 45
206.3837 -289 571 4077 42
206.3838 -664 84 4076 73
206.3839 -408 594 4075 56
206.3840 -271 580 4074 89
206.3841 -891 220 4073 14
206.3842 -134 841 4072 56
206.3843 -943 602 4071 3
206.3844 -286 129 4070 78
206.3845 -737 568 4069 32
206.3846 -777 24 4068 18
206.3847 -487 692 4067 92
206.3848 -489 169 4066 62
206.3849 -13 668 4065 25
206.3850 -360 755 4064 13
206.3851 -379 571 4063 38
206.3852 -238 530 4062 75
206.3853 -473 254 4061 19
206.3854 -561 456 4060 65
206.3855 -543 139 4059 54
206.3856 -331 267 4058 96
206.3857 -522 294 4057 28
206.3858 -501 369 4056 99
206.3859 -912 119 4055 47
206.3860 -183 756 4054 65
206.3861 -41 623 4053 98
206.3862 -275 566 4052 14
206.3863 -797 534 4051 76
206.3864 -317 107 4050 91
206.3865 -872 589 4049 1
206.3866 -972 670 4048 21
206.3867 -925 292 4047 80
206.3868 -249 521 4046 2
206.3869 -363 822 4045 58
206.3870 -132 671 4044 72
206.3871 -57 841 4043 14
206.3872 -32 375 4042 76
206.3873 -426 852 4041 47
206.3874 -517 894 4040 48
206.3875 -919 805 4039 44
206.3876 -377 403 4038 90
206.3877 -771 787 4037 4
206.3878 -698 432 4036 67
206.3879 -150 859 4035 88
206.3880 -830 587 4034 23
206.3881 -465 375 4033 7
206.3882 -522 288 4032 2
206.3883 -958 997 4031 60
206.3884 -89 35 4030 90
206.3885 -402 544 4029 59
206.3886 -615 853 4028 54
206.3887 -354 370 4027 60
206.3888 -573 790 4026 7
206.3889 -271 655 4025 54
206.3890 -211 154 4024 31
206.3891 -87 50 4023 36
206.3892 -290 419 4022 94
206.3893 -961 696 4021 56
206.3894 -491 310 4020 86
206.3895 -690 56 4019 68
206.3896 -482 935 4018 78
206.3897 -580 533 4017 26
206.3898 -134 524 4016 78
206.3899 -500 228 4015 30
206.3900 -104 954 4014 5
206.3901 -630 421 4013 12
206.3902 -723 378 4012 79
206.3903 -385 695 4011 32
206.3904 -253 182 4010 46
206.3905 -121 899 4009 80
206.3906 -401 526 4008 20
206.3907 -9 478 4007 90
206.3908 -295 479 4006 44
206.3909 -273 242 4005 63
206.3910 -533 935 4004 39
206.3911 -42 327 4003 47
206.3912 -683 467 4002 90
206.3913 -513 859 4001 33
206.3914 -282 669 4000 13
206.3915 -372 592 3999 13
206.3916 -47 305 3998 72
206.3917 -999 457 3997 39
206.3918 -237 811 3996 71
206.3919 -307 238 3995 2
206.3920 -608 922 3994 74
206.3921 -859 566 3993 49
206.3922 -608 568 3992 35
206.3923 -189 206 3991 17
206.3924 -77 999 3990 23
206.3925 -287 411 3989 91
206.3926 -848 328 3988 32
206.3927 -645 678 3987 4
206.3928 -572 691 3986 76
206.3929 -315 282 3985 93
206.3930 -356 250 3984 69
206.3931 -998 131 3983 74
206.3932 -361 188 3982 25
206.3933 -206 940 3981 41
206.3934 -588 320 3980 11
206.3935 -82 584 3979 78
206.3936 -650 277 3978 43
206.3937 -986 286 3977 20
206.3938 -409 831 3976 7
206.3939 -31 230 3975 25
206.3940 -118 950 3974 95
206.3941 -942 496 3973 35
206.3942 -248 833 3972 63
206.3943 -620 305 3971 15
206.3944 -735 322 3970 61
206.3945 -307 351 3969 50
206.3946 -990 236 3968 43
206.3947 -454 129 3967 66
206.3948 -600 815 3966 57
206.3949 -280 297 3965 37
206.3950 -454 601 3964 91
206.3951 -663 721 3963 17
206.3952 -528 480 3962 69
206.3953 -982 537 3961 62
206.3954 -971 111 3960 88
206.3955 -115 74 3959 42
206.3956 -106 767 3958 31
206.3957 -314 86 3957 53
206.3958 -517 200 3956 85
206.3959 -696 464 3955 32
206.3960 -879 736 3954 82
206.3961 -240 483 3953 79
206.3962 -943 65 3952 13
206.3963 -425 743 3951 54
206.3964 -36 456 3950 1
206.3965 -307 110 3949 85
206.3966 -681 781 3948 0
206.3967 -886 681 3947 79
206.3968 -736 533 3946 79
206.3969 -728 495 3945 82
206.3970 -253 34 3944 81
206.3971 -418 656 3943 63
206.3972 -321 588 3942 29
206.3973 -286 535 3941 51
206.3974 -345 154 3940 38
206.3975 -329 847 3939 72
206.3976 -99 216 3938 62
206.3977 -148 996 3937 79
206.3978 -38 975 3936 14
206.3979 -460 4 3935 0
206.3980 -377 178 3934 47
206.3981 -68 341 3933 83
206.3982 -52 779 3932 9
206.3983 -381 129 3931 3
206.3984 -306 658 3930 94
206.3985 -631 104 3929 1
206.3986 -220 830 3928 23
206.3987 -20 645 3927 95
206.3988 -970 141 3926 11
206.3989 -826 533 3925 57
206.3990 -837 640 3924 8
206.3991 -561 738 3923 30
206.3992 -650 62 3922 1
206.3993 -470 93 3921 67
206.3994 -554 924 3920 7
206.3995 -273 785 3919 67
206.3996 -185 280 3918 41
206.3997 -503 839 3917 19
206.3998 -608 533 3916 5
206.3999 -893 494 3915 14
206.4000 -901 773 3914 98
206.4001 -676 292 3913 27
206.4002 -968 346 3912 91
206.4003 -168 594 3911 18
206.4004 -139 400 3910 91
206.4005 -505 263 3909 28
206.4006 -441 211 3908 8
206.4007 -305 148 3907 68
206.4008 -39 905 3906 89
206.4009 -720 155 3905 71
206.4010 -481 713 3904 99
206.4011 -946 364 3903 22
206.4012 -751 730 3902 70
206.4013 -194 264 3901 80
206.4014 -136 634 3900 2
206.4015 -52 193 3899 63
206.4016 -62 405 3898 6
206.4017 -243 787 3897 13
206.4018 -750 179 3896 26
206.4019 -441 724 3895 31
206.4020 -349 766 3894 23
206.4021 -633 518 3893 53
206.4022 -466 906 3892 19
206.4023 -630 771 3891 55
206.4024 -440 395 3890 5
206.4025 -788 569 3889 8
206.4026 -618 929 3888 98
206.4027 -608 868 3887 81
206.4028 -454 947 3886 49
206.4029 -958 79 3885 30
206.4030 -247 703 3884 9
206.4031 -611 340 3883 71
206.4032 -135 637 3882 16
206.4033 -376 499 3881 83
206.4034 -825 973 3880 19
206.4035 -640 95 3879 65
206.4036 -60 169 3878 16
206.4037 -920 326 3877 0
206.4038 -867 184 3876 15
206.4039 -376 216 3875 49
206.4040 -362 376 3874 71
206.4041 -703 548 3873 63
206.4042 -137 331 3872 47
206.4043 -526 645 3871 75
206.4044 -877 538 3870 55
206.4045 -925 482 3869 18
206.4046 -842 159 3868 58
206.4047 -142 856 3867 13
206.4048 -968 657 3866 5
206.4049 -840 786 3865 49
206.4050 -827 74 3864 1
206.4051 -217 160 3863 65
206.4052 -686 717 3862 56
206.4053 -107 207 3861 61
206.4054 -55 366 3860 64
206.4055 -322 604 3859 95
206.4056 -303 440 3858 8
206.4057 -199 86 3857 70
206.4058 -870 561 3856 17
206.4059 -712 477 3855 12
206.4060 -913 354 3854 1
206.4061 -443 92 3853 61
206.4062 -509 955 3852 53
206.4063 -841 962 3851 57
206.4064 -762 696 3850 5
206.4065 -163 869 3849 73
206.4066 -353 381 3848 1
206.4067 -525 527 3847 10
206.4068 -83 45 3846 32
206.4069 -122 115 3845 15
206.4070 -262 402 3844 79
206.4071 -137 79 3843 47
206.4072 -992 951 3842 93
206.4073 -265 527 3841 66
206.4074 -827 318 3840 7
206.4075 -487 713 3839 59
206.4076 -854 914 3838 80
206.4077 -481 775 3837 82
206.4078 -930 169 3836 44
206.4079 -713 360 3835 96
206.4080 -322 327 3834 86
206.4081 -127 536 3833 12
206.4082 -424 266 3832 14
206.4083 -208 588 3831 72
206.4084 -605 479 3830 43
206.4085 -798 789 3829 33
206.4086 -138 981 3828 63
206.4087 -606 385 3827 37
206.4088 -809 481 3826 55
206.4089 -32 100 3825 21
206.4090 -791 735 3824 39
206.4091 -269 980 3823 19
206.4092 -677 417 3822 70
206.4093 -108 288 3821 21
206.4094 -690 98 3820 60
206.4095 -807 707 3819 80
206.4096 -595 259 3818 65
206.4097 -903 822 3817 53
206.4098 -381 334 3816 79
206.4099 -364 826 3815 77
206.4100 -755 195 3814 24
206.4101 -562 492 3813 52
206.4102 -128 486 3812 59
206.4103 -190 613 3811 56
206.4104 -391 796 3810 41
206.4105 -448 146 3809 88
206.4106 -437 127 3808 21
206.4107 -487 735 3807 69
206.4108 -508 20 3806 52
206.4109 -631 535 3805 1
206.4110 -703 719 3804 60
206.4111 -5 930 3803 19
206.4112 -873 22 3802 43
206.4113 -816 150 3801 93
206.4114 -650 535 3800 79
206.4115 -19 670 3799 94
206.4116 -391 519 3798 1
206.4117 -715 169 3797 94
206.4118 -484 504 3796 97
206.4119 -816 408 3795 87
206.4120 -789 416 3794 92
206.4121 -907 758 3793 69
206.4122 -872 496 3792 13
206.4123 -614 139 3791 5
206.4124 -865 855 3790 16
206.4125 -151 932 3789 63
206.4126 -350 61 3788 62
206.4127 -664 969 3787 67
206.4128 -96 102 3786 23
206.4129 -992 949 3785 66
206.4130 -658 229 3784 2
206.4131 -262 566 3783 88
206.4132 -356 74 3782 3
206.4133 -283 890 3781 25
206.4134 -923 534 3780 74
206.4135 -870 3 3779 71
206.4136 -92 952 3778 80
206.4137 -866 444 3777 68
206.4138 -153 563 3776 56
206.4139 -719 640 3775 10
206.4140 -663 145 3774 33
206.4141 -491 846 3773 39
206.4142 -183 778 3772 90
206.4143 -356 507 3771 7
206.4144 -531 35 3770 35
206.4145 -51 913 3769 5
206.4146 -507 115 3768 77
206.4147 -881 116 3767 22
206.4148 -922 464 3766 71
206.4149 -494 769 3765 43
206.4150 -299 938 3764 5
206.4151 -68 490 3763 17
206.4152 -270 832 3762 30
206.4153 -471 713 3761 82
206.4154 -122 306 3760 82
206.4155 -797 275 3759 48
206.4156 -999 552 3758 54
206.4157 -651 512 3757 62
206.4158 -695 279 3756 95
206.4159 -830 378 3755 42
206.4160 -447 883 3754 19
206.4161 -658 864 3753 23
206.4162 -118 479 3752 79
206.4163 -407 2 3751 79
206.4164 -30 344 3750 34
206.4165 -722 937 3749 32
206.4166 -40 916 3748 79
206.4167 -232 668 3747 34
206.4168 -900 530 3746 95
206.4169 -494 232 3745 86
206.4170 -18 963 3744 38
206.4171 -385 434 3743 78
206.4172 -477 998 3742 53
206.4173 -658 449 3741 71
206.4174 -407 23 3740 37
206.4175 -20 527 3739 30
206.4176 -248 450 3738 68
206.4177 -137 391 3737 80
206.4178 -297 91 3736 33
206.4179 -268 481 3735 40
206.4180 -529 593 3734 47
206.4181 -435 249 3733 63
206.4182 -548 828 3732 90
206.4183 -425 334 3731 81
206.4184 -496 68 3730 25
206.4185 -76 626 3729 38
206.4186 -59 873 3728 77
206.4187 -300 475 3727 11
206.4188 -609 925 3726 83
206.4189 -888 930 3725 2
206.4190 -343 841 3724 73
206.4191 -421 725 3723 9
206.4192 -494 88 3722 88
206.4193 -265 568 3721 12
206.4194 -441 863 3720 92
206.4195 -752 614 3719 42
206.4196 -397 662 3718 1
206.4197 -550 270 3717 75
206.4198 -994 811 3716 69
206.4199 -88 289 3715 72
206.4200 -116 645 3714 54
206.4201 -637 207 3713 92
206.4202 -520 764 3712 92
206.4203 -704 193 3711 22
206.4204 -249 508 3710 82
206.4205 -952 403 3709 68
206.4206 -391 258 3708 35
206.4207 -459 67 3707 84
206.4208 -521 970 3706 55
206.4209 -644 175 3705 90
206.4210 -437 622 3704 97
206.4211 -443 995 3703 47
206.4212 -570 698 3702 11
206.4213 -685 404 3701 81
206.4214 -105 135 3700 45
206.4215 -144 333 3699 29
206.4216 -191 507 3698 56
206.4217 -96 291 3697 93
206.4218 -794 649 3696 93
206.4219 -553 933 3695 87
206.4220 -626 493 3694 20
206.4221 -297 362 3693 99
206.4222 -294 301 3692 87
206.4223 -268 359 3691 88
206.4224 -801 158 3690 57
206.4225 -826 736 3689 96
206.4226 -215 628 3688 95
206.4227 -642 994 3687 9
206.4228 -715 60 3686 30
206.4229 -440 670 3685 24
206.4230 -131 212 3684 92
206.4231 -60 121 3683 32
206.4232 -941 988 3682 0
206.4233 -201 305 3681 2
206.4234 -421 618 3680 46
206.4235 -107 7 3679 97
206.4236 -634 859 3678 61
206.4237 -933 791 3677 57
206.4238 -390 60 3676 92
206.4239 -458 315 3675 27
206.4240 -90 596 3674 30
206.4241 -133 327 3673 7
206.4242 -683 976 3672 11
206.4243 -686 558 3671 74
206.4244 -611 491 3670 77
206.4245 -147 364 3669 31
206.4246 -67 37 3668 47
206.4247 -731 646 3667 70
206.4248 -745 651 3666 54
206.4249 -718 966 3665 93
206.4250 -269 238 3664 36
206.4251 -350 951 3663 95
206.4252 -418 379 3662 45
206.4253 -66 960 3661 99
206.4254 -127 465 3660 7
206.4255 -326 840 3659 46
206.4256 -391 772 3658 8
206.4257 -995 157 3657 33
206.4258 -684 610 3656 98
206.4259 -728 564 3655 2
206.4260 -287 409 3654 44
206.4261 -572 507 3653 91
206.4262 -418 453 3652 93
206.4263 -494 922 3651 35
206.4264 -625 610 3650 93
206.4265 -67 383 3649 80
206.4266 -614 744 3648 93
206.4267 -546 349 3647 39
206.4268 -45 959 3646 31
206.4269 -155 577 3645 95
206.4270 -901 529 3644 44
206.4271 -54 987 3643 71
206.4272 -531 580 3642 15
206.4273 -311 411 3641 92
206.4274 -227 138 3640 86
206.4275 -639 866 3639 55
206.4276 -394 537 3638 45
206.4277 -390 85 3637 6
206.4278 -382 355 3636 50
206.4279 -47 513 3635 89
206.4280 -542 726 3634 25
206.4281 -406 561 3633 84
206.4282 -168 229 3632 52
206.4283 -273 54 3631 21
206.4284 -271 312 3630 8
206.4285 -328 104 3629 58
206.4286 -451 385 3628 24
206.4287 -730 566 3627 0
206.4288 -841 610 3626 0
206.4289 -787 636 3625 33
206.4290 -165 406 3624 50
206.4291 -331 323 3623 13
206.4292 -175 303 3622 23
206.4293 -742 135 3621 89
206.4294 -207 496 3620 0
206.4295 -719 342 3619 94
206.4296 -818 241 3618 87
206.4297 -956 995 3617 72
206.4298 -973 673 3616 88
206.4299 -230 828 3615 5
206.4300 -82 370 3614 62
206.4301 -20 897 3613 83
206.4302 -167 342 3612 15
206.4303 -639 894 3611 43
206.4304 -154 58 3610 53
206.4305 -100 65 3609 48
206.4306 -245 155 3608 90
206.4307 -321 832 3607 86
206.4308 -845 834 3606 98
206.4309 -457 431 3605 74
206.4310 -473 789 3604 14
206.4311 -554 676 3603 6
206.4312 -448 723 3602 85
206.4313 -835 898 3601 52
206.4314 -992 45 3600 48
206.4315 -910 587 3599 5
206.4316 -322 39 3598 85
206.4317 -998 878 3597 92
206.4318 -403 239 3596 47
206.4319 -642 595 3595 38
206.4320 -112 85 3594 98
206.4321 -953 209 3593 91
206.4322 -824 324 3592 10
206.4323 -853 42 3591 61
206.4324 -458 431 3590 84
206.4325 -548 198 3589 8
206.4326 -160 930 3588 58
206.4327 -639 447 3587 32
206.4328 -643 89 3586 59
206.4329 -509 403 3585 76
206.4330 -876 65 3584 53
206.4331 -884 812 3583 15
206.4332 -281 493 3582 12
206.4333 -611 769 3581 97
206.4334 -233 760 3580 39
206.4335 -267 494 3579 90
206.4336 -483 262 3578 38
206.4337 -358 729 3577 52
206.4338 -686 834 3576 99
206.4339 -337 229 3575 13
206.4340 -253 372 3574 63
206.4341 -318 28 3573 99
206.4342 -723 158 3572 60
206.4343 -9 576 3571 67
206.4344 -265 485 3570 37
206.4345 -232 522 3569 96
206.4346 -533 866 3568 78
206.4347 -895 525 3567 12
206.4348 -604 861 3566 67
206.4349 -857 500 3565 34
206.4350 -343 641 3564 8
206.4351 -870 387 3563 93
206.4352 -582 933 3562 59
206.4353 -91 292 3561 71
206.4354 -962 412 3560 74
206.4355 -655 181 3559 3
206.4356 -341 658 3558 69
206.4357 -663 453 3557 63
206.4358 -360 323 3556 29
206.4359 -858 265 3555 74
206.4360 -253 148 3554 51
206.4361 -454 340 3553 47
206.4362 -641 880 3552 28
206.4363 -879 970 3551 49
206.4364 -231 710 3550 12
206.4365 -522 334 3549 30
206.4366 -205 61 3548 31
206.4367 -129 347 3547 67
206.4368 -58 543 3546 30
206.4369 -117 232 3545 50
206.4370 -807 40 3544 60
206.4371 -460 185 3543 79
206.4372 -909 796 3542 81
206.4373 -259 362 3541 76
206.4374 -376 821 3540 64
206.4375 -273 992 3539 70
206.4376 -713 636 3538 31
206.4377 -803 374 3537 7
206.4378 -311 801 3536 7
206.4379 -192 897 3535 94
206.4380 -854 805 3534 30
206.4381 -389 985 3533 34
206.4382 -433 51 3532 55
206.4383 -541 114 3531 65
206.4384 -828 937 3530 88
206.4385 -356 393 3529 10
206.4386 -262 240 3528 55
206.4387 -572 4 3527 91
206.4388 -904 130 3526 49
206.4389 -91 631 3525 11
206.4390 -820 963 3524 33
206.4391 -933 795 3523 46
206.4392 -937 900 3522 95
206.4393 -176 766 3521 89
206.4394 -544 780 3520 71
206.4395 -153 543 3519 47
206.4396 -235 648 3518 9
206.4397 -873 418 3517 69
206.4398 -499 373 3516 66
206.4399 -667 781 3515 81
206.4400 -167 872 3514 27
206.4401 -895 508 3513 88
206.4402 -133 64 3512 99
206.4403 -986 178 3511 76
206.4404 -237 241 3510 63
206.4405 -894 378 3509 39
206.4406 -230 403 3508 91
206.4407 -45 21 3507 36
206.4408 -592 855 3506 37
206.4409 -908 541 3505 83
206.4410 -364 384 3504 50
206.4411 -444 890 3503 27
206.4412 -886 235 3502 76
206.4413 -936 128 3501 14
206.4414 -862 240 3500 74
206.4415 -975 474 3499 34
206.4416 -381 555 3498 66
206.4417 -165 987 3497 18
206.4418 -313 543 3496 45
206.4419 -157 330 3495 68
206.4420 -494 228 3494 54
206.4421 -654 510 3493 91
206.4422 -107 614 3492 55
206.4423 -887 399 3491 94
206.4424 -766 405 3490 7
206.4425 -918 679 3489 88
206.4426 -568 478 3488 59
206.4427 -444 732 3487 21
206.4428 -212 769 3486 85
206.4429 -102 139 3485 15
206.4430 -718 624 3484 66
206.4431 -895 361 3483 83
206.4432 -215 608 3482 54
206.4433 -993 875 3481 21
206.4434 -726 187 3480 12
206.4435 -200 292 3479 84
206.4436 -745 378 3478 35
206.4437 -963 364 3477 12
206.4438 -629 695 3476 23
206.4439 -515 493 3475 10
206.4440 -262 823 3474 38
206.4441 -752 292 3473 82
206.4442 -733 327 3472 68
206.4443 -687 99 3471 22
206.4444 -895 272 3470 26
206.4445 -914 498 3469 52
206.4446 -14 226 3468 45
206.4447 -668 892 3467 78
206.4448 -201 122 3466 33
206.4449 -670 726 3465 11
206.4450 -530 560 3464 25
206.4451 -965 142 3463 50
206.4452 -227 458 3462 1
206.4453 -827 954 3461 4
206.4454 -773 742 3460 79
206.4455 -271 70 3459 98
206.4456 -334 672 3458 90
206.4457 -769 448 3457 34
206.4458 -395 221 3456 46
206.4459 -165 860 3455 53
206.4460 -418 743 3454 13
206.4461 -683 490 3453 56
206.4462 -504 973 3452 73
206.4463 -211 253 3451 40
206.4464 -672 811 3450 5
206.4465 -397 80 3449 50
206.4466 -224 554 3448 93
206.4467 -226 878 3447 56
206.4468 -360 934 3446 37
206.4469 -116 392 3445 23
206.4470 -253 573 3444 74
206.4471 -517 828 3443 73
206.4472 -719 337 3442 17
206.4473 -442 346 3441 29
206.4474 -730 551 3440 53
206.4475 -526 564 3439 27
206.4476 -676 373 3438 17
206.4477 -943 190 3437 99
206.4478 -542 143 3436 86
206.4479 -819 483 3435 24
206.4480 -745 11 3434 86
206.4481 -490 556 3433 73
206.4482 -990 885 3432 79
206.4483 -795 753 3431 27
206.4484 -987 265 3430 71
206.4485 -190 101 3429 20
206.4486 -183 175 3428 84
206.4487 -46 131 3427 73
206.4488 -660 621 3426 40
206.4489 -472 380 3425 72
206.4490 -454 127 3424 7
206.4491 -671 938 3423 25
206.4492 -132 520 3422 50
206.4493 -488 564 3421 19
206.4494 -163 507 3420 80
206.4495 -925 354 3419 79
206.4496 -43 117 3418 0
206.4497 -510 330 3417 13
206.4498 -240 679 3416 38
206.4499 -253 648 3415 18
206.4500 -189 819 3414 1
206.4501 -417 753 3413 78
206.4502 -956 305 3412 53
206.4503 -57 386 3411 64
206.4504 -153 11 3410 32
206.4505 -236 789 3409 23
206.4506 -787 869 3408 88
206.4507 -651 750 3407 53
206.4508 -30 198 3406 26
206.4509 -829 170 3405 98
206.4510 -65 234 3404 6
206.4511 -448 244 3403 77
206.4512 -919 894 3402 46
206.4513 -374 320 3401 89
206.4514 -222 86 3400 90
206.4515 -919 355 3399 91
206.4516 -119 348 3398 44
206.4517 -552 264 3397 13
206.4518 -28 281 3396 62
206.4519 -936 924 3395 20
206.4520 -989 291 3394 76
206.4521 -349 310 3393 61
206.4522 -574 562 3392 52
206.4523 -233 994 3391 54
206.4524 -730 988 3390 15
206.4525 -7 466 3389 30
206.4526 -83 314 3388 80
206.4527 -983 514 3387 56
206.4528 -357 420 3386 52
206.4529 -632 436 3385 9
206.4530 -980 146 3384 94
206.4531 -748 88 3383 63
206.4532 -567 984 3382 77
206.4533 -6 392 3381 34
206.4534 -521 849 3380 50
206.4535 -151 501 3379 72
206.4536 -799 233 3378 92
206.4537 -94 42 3377 10
206.4538 -983 431 3376 62
206.4539 -290 145 3375 72
206.4540 -58 307 3374 65
206.4541 -104 864 3373 23
206.4542 -592 434 3372 18
206.4543 -542 837 3371 56
206.4544 -347 780 3370 48
206.4545 -268 798 3369 36
206.4546 -190 823 3368 35
206.4547 -610 474 3367 70
206.4548 -286 901 3366 11
206.4549 -837 72 3365 69
206.4550 -443 418 3364 23
206.4551 -429 52 3363 95
206.4552 -596 618 3362 51
206.4553 -57 76 3361 4
206.4554 -981 114 3360 19
206.4555 -975 17 3359 7
206.4556 -349 647 3358 7
206.4557 -572 593 3357 58
206.4558 -828 418 3356 32
206.4559 -654 460 3355 44
206.4560 -366 278 3354 39
206.4561 -433 441 3353 1
206.4562 -542 462 3352 83
206.4563 -962 855 3351 53
206.4564 -97 114 3350 7
206.4565 -370 2 3349 0
206.4566 -53 497 3348 62
206.4567 -174 255 3347 77
206.4568 -958 875 3346 74
206.4569 -182 54 3345 17
206.4570 -836 380 3344 28
206.4571 -979 181 3343 93
206.4572 -606 292 3342 89
206.4573 -741 464 3341 58
206.4574 -111 68 3340 86
206.4575 -505 380 3339 72
206.4576 -241 848 3338 31
206.4577 -380 33 3337 87
206.4578 -820 569 3336 21
206.4579 -673 886 3335 77
206.4580 -199 355 3334 34
206.4581 -888 41 3333 85
206.4582 -828 311 3332 37
206.4583 -395 715 3331 86
206.4584 -687 138 3330 62
206.4585 -532 410 3329 60
206.4586 -815 437 3328 26
206.4587 -464 662 3327 86
206.4588 -682 441 3326 55
206.4589 -531 429 3325 14
206.4590 -313 488 3324 47
206.4591 -730 483 3323 31
206.4592 -595 507 3322 6
206.4593 -577 236 3321 43
206.4594 -727 22 3320 70
206.4595 -973 342 3319 15
206.4596 -775 403 3318 71
206.4597 -221 301 3317 35
206.4598 -11 412 3316 78
206.4599 -941 672 3315 15
206.4600 -5 164 3314 21
206.4601 -975 249 3313 58
206.4602 -271 627 3312 13
206.4603 -213 725 3311 1
206.4604 -680 552 3310 84
206.4605 -938 438 3309 75
206.4606 -102 366 3308 19
206.4607 -888 569 3307 55
206.4608 -739 630 3306 20
206.4609 -508 933 3305 7
206.4610 -914 634 3304 93
206.4611 -621 448 3303 2
206.4612 -902 115 3302 70
206.4613 -172 169 3301 5
206.4614 -113 94 3300 53
206.4615 -72 557 3299 74
206.4616 -796 643 3298 83
206.4617 -939 344 3297 21
206.4618 -696 139 3296 14
206.4619 -298 134 3295 23
206.4620 -186 906 3294 59
206.4621 -332 325 3293 29
206.4622 -946 646 3292 71
206.4623 -74 524 3291 72
206.4624 -537 791 3290 5
206.4625 -913 904 3289 4
206.4626 -299 623 3288 27
206.4627 -204 64 3287 85
206.4628 -5 917 3286 24
206.4629 -228 637 3285 39
206.4630 -580 301 3284 11
206.4631 -679 573 3283 85
206.4632 -121 988 3282 38
206.4633 -732 670 3281 87
206.4634 -887 17 3280 53
206.4635 -281 765 3279 62
206.4636 -558 419 3278 61
206.4637 -147 613 3277 9
206.4638 -279 844 3276 19
206.4639 -336 285 3275 77
206.4640 -727 259 3274 64
206.4641 -584 467 3273 90
206.4642 -318 514 3272 55
206.4643 -653 334 3271 38
206.4644 -251 912 3270 84
206.4645 -346 9 3269 60
206.4646 -805 519 3268 72
206.4647 -769 896 3267 41
206.4648 -559 421 3266 86
206.4649 -26 129 3265 94
206.4650 -792 746 3264 60
206.4651 -953 343 3263 14
206.4652 -179 169 3262 26
206.4653 -422 543 3261 66
206.4654 -903 239 3260 40
206.4655 -489 882 3259 90
206.4656 -623 312 3258 54
206.4657 -474 542 3257 3
206.4658 -291 925 3256 21
206.4659 -383 334 3255 53
206.4660 -403 465 3254 23
206.4661 -173 876 3253 83
206.4662 -626 601 3252 77
206.4663 -303 263 3251 75
206.4664 -356 496 3250 51
206.4665 -570 364 3249 41
206.4666 -769 505 3248 86
206.4667 -617 825 3247 14
206.4668 -590 677 3246 18
206.4669 -869 299 3245 90
206.4670 -588 394 3244 98
206.4671 -275 65 3243 22
206.4672 -338 16 3242 54
206.4673 -767 238 3241 32
206.4674 -131 104 3240 94
206.4675 -859 547 3239 78
206.4676 -679 716 3238 80
206.4677 -147 965 3237 15
206.4678 -378 275 3236 2
206.4679 -904 927 3235 72
206.4680 -329 750 3234 28
206.4681 -48 682 3233 31
206.4682 -777 224 3232 93
206.4683 -133 376 3231 57
206.4684 -557 160 3230 63
206.4685 -831 985 3229 27
206.4686 -750 649 3228 17
206.4687 -690 124 3227 53
206.4688 -347 306 3226 76
206.4689 -177 439 3225 47
206.4690 -67 968 3224 57
206.4691 -458 376 3223 28
206.4692 -847 365 3222 27
206.4693 -216 935 3221 64
206.4694 -175 363 3220 57
206.4695 -335 92 3219 72
206.4696 -525 648 3218 8
206.4697 -818 762 3217 6
206.4698 -866 295 3216 34
206.4699 -471 899 3215 17
206.4700 -591 293 3214 10
206.4701 -11 10 3213 60
206.4702 -429 626 3212 61
206.4703 -572 67 3211 63
206.4704 -271 850 3210 4
206.4705 -443 645 3209 83
206.4706 -886 19 3208 81
206.4707 -466 717 3207 70
206.4708 -395 172 3206 95
206.4709 -605 60 3205 39
206.4710 -283 500 3204 87
206.4711 -383 998 3203 58
206.4712 -559 978 3202 58
206.4713 -216 590 3201 85
206.4714 -204 201 3200 30
206.4715 -626 29 3199 82
206.4716 -301 103 3198 55
206.4717 -545 755 3197 41
206.4718 -111 556 3196 7
206.4719 -559 515 3195 78
206.4720 -502 299 3194 32
206.4721 -19 997 3193 90
206.4722 -388 725 3192 82
206.4723 -389 555 3191 34
206.4724 -172 474 3190 1
206.4725 -925 269 3189 57
206.4726 -348 138 3188 32
206.4727 -198 348 3187 75
206.4728 -41 280 3186 43
206.4729 -215 467 3185 55
206.4730 -301 422 3184 5
206.4731 -272 75 3183 48
206.4732 -170 481 3182 63
206.4733 -81 330 3181 99
206.4734 -204 433 3180 21
206.4735 -131 254 3179 24
206.4736 -789 568 3178 57
206.4737 -67 322 3177 15
206.4738 -813 882 3176 15
206.4739 -45 494 3175 82
206.4740 -346 573 3174 91
206.4741 -594 852 3173 2
206.4742 -150 632 3172 10
206.4743 -897 781 3171 8
206.4744 -178 970 3170 87
206.4745 -685 670 3169 7
206.4746 -246 426 3168 34
206.4747 -439 993 3167 72
206.4748 -388 330 3166 25
206.4749 -920 913 3165 76
206.4750 -721 883 3164 69
206.4751 -219 928 3163 75
206.4752 -850 12 3162 44
206.4753 -810 212 3161 25
206.4754 -300 803 3160 71
206.4755 -243 731 3159 49
206.4756 -432 620 3158 43
206.4757 -663 467 3157 80
206.4758 -417 485 3156 5
206.4759 -29 70 3155 46
206.4760 -955 945 3154 19
206.4761 -915 309 3153 50
206.4762 -799 190 3152 36
206.4763 -409 533 3151 4
206.4764 -72 226 3150 51
206.4765 -110 53 3149 5
206.4766 -153 632 3148 81
206.4767 -981 755 3147 76
206.4768 -415 584 3146 24
206.4769 -124 268 3145 38
206.4770 -636 697 3144 7
206.4771 -118 132 3143 3
206.4772 -656 328 3142 11
206.4773 -307 529 3141 39
206.4774 -172 453 3140 33
206.4775 -420 245 3139 96
206.4776 -877 42 3138 95
206.4777 -171 522 3137 17
206.4778 -315 858 3136 56
206.4779 -571 312 3135 29
206.4780 -564 35 3134 48
206.4781 -803 922 3133 51
206.4782 -798 726 3132 46
206.4783 -76 53 3131 34
206.4784 -208 374 3130 13
206.4785 -203 5 3129 75
206.4786 -519 783 3128 54
206.4787 -663 607 3127 70
206.4788 -546 273 3126 85
206.4789 -277 804 3125 74
206.4790 -112 969 3124 0
206.4791 -196 55 3123 76
206.4792 -673 113 3122 0
206.4793 -678 213 3121 72
206.4794 -369 383 3120 86
206.4795 -221 208 3119 0
206.4796 -176 837 3118 68
206.4797 -334 850 3117 85
206.4798 -469 112 3116 11
206.4799 -834 736 3115 26
206.4800 -914 246 3114 16
206.4801 -942 755 3113 91
206.4802 -899 282 3112 52
206.4803 -829 854 3111 99
206.4804 -175 862 3110 30
206.4805 -371 321 3109 14
206.4806 -986 828 3108 4
206.4807 -738 737 3107 84
206.4808 -375 848 3106 86
206.4809 -489 104 3105 63
206.4810 -490 248 3104 92
206.4811 -473 393 3103 97
206.4812 -427 528 3102 4
206.4813 -992 685 3101 7
206.4814 -541 161 3100 65
206.4815 -492 102 3099 80
206.4816 -90 202 3098 38
206.4817 -889 976 3097 24
206.4818 -744 230 3096 36
206.4819 -856 714 3095 88
206.4820 -855 948 3094 99
206.4821 -864 929 3093 1
206.4822 -842 971 3092 4
206.4823 -524 416 3091 43
206.4824 -58 849 3090 45
206.4825 -899 420 3089 4
206.4826 -226 135 3088 40
206.4827 -746 886 3087 20
206.4828 -516 476 3086 14
206.4829 -765 887 3085 88
206.4830 -18 981 3084 0
206.4831 -958 971 3083 99
206.4832 -555 610 3082 2
206.4833 -566 984 3081 31
206.4834 -429 401 3080 46
206.4835 -284 646 3079 15
206.4836 -249 200 3078 67
206.4837 -410 56 3077 47
206.4838 -588 257 3076 22
206.4839 -906 886 3075 75
206.4840 -9 10 3074 74
206.4841 -360 968 3073 6
206.4842 -626 704 3072 40
206.4843 -582 851 3071 98
206.4844 -755 307 3070 13
206.4845 -445 484 3069 14
206.4846 -144 193 3068 3
206.4847 -798 250 3067 83
206.4848 -370 478 3066 82
206.4849 -876 3 3065 68
206.4850 -41 686 3064 89
206.4851 -264 658 3063 64
206.4852 -852 413 3062 73
206.4853 -543 851 3061 4
206.4854 -822 992 3060 82
206.4855 -291 110 3059 30
206.4856 -943 195 3058 30
206.4857 -771 17 3057 34
206.4858 -474 138 3056 42
206.4859 -317 786 3055 49
206.4860 -28 248 3054 83
206.4861 -244 913 3053 77
206.4862 -561 690 3052 41
206.4863 -859 216 3051 30
206.4864 -881 517 3050 72
206.4865 -915 8 3049 53
206.4866 -177 954 3048 34
206.4867 -879 917 3047 17
206.4868 -352 934 3046 29
206.4869 -537 659 3045 15
206.4870 -334 57 3044 28
206.4871 -222 366 3043 78
206.4872 -474 102 3042 68
206.4873 -698 588 3041 70
206.4874 -508 189 3040 97
206.4875 -53 183 3039 96
206.4876 -37 176 3038 73
206.4877 -982 874 3037 29
206.4878 -275 139 3036 52
206.4879 -602 869 3035 81
206.4880 -691 504 3034 20
206.4881 -263 100 3033 11
206.4882 -514 980 3032 74
206.4883 -398 725 3031 77
206.4884 -5 10 3030 19
206.4885 -7 228 3029 45
206.4886 -301 439 3028 1
206.4887 -734 771 3027 5
206.4888 -270 711 3026 70
206.4889 -364 611 3025 67
206.4890 -403 91 3024 91
206.4891 -120 363 3023 42
206.4892 -254 972 3022 74
206.4893 -714 585 3021 11
206.4894 -781 734 3020 39
206.4895 -788 439 3019 99
206.4896 -668 960 3018 70
206.4897 -59 348 3017 56
206.4898 -100 33 3016 46
206.4899 -519 762 3015 90
206.4900 -728 483 3014 96
206.4901 -390 678 3013 28
206.4902 -387 633 3012 86
206.4903 -850 722 3011 54
206.4904 -295 395 3010 93
206.4905 -478 291 3009 99
206.4906 -611 138 3008 12
206.4907 -315 103 3007 60
206.4908 -271 557 3006 95
206.4909 -278 945 3005 58
206.4910 -805 677 3004 79
206.4911 -44 418 3003 33
206.4912 -910 325 3002 0
206.4913 -327 607 3001 53
206.4914 -103 940 3000 55
206.4915 -153 872 2999 81
206.4916 -34 512 2998 86
206.4917 -546 648 2997 29
206.4918 -611 379 2996 4
206.4919 -268 788 2995 99
206.4920 -258 453 2994 47
206.4921 -92 334 2993 76
206.4922 -717 466 2992 13
206.4923 -667 981 2991 58
206.4924 -67 737 2990 22
206.4925 -359 950 2989 95
206.4926 -863 570 2988 11
206.4927 -269 252 2987 48
206.4928 -590 51 2986 93
206.4929 -335 519 2985 34
206.4930 -118 712 2984 0
206.4931 -868 626 2983 16
206.4932 -484 550 2982 37
206.4933 -244 360 2981 5
206.4934 -786 272 2980 59
206.4935 -380 832 2979 70
206.4936 -317 630 2978 49
206.4937 -200 553 2977 59
206.4938 -532 591 2976 67
206.4939 -807 333 2975 25
206.4940 -85 843 2974 21
206.4941 -76 790 2973 25
206.4942 -189 324 2972 38
206.4943 -88 451 2971 23
206.4944 -440 891 2970 45
206.4945 -201 212 2969 40
206.4946 -76 902 2968 6
206.4947 -962 915 2967 11
206.4948 -257 423 2966 66
206.4949 -489 38 2965 72
206.4950 -52 966 2964 72
206.4951 -466 866 2963 0
206.4952 -873 144 2962 88
206.4953 -560 781 2961 10
206.4954 -679 52 2960 64
206.4955 -310 342 2959 23
206.4956 -986 946 2958 12
206.4957 -491 448 2957 11
206.4958 -385 943 2956 70
206.4959 -72 3 2955 76
206.4960 -99 713 2954 43
206.4961 -722 120 2953 58
206.4962 -362 786 2952 59
206.4963 -729 452 2951 31
206.4964 -709 409 2950 88
206.4965 -396 112 2949 36
206.4966 -497 11 2948 32
206.4967 -505 408 2947 49
206.4968 -940 937 2946 10
206.4969 -289 331 2945 31
206.4970 -592 850 2944 97
206.4971 -334 993 2943 37
206.4972 -333 279 2942 35
206.4973 -43 432 2941 63
206.4974 -297 511 2940 1
206.4975 -101 45 2939 31
206.4976 -602 827 2938 89
206.4977 -471 390 2937 99
206.4978 -605 792 2936 56
206.4979 -480 340 2935 65
206.4980 -857 594 2934 69
206.4981 -713 17 2933 25
206.4982 -847 726 2932 0
206.4983 -920 613 2931 29
206.4984 -466 706 2930 74
206.4985 -218 413 2929 19
206.4986 -436 907 2928 49
206.4987 -598 427 2927 13
206.4988 -451 914 2926 86
206.4989 -746 954 2925 12
206.4990 -576 437 2924 62
206.4991 -291 257 2923 14
206.4992 -112 710 2922 86
206.4993 -906 544 2921 92
206.4994 -292 549 2920 45
206.4995 -506 697 2919 24
206.4996 -479 368 2918 78
206.4997 -513 264 2917 83
206.4998 -959 740 2916 14
206.4999 -516 501 2915 70
206.5000 -180 479 2914 16
206.5001 -547 278 2913 28
206.5002 -166 938 2912 17
206.5003 -994 472 2911 20
206.5004 -852 207 2910 61
206.5005 -329 465 2909 78
206.5006 -103 943 2908 2
206.5007 -524 691 2907 96
206.5008 -238 441 2906 55
206.5009 -22 535 2905 44
206.5010 -201 884 2904 33
206.5011 -339 106 2903 63
206.5012 -465 972 2902 38
206.5013 -265 591 2901 17
206.5014 -741 828 2900 14
206.5015 -522 758 2899 52
206.5016 -251 60 2898 22
206.5017 -250 413 2897 57
206.5018 -906 109 2896 28
206.5019 -651 107 2895 21
206.5020 -777 703 2894 82
206.5021 -134 251 2893 86
206.5022 -380 209 2892 87
206.5023 -763 29 2891 19
206.5024 -69 618 2890 52
206.5025 -698 297 2889 21
206.5026 -647 646 2888 27
206.5027 -303 294 2887 0
206.5028 -2 68 2886 34
206.5029 -404 396 2885 25
206.5030 -451 958 2884 87
206.5031 -42 987 2883 64
206.5032 -179 674 2882 75
206.5033 -411 675 2881 61
206.5034 -321 304 2880 69
206.5035 -650 948 2879 37
206.5036 -352 269 2878 5
206.5037 -225 656 2877 34
206.5038 -672 89 2876 30
206.5039 -437 380 2875 59
206.5040 -970 231 2874 95
206.5041 -313 888 2873 40
206.5042 -999 136 2872 86
206.5043 -370 922 2871 76
206.5044 -355 323 2870 9
206.5045 -679 319 2869 67
206.5046 -613 707 2868 29
206.5047 -566 43 2867 12
206.5048 -709 701 2866 55
206.5049 -148 646 2865 23
206.5050 -342 543 2864 46
206.5051 -751 546 2863 65
206.5052 -214 93 2862 31
206.5053 -598 678 2861 62
206.5054 -4 419 2860 1
206.5055 -612 372 2859 67
206.5056 -663 171 2858 6
206.5057 -341 573 2857 4
206.5058 -55 318 2856 85
206.5059 -102 767 2855 56
206.5060 -996 809 2854 80
206.5061 -453 343 2853 59
206.5062 -415 686 2852 53
206.5063 -258 612 2851 61
206.5064 -47 338 2850 59
206.5065 -200 610 2849 39
206.5066 -598 19 2848 94
206.5067 -254 188 2847 32
206.5068 -550 296 2846 28
206.5069 -958 754 2845 95
206.5070 -466 214 2844 10
206.5071 -657 53 2843 54
206.5072 -73 921 2842 3
206.5073 -274 22 2841 15
206.5074 -728 201 2840 21
206.5075 -590 444 2839 84
206.5076 -831 626 2838 60
206.5077 -891 35 2837 34
206.5078 -541 333 2836 70
206.5079 -540 846 2835 59
206.5080 -160 563 2834 49
206.5081 -132 505 2833 80
206.5082 -899 881 2832 58
206.5083 -820 945 2831 79
206.5084 -757 363 2830 54
206.5085 -817 245 2829 13
206.5086 -590 258 2828 75
206.5087 -702 639 2827 93
206.5088 -486 111 2826 34
206.5089 -283 99 2825 0
206.5090 -57 683 2824 37
206.5091 -623 224 2823 2
206.5092 -936 785 2822 23
206.5093 -581 253 2821 7
206.5094 -118 407 2820 6
206.5095 -986 378 2819 93
206.5096 -618 819 2818 22
206.5097 -528 589 2817 88
206.5098 -12 348 2816 21
206.5099 -416 621 2815 20
206.5100 -458 351 2814 22
206.5101 -439 794 2813 43
206.5102 -532 154 2812 68
206.5103 -845 15 2811 35
206.5104 -29 123 2810 46
206.5105 -559 712 2809 13
206.5106 -229 339 2808 36
206.5107 -241 671 2807 9
206.5108 -726 13 2806 51
206.5109 -270 977 2805 59
206.5110 -557 791 2804 95
206.5111 -639 746 2803 1
206.5112 -139 332 2802 90
206.5113 -892 891 2801 68
206.5114 -410 331 2800 81
206.5115 -372 763 2799 47
206.5116 -668 278 2798 32
206.5117 -658 574 2797 98
206.5118 -35 920 2796 51
206.5119 -185 638 2795 45
206.5120 -44 938 2794 71
206.5121 -413 111 2793 91
206.5122 -441 220 2792 50
206.5123 -559 871 2791 24
206.5124 -568 345 2790 48
206.5125 -484 141 2789 3
206.5126 -703 340 2788 70
206.5127 -654 473 2787 0
206.5128 -281 59 2786 62
206.5129 -700 743 2785 85
206.5130 -826 793 2784 14
206.5131 -891 418 2783 63
206.5132 -349 253 2782 97
206.5133 -525 764 2781 88
206.5134 -204 443 2780 99
206.5135 -800 333 2779 8
206.5136 -867 694 2778 78
206.5137 -414 387 2777 4
206.5138 -315 772 2776 37
206.5139 -949 708 2775 58
206.5140 -375 510 2774 87
206.5141 -164 658 2773 93
206.5142 -489 89 2772 54
206.5143 -320 892 2771 82
206.5144 -110 906 2770 32
206.5145 -639 302 2769 40
206.5146 -307 731 2768 93
206.5147 -615 677 2767 45
206.5148 -63 792 2766 9
206.5149 -198 706 2765 36
206.5150 -852 939 2764 57
206.5151 -568 393 2763 21
206.5152 -197 718 2762 67
206.5153 -985 502 2761 16
206.5154 -603 917 2760 21
206.5155 -571 470 2759 47
206.5156 -54 479 2758 33
206.5157 -885 354 2757 69
206.5158 -85 733 2756 55
206.5159 -767 791 2755 86
206.5160 -545 363 2754 34
206.5161 -674 535 2753 28
206.5162 -215 505 2752 37
206.5163 -585 959 2751 21
206.5164 -446 739 2750 38
206.5165 -990 138 2749 3
206.5166 -125 639 2748 51
206.5167 -620 140 2747 16
206.5168 -942 686 2746 79
206.5169 -427 518 2745 31
206.5170 -828 62 2744 22
206.5171 -29 912 2743 87
206.5172 -546 159 2742 45
206.5173 -219 830 2741 63
206.5174 -600 350 2740 13
206.5175 -498 514 2739 45
206.5176 -499 348 2738 86
206.5177 -453 369 2737 50
206.5178 -167 481 2736 67
206.5179 -456 96 2735 51
206.5180 -150 350 2734 59
206.5181 -753 412 2733 79
206.5182 -328 828 2732 48
206.5183 -480 492 2731 32
206.5184 -835 682 2730 61
206.5185 -165 590 2729 10
206.5186 -979 360 2728 99
206.5187 -887 826 2727 4
206.5188 -384 163 2726 28
206.5189 -746 915 2725 71
206.5190 -937 801 2724 30
206.5191 -584 314 2723 39
206.5192 -336 156 2722 42
206.5193 -809 708 2721 84
206.5194 -91 516 2720 64
206.5195 -230 102 2719 67
206.5196 -534 954 2718 18
206.5197 -662 758 2717 9
206.5198 -247 574 2716 50
206.5199 -114 405 2715 63
206.5200 -486 908 2714 80
206.5201 -158 972 2713 35
206.5202 -447 575 2712 24
206.5203 -191 204 2711 52
206.5204 -414 973 2710 71
206.5205 -147 483 2709 86
206.5206 -195 95 2708 69
206.5207 -184 588 2707 87
206.5208 -169 864 2706 41
206.5209 -496 830 2705 13
206.5210 -935 454 2704 62
206.5211 -397 105 2703 32
206.5212 -370 721 2702 71
206.5213 -230 809 2701 25
206.5214 -490 856 2700 77
206.5215 -388 165 2699 26
206.5216 -507 824 2698 95
206.5217 -723 457 2697 1
206.5218 -34 281 2696 1
206.5219 -375 504 2695 67
206.5220 -348 300 2694 56
206.5221 -384 617 2693 53
206.5222 -912 454 2692 2
206.5223 -953 478 2691 14
206.5224 -690 510 2690 74
206.5225 -341 314 2689 10
206.5226 -366 940 2688 88
206.5227 -176 996 2687 78
206.5228 -776 342 2686 68
206.5229 -203 111 2685 65
206.5230 -683 22 2684 2
206.5231 -162 512 2683 96
206.5232 -975 886 2682 47
206.5233 -968 399 2681 95
206.5234 -196 639 2680 26
206.5235 -373 220 2679 34
206.5236 -943 98 2678 97
206.5237 -654 93 2677 19
206.5238 -230 31 2676 39
206.5239 -89 631 2675 57
206.5240 -510 63 2674 51
206.5241 -625 491 2673 52
206.5242 -487 513 2672 18
206.5243 -760 696 2671 0
206.5244 -419 912 2670 77
206.5245 -122 375 2669 82
206.5246 -4 783 2668 42
206.5247 -62 791 2667 28
206.5248 -400 826 2666 42
206.5249 -567 53 2665 14
206.5250 -571 998 2664 57
206.5251 -978 334 2663 88
206.5252 -816 178 2662 13
206.5253 -783 235 2661 72
206.5254 -537 949 2660 34
206.5255 -591 392 2659 29
206.5256 -992 140 2658 11
206.5257 -964 864 2657 94
206.5258 -773 283 2656 66
206.5259 -54 561 2655 83
206.5260 -663 694 2654 99
206.5261 -156 745 2653 59
206.5262 -943 411 2652 16
206.5263 -285 386 2651 3
206.5264 -557 43 2650 24
206.5265 -251 179 2649 94
206.5266 -276 176 2648 59
206.5267 -581 279 2647 2
206.5268 -721 829 2646 19
206.5269 -866 836 2645 71
206.5270 -949 402 2644 39
206.5271 -334 431 2643 50
206.5272 -25 128 2642 21
206.5273 -342 786 2641 65
206.5274 -864 299 2640 72
206.5275 -3 348 2639 30
206.5276 -896 570 2638 97
206.5277 -449 836 2637 69
206.5278 -993 472 2636 85
206.5279 -434 327 2635 85
206.5280 -970 883 2634 91
206.5281 -302 294 2633 61
206.5282 -342 555 2632 30
206.5283 -487 928 2631 68
206.5284 -951 423 2630 47
206.5285 -777 329 2629 86
206.5286 -733 280 2628 10
206.5287 -364 835 2627 44
206.5288 -144 3 2626 45
206.5289 -444 937 2625 55
206.5290 -588 303 2624 46
206.5291 -739 305 2623 66
206.5292 -626 626 2622 96
206.5293 -505 204 2621 85
206.5294 -93 617 2620 53
206.5295 -48 754 2619 17
206.5296 -445 659 2618 4
206.5297 -831 990 2617 36
206.5298 -66 897 2616 22
206.5299 -634 95 2615 69
206.5300 -997 795 2614 85
206.5301 -678 707 2613 84
206.5302 -422 106 2612 11
206.5303 -586 318 2611 12
206.5304 -862 361 2610 41
206.5305 -95 129 2609 4
206.5306 -668 675 2608 60
206.5307 -93 148 2607 61
206.5308 -801 520 2606 76
206.5309 -300 844 2605 43
206.5310 -87 6 2604 63
206.5311 -601 735 2603 31
206.5312 -787 992 2602 25
206.5313 -956 709 2601 83
206.5314 -232 366 2600 72
206.5315 -454 441 2599 76
206.5316 -526 990 2598 42
206.5317 -628 848 2597 57
206.5318 -676 333 2596 29
206.5319 -837 795 2595 50
206.5320 -270 317 2594 21
206.5321 -743 62 2593 48
206.5322 -283 420 2592 81
206.5323 -342 111 2591 83
206.5324 -925 957 2590 72
206.5325 -451 339 2589 77
206.5326 -142 852 2588 92
206.5327 -514 282 2587 89
206.5328 -538 791 2586 95
206.5329 -477 287 2585 83
206.5330 -255 726 2584 56
206.5331 -642 672 2583 52
206.5332 -309 983 2582 45
206.5333 -153 105 2581 94
206.5334 -617 946 2580 41
206.5335 -487 850 2579 47
206.5336 -569 29 2578 30
206.5337 -490 945 2577 62
206.5338 -504 114 2576 97
206.5339 -561 271 2575 6
206.5340 -54 39 2574 22
206.5341 -688 67 2573 61
206.5342 -877 518 2572 33
206.5343 -159 524 2571 15
206.5344 -96 942 2570 53
206.5345 -820 165 2569 13
206.5346 -84 681 2568 91
206.5347 -831 651 2567 7
206.5348 -842 915 2566 98
206.5349 -231 839 2565 94
206.5350 -972 609 2564 50
206.5351 -548 279 2563 36
206.5352 -994 177 2562 81
206.5353 -581 619 2561 71
206.5354 -777 405 2560 6
206.5355 -483 213 2559 27
206.5356 -30 838 2558 73
206.5357 -736 91 2557 25
206.5358 -75 44 2556 98
206.5359 -229 435 2555 61
206.5360 -329 141 2554 25
206.5361 -101 554 2553 42
206.5362 -558 91 2552 55
206.5363 -213 656 2551 41
206.5364 -191 786 2550 80
206.5365 -375 540 2549 29
206.5366 -746 483 2548 45
206.5367 -47 263 2547 29
206.5368 -608 378 2546 66
206.5369 -294 351 2545 84
206.5370 -587 835 2544 90
206.5371 -462 869 2543 22
206.5372 -435 141 2542 54
206.5373 -870 609 2541 34
206.5374 -246 509 2540 2
206.5375 -56 841 2539 81
206.5376 -219 158 2538 62
206.5377 -885 634 2537 69
206.5378 -26 814 2536 43
206.5379 -515 945 2535 31
206.5380 -966 672 2534 70
206.5381 -728 685 2533 12
206.5382 -531 198 2532 2
206.5383 -100 322 2531 56
206.5384 -667 206 2530 62
206.5385 -682 186 2529 18
206.5386 -523 931 2528 83
206.5387 -820 258 2527 33
206.5388 -868 125 2526 85
206.5389 -273 607 2525 51
206.5390 -987 582 2524 54
206.5391 -486 96 2523 23
206.5392 -876 462 2522 19
206.5393 -115 941 2521 43
206.5394 -20 434 2520 43
206.5395 -254 352 2519 98
206.5396 -672 502 2518 15
206.5397 -133 475 2517 70
206.5398 -518 347 2516 95
206.5399 -24 961 2515 59
206.5400 -486 312 2514 28
206.5401 -634 40 2513 50
206.5402 -521 765 2512 61
206.5403 -506 999 2511 76
206.5404 -81 447 2510 9
206.5405 -850 826 2509 76
206.5406 -26 455 2508 58
206.5407 -127 751 2507 53
206.5408 -386 357 2506 61
206.5409 -649 308 2505 49
206.5410 -272 785 2504 53
206.5411 -274 889 2503 85
206.5412 -766 849 2502 11
206.5413 -552 666 2501 1
206.5414 -621 328 2500 42
206.5415 -370 184 2499 23
206.5416 -703 41 2498 82
206.5417 -394 925 2497 89
206.5418 -48 120 2496 74
206.5419 -522 956 2495 73
206.5420 -896 685 2494 37
206.5421 -39 738 2493 99
206.5422 -183 98 2492 50
206.5423 -338 589 2491 21
206.5424 -143 194 2490 93
206.5425 -143 407 2489 25
206.5426 -116 925 2488 66
206.5427 -804 157 2487 30
206.5428 -164 4 2486 34
206.5429 -270 359 2485 52
206.5430 -946 379 2484 62
206.5431 -640 488 2483 85
206.5432 -509 294 2482 85
206.5433 -395 282 2481 84
206.5434 -786 681 2480 19
206.5435 -482 583 2479 0
206.5436 -767 357 2478 2
206.5437 -152 963 2477 31
206.5438 -645 818 2476 64
206.5439 -979 900 2475 89
206.5440 -890 769 2474 32
206.5441 -194 0 2473 30
206.5442 -12 11 2472 13
206.5443 -601 650 2471 11
206.5444 -97 195 2470 60
206.5445 -225 973 2469 30
206.5446 -393 714 2468 71
206.5447 -145 672 2467 61
206.5448 -918 746 2466 50
206.5449 -130 570 2465 66
206.5450 -769 16 2464 8
206.5451 -989 176 2463 69
206.5452 -361 16 2462 18
206.5453 -454 505 2461 41
206.5454 -221 303 2460 50
206.5455 -259 590 2459 87
206.5456 -42 98 2458 83
206.5457 -926 108 2457 24
206.5458 -175 841 2456 22
206.5459 -553 576 2455 78
206.5460 -840 392 2454 36
206.5461 -159 515 2453 78
206.5462 -511 770 2452 62
206.5463 -202 907 2451 90
206.5464 -712 631 2450 23
206.5465 -492 40 2449 96
206.5466 -989 583 2448 21
206.5467 -267 21 2447 11
206.5468 -265 439 2446 75
206.5469 -184 425 2445 62
206.5470 -876 581 2444 71
206.5471 -744 152 2443 68
206.5472 -863 721 2442 64
206.5473 -276 672 2441 30
206.5474 -590 271 2440 48
206.5475 -457 745 2439 22
206.5476 -561 100 2438 50
206.5477 -581 365 2437 72
206.5478 -14 128 2436 0
206.5479 -844 908 2435 8
206.5480 -429 31 2434 30
206.5481 -430 33 2433 13
206.5482 -49 339 2432 88
206.5483 -401 819 2431 58
206.5484 -525 269 2430 68
206.5485 -644 717 2429 13
206.5486 -735 780 2428 89
206.5487 -237 720 2427 98
206.5488 -219 919 2426 56
206.5489 -876 774 2425 16
206.5490 -998 174 2424 41
206.5491 -693 251 2423 99
206.5492 -520 293 2422 38
206.5493 -550 901 2421 64
206.5494 -551 551 2420 87
206.5495 -936 238 2419 88
206.5496 -59 914 2418 90
206.5497 -801 412 2417 49
206.5498 -145 397 2416 1
206.5499 -599 754 2415 34
206.5500 -922 416 2414 87
206.5501 -957 617 2413 30
206.5502 -391 733 2412 17
206.5503 -350 772 2411 96
206.5504 -313 994 2410 99
206.5505 -323 972 2409 61
206.5506 -502 411 2408 87
206.5507 -15 480 2407 25
206.5508 -642 674 2406 65
206.5509 -338 465 2405 54
206.5510 -798 572 2404 67
206.5511 -884 131 2403 96
206.5512 -961 203 2402 56
206.5513 -777 971 2401 4
206.5514 -21 383 2400 3
206.5515 -560 737 2399 98
206.5516 -931 618 2398 82
206.5517 -805 602 2397 48
206.5518 -209 110 2396 37
206.5519 -892 868 2395 30
206.5520 -440 711 2394 53
206.5521 -928 399 2393 91
206.5522 -231 524 2392 92
206.5523 -588 4 2391 18
206.5524 -645 47 2390 75
206.5525 -118 168 2389 46
206.5526 -15 334 2388 62
206.5527 -492 114 2387 12
206.5528 -241 67 2386 59
206.5529 -156 765 2385 31
206.5530 -312 625 2384 45
206.5531 -875 990 2383 51
206.5532 -519 740 2382 69
206.5533 -956 427 2381 64
206.5534 -879 294 2380 94
206.5535 -833 831 2379 52
206.5536 -219 504 2378 10
206.5537 -47 529 2377 52
206.5538 -302 278 2376 25
206.5539 -139 865 2375 8
206.5540 -634 938 2374 84
206.5541 -250 816 2373 43
206.5542 -312 53 2372 35
206.5543 -132 699 2371 56
206.5544 -463 416 2370 7
206.5545 -327 423 2369 4
206.5546 -974 579 2368 61
206.5547 -250 271 2367 17
206.5548 -413 166 2366 74
206.5549 -926 239 2365 16
206.5550 -122 408 2364 50
206.5551 -763 81 2363 38
206.5552 -353 792 2362 93
206.5553 -282 485 2361 18
206.5554 -993 32 2360 66
206.5555 -843 431 2359 13
206.5556 -308 441 2358 35
206.5557 -105 427 2357 72
206.5558 -926 581 2356 83
206.5559 -831 658 2355 48
206.5560 -326 120 2354 80
206.5561 -289 446 2353 35
206.5562 -306 757 2352 41
206.5563 -453 511 2351 7
206.5564 -601 532 2350 28
206.5565 -989 784 2349 15
206.5566 -13 628 2348 53
206.5567 -846 887 2347 20
206.5568 -923 350 2346 17
206.5569 -538 681 2345 9
206.5570 -673 445 2344 50
206.5571 -688 948 2343 3
206.5572 -246 339 2342 98
206.5573 -978 780 2341 85
206.5574 -748 139 2340 85
206.5575 -155 614 2339 61
206.5576 -741 332 2338 97
206.5577 -536 24 2337 16
206.5578 -668 83 2336 92
206.5579 -235 589 2335 38
206.5580 -497 467 2334 86
206.5581 -609 54 2333 98
206.5582 -558 129 2332 44
206.5583 -641 1 2331 26
206.5584 -524 240 2330 22
206.5585 -282 635 2329 59
206.5586 -308 808 2328 41
206.5587 -940 244 2327 20
206.5588 -493 538 2326 86
206.5589 -122 520 2325 43
206.5590 -412 878 2324 73
206.5591 -925 544 2323 88
206.5592 -127 173 2322 5
206.5593 -760 38 2321 91
206.5594 -605 637 2320 11
206.5595 -826 178 2319 24
206.5596 -564 210 2318 97
206.5597 -705 336 2317 36
206.5598 -18 435 2316 44
206.5599 -641 693 2315 37
206.5600 -334 850 2314 71
206.5601 -370 837 2313 48
206.5602 -134 133 2312 79
206.5603 -401 800 2311 36
206.5604 -459 874 2310 15
206.5605 -967 268 2309 77
206.5606 -873 605 2308 26
206.5607 -901 921 2307 85
206.5608 -741 75 2306 68
206.5609 -843 661 2305 37
206.5610 -13 223 2304 30
206.5611 -704 688 2303 96
206.5612 -333 431 2302 23
206.5613 -925 211 2301 73
206.5614 -606 375 2300 94
206.5615 -662 518 2299 49
206.5616 -684 401 2298 9
206.5617 -846 172 2297 97
206.5618 -414 310 2296 16
206.5619 -437 70 2295 89
206.5620 -535 343 2294 83
206.5621 -257 727 2293 30
206.5622 -219 502 2292 37
206.5623 -836 791 2291 40
206.5624 -857 451 2290 31
206.5625 -116 396 2289 94
206.5626 -229 122 2288 97
206.5627 -861 812 2287 83
206.5628 -240 262 2286 43
206.5629 -726 67 2285 97
206.5630 -615 521 2284 90
206.5631 -224 937 2283 27
206.5632 -711 962 2282 3
206.5633 -340 89 2281 38
206.5634 -54 374 2280 97
206.5635 -274 965 2279 74
206.5636 -309 140 2278 88
206.5637 -549 405 2277 36
206.5638 -194 455 2276 62
206.5639 -546 74 2275 51
206.5640 -583 624 2274 11
206.5641 -975 239 2273 39
206.5642 -873 655 2272 51
206.5643 -714 403 2271 37
206.5644 -409 238 2270 28
206.5645 -824 854 2269 77
206.5646 -735 519 2268 96
206.5647 -949 745 2267 76
206.5648 -381 108 2266 35
206.5649 -449 402 2265 64
206.5650 -384 720 2264 96
206.5651 -584 877 2263 60
206.5652 -251 142 2262 10
206.5653 -165 84 2261 15
206.5654 -384 506 2260 30
206.5655 -334 814 2259 58
206.5656 -773 204 2258 8
206.5657 -637 404 2257 78
206.5658 -706 706 2256 56
206.5659 -681 685 2255 93
206.5660 -842 353 2254 6
206.5661 -734 507 2253 80
206.5662 -57 942 2252 33
206.5663 -578 854 2251 8
206.5664 -692 720 2250 78
206.5665 -609 494 2249 4
206.5666 -799 304 2248 56
206.5667 -697 217 2247 13
206.5668 -20 635 2246 93
206.5669 -331 867 2245 2
206.5670 -846 264 2244 83
206.5671 -564 467 2243 10
206.5672 -87 247 2242 67
206.5673 -134 303 2241 47
206.5674 -225 732 2240 88
206.5675 -190 487 2239 8
206.5676 -86 425 2238 80
206.5677 -581 205 2237 10
206.5678 -768 906 2236 67
206.5679 -602 185 2235 68
206.5680 -797 730 2234 48
206.5681 -219 430 2233 28
206.5682 -943 197 2232 47
206.5683 -571 593 2231 95
206.5684 -244 803 2230 90
206.5685 -62 272 2229 3
206.5686 -220 707 2228 10
206.5687 -299 424 2227 50
206.5688 -720 987 2226 81
206.5689 -454 203 2225 16
206.5690 -300 203 2224 80
206.5691 -233 804 2223 57
206.5692 -604 523 2222 27
206.5693 -790 44 2221 37
206.5694 -530 873 2220 32
206.5695 -564 932 2219 18
206.5696 -283 597 2218 84
206.5697 -436 692 2217 92
206.5698 -784 646 2216 57
206.5699 -0 360 2215 26
206.5700 -398 227 2214 15
206.5701 -280 301 2213 6
206.5702 -479 903 2212 62
206.5703 -171 46 2211 81
206.5704 -940 143 2210 25
206.5705 -334 340 2209 96
206.5706 -905 921 2208 28
206.5707 -46 341 2207 84
206.5708 -285 313 2206 65
206.5709 -133 111 2205 78
206.5710 -926 87 2204 60
206.5711 -397 438 2203 11
206.5712 -857 814 2202 80
206.5713 -902 554 2201 30
206.5714 -802 294 2200 23
206.5715 -419 684 2199 60
206.5716 -579 435 2198 42
206.5717 -28 193 2197 85
206.5718 -201 869 2196 76
206.5719 -24 181 2195 15
206.5720 -649 483 2194 20
206.5721 -623 316 2193 52
206.5722 -260 493 2192 54
206.5723 -259 77 2191 95
206.5724 -610 623 2190 10
206.5725 -248 177 2189 38
206.5726 -242 570 2188 83
206.5727 -324 97 2187 55
206.5728 -687 608 2186 82
206.5729 -698 945 2185 17
206.5730 -166 678 2184 37
206.5731 -823 988 2183 2
206.5732 -416 585 2182 36
206.5733 -453 854 2181 0
206.5734 -446 717 2180 64
206.5735 -606 543 2179 36
206.5736 -472 288 2178 0
206.5737 -489 724 2177 91
206.5738 -662 649 2176 63
206.5739 -267 802 2175 98
206.5740 -689 349 2174 53
206.5741 -402 663 2173 34
206.5742 -731 361 2172 40
206.5743 -137 351 2171 96
206.5744 -174 288 2170 0
206.5745 -254 355 2169 84
206.5746 -564 87 2168 13
206.5747 -74 281 2167 98
206.5748 -846 647 2166 82
206.5749 -453 457 2165 39
206.5750 -685 188 2164 57
206.5751 -302 936 2163 28
206.5752 -10 444 2162 67
206.5753 -62 956 2161 59
206.5754 -932 166 2160 96
206.5755 -267 706 2159 91
206.5756 -806 150 2158 68
206.5757 -634 156 2157 48
206.5758 -190 432 2156 22
206.5759 -268 817 2155 39
206.5760 -252 290 2154 76
206.5761 -491 615 2153 38
206.5762 -487 77 2152 29
206.5763 -789 630 2151 94
206.5764 -459 43 2150 13
206.5765 -556 229 2149 66
206.5766 -993 200 2148 46
206.5767 -724 261 2147 17
206.5768 -615 835 2146 44
206.5769 -526 625 2145 92
206.5770 -674 384 2144 1
206.5771 -537 91 2143 76
206.5772 -447 344 2142 0
206.5773 -586 817 2141 69
206.5774 -813 464 2140 32
206.5775 -29 203 2139 90
206.5776 -939 289 2138 56
206.5777 -425 728 2137 26
206.5778 -209 522 2136 10
206.5779 -240 904 2135 8
206.5780 -293 256 2134 85
206.5781 -746 756 2133 13
206.5782 -527 305 2132 9
206.5783 -352 368 2131 86
206.5784 -261 426 2130 77
206.5785 -914 341 2129 78
206.5786 -561 292 2128 9
206.5787 -205 160 2127 51
206.5788 -617 20 2126 21
206.5789 -648 236 2125 96
206.5790 -499 714 2124 94
206.5791 -450 47 2123 54
206.5792 -937 229 2122 21
206.5793 -941 87 2121 17
206.5794 -85 988 2120 9
206.5795 -48 693 2119 34
206.5796 -132 577 2118 35
206.5797 -139 297 2117 35
206.5798 -783 246 2116 58
206.5799 -522 21 2115 96
206.5800 -667 401 2114 14
206.5801 -817 328 2113 4
206.5802 -141 42 2112 51
206.5803 -99 84 2111 99
206.5804 -295 744 2110 85
206.5805 -116 993 2109 3
206.5806 -280 997 2108 91
206.5807 -50 767 2107 99
206.5808 -225 619 2106 35
206.5809 -620 820 2105 26
206.5810 -72 99 2104 85
206.5811 -285 536 2103 84
206.5812 -958 517 2102 67
206.5813 -340 139 2101 4
206.5814 -750 820 2100 80
206.5815 -996 120 2099 17
206.5816 -229 923 2098 83
206.5817 -148 636 2097 23
206.5818 -798 94 2096 82
206.5819 -721 406 2095 60
206.5820 -562 5 2094 54
206.5821 -19 173 2093 78
206.5822 -377 634 2092 32
206.5823 -319 238 2091 61
206.5824 -699 624 2090 58
206.5825 -196 343 2089 75
206.5826 -286 605 2088 76
206.5827 -542 405 2087 8
206.5828 -687 218 2086 34
206.5829 -401 58 2085 7
206.5830 -831 759 2084 15
206.5831 -538 460 2083 54
206.5832 -396 708 2082 64
206.5833 -613 28 2081 5
206.5834 -281 836 2080 61
206.5835 -737 987 2079 50
206.5836 -199 685 2078 90
206.5837 -186 731 2077 74
206.5838 -160 272 2076 85
206.5839 -298 919 2075 28
206.5840 -299 615 2074 56
206.5841 -751 901 2073 29
206.5842 -680 582 2072 14
206.5843 -192 439 2071 78
206.5844 -849 116 2070 33
206.5845 -301 593 2069 54
206.5846 -953 165 2068 53
206.5847 -459 889 2067 1
206.5848 -353 569 2066 2
206.5849 -303 715 2065 86
206.5850 -714 276 2064 99
206.5851 -318 150 2063 54
206.5852 -143 359 2062 7
206.5853 -323 450 2061 48
206.5854 -522 787 2060 34
206.5855 -428 6 2059 54
206.5856 -275 524 2058 34
206.5857 -319 986 2057 49
206.5858 -853 164 2056 10
206.5859 -438 863 2055 4
206.5860 -126 451 2054 58
206.5861 -790 476 2053 39
206.5862 -908 583 2052 17
206.5863 -662 145 2051 82
206.5864 -781 796 2050 80
206.5865 -481 198 2049 9
206.5866 -538 854 2048 15
206.5867 -822 387 2047 95
206.5868 -301 56 2046 46
206.5869 -411 460 2045 41
206.5870 -975 193 2044 31
206.5871 -893 221 2043 33
206.5872 -437 354 2042 88
206.5873 -349 19 2041 24
206.5874 -597 705 2040 88
206.5875 -343 942 2039 30
206.5876 -466 196 2038 94
206.5877 -330 489 2037 71
206.5878 -596 51 2036 52
206.5879 -266 101 2035 88
206.5880 -972 977 2034 43
206.5881 -866 453 2033 8
206.5882 -334 635 2032 45
206.5883 -314 365 2031 8
206.5884 -762 580 2030 75
206.5885 -746 356 2029 25
206.5886 -706 227 2028 87
206.5887 -438 195 2027 13
206.5888 -949 631 2026 73
206.5889 -124 453 2025 33
206.5890 -524 353 2024 29
206.5891 -817 626 2023 10
206.5892 -270 367 2022 53
206.5893 -784 336 2021 2
206.5894 -224 498 2020 55
206.5895 -129 376 2019 1
206.5896 -32 740 2018 4
206.5897 -563 402 2017 26
206.5898 -178 403 2016 48
206.5899 -99 35 2015 82
206.5900 -727 188 2014 59
206.5901 -259 573 2013 70
206.5902 -30 511 2012 54
206.5903 -838 469 2011 48
206.5904 -121 535 2010 55
206.5905 -635 975 2009 9
206.5906 -338 773 2008 9
206.5907 -998 777 2007 46
206.5908 -367 664 2006 38
206.5909 -847 225 2005 7
206.5910 -614 892 2004 37
206.5911 -62 160 2003 46
206.5912 -42 60 2002 22
206.5913 -934 926 2001 19
206.5914 -559 465 2000 71
206.5915 -202 997 1999 48
206.5916 -995 629 1998 29
206.5917 -113 82 1997 34
206.5918 -438 306 1996 63
206.5919 -333 707 1995 52
206.5920 -731 904 1994 23
206.5921 -99 238 1993 55
206.5922 -133 36 1992 1
206.5923 -461 476 1991 10
206.5924 -467 230 1990 37
206.5925 -368 188 1989 35
206.5926 -546 957 1988 20
206.5927 -776 709 1987 88
206.5928 -599 110 1986 67
206.5929 -802 287 1985 10
206.5930 -666 679 1984 60
206.5931 -201 533 1983 63
206.5932 -560 910 1982 96
206.5933 -245 733 1981 67
206.5934 -42 17 1980 99
206.5935 -231 150 1979 9
206.5936 -247 324 1978 82
206.5937 -599 207 1977 77
206.5938 -822 569 1976 17
206.5939 -607 503 1975 79
206.5940 -146 969 1974 13
206.5941 -622 666 1973 46
206.5942 -177 293 1972 64
206.5943 -715 678 1971 31
206.5944 -867 894 1970 20
206.5945 -825 277 1969 81
206.5946 -117 51 1968 98
206.5947 -637 593 1967 64
206.5948 -66 379 1966 77
206.5949 -533 661 1965 21
206.5950 -303 670 1964 46
206.5951 -372 823 1963 52
206.5952 -615 326 1962 44
206.5953 -783 111 1961 46
206.5954 -617 392 1960 84
206.5955 -225 827 1959 4
206.5956 -458 335 1958 70
206.5957 -213 870 1957 48
206.5958 -718 562 1956 57
206.5959 -990 753 1955 53
206.5960 -847 937 1954 23
206.5961 -497 79 1953 93
206.5962 -214 983 1952 75
206.5963 -718 613 1951 83
206.5964 -564 805 1950 16
206.5965 -492 335 1949 39
206.5966 -464 227 1948 76
206.5967 -308 909 1947 24
206.5968 -809 38 1946 49
206.5969 -816 302 1945 72
206.5970 -858 298 1944 14
206.5971 -95 173 1943 35
206.5972 -370 925 1942 28
206.5973 -807 665 1941 49
206.5974 -470 773 1940 15
206.5975 -108 625 1939 7
206.5976 -317 521 1938 2
206.5977 -871 750 1937 15
206.5978 -735 766 1936 49
206.5979 -3 585 1935 99
206.5980 -124 792 1934 95
206.5981 -248 68 1933 76
206.5982 -259 786 1932 72
206.5983 -891 342 1931 56
206.5984 -148 81 1930 33
206.5985 -104 44 1929 36
206.5986 -770 871 1928 79
206.5987 -984 657 1927 44
206.5988 -181 504 1926 13
206.5989 -792 35 1925 73
206.5990 -724 195 1924 87
206.5991 -281 38 1923 87
206.5992 -444 161 1922 98
206.5993 -260 225 1921 36
206.5994 -36 974 1920 74
206.5995 -172 571 1919 4
206.5996 -214 344 1918 33
206.5997 -153 310 1917 78
206.5998 -468 403 1916 80
206.5999 -840 853 1915 38
206.6000 -156 2 1914 6
206.6001 -876 887 1913 44
206.6002 -935 620 1912 83
206.6003 -250 624 1911 18
206.6004 -403 699 1910 22
206.6005 -227 709 1909 86
206.6006 -33 548 1908 95
206.6007 -907 982 1907 6
206.6008 -550 413 1906 68
206.6009 -850 321 1905 62
206.6010 -114 624 1904 68
206.6011 -267 605 1903 27
206.6012 -996 654 1902 94
206.6013 -924 959 1901 68
206.6014 -990 360 1900 84
206.6015 -161 905 1899 17
206.6016 -565 897 1898 19
206.6017 -568 376 1897 12
206.6018 -92 56 1896 35
206.6019 -697 943 1895 69
206.6020 -19 404 1894 73
206.6021 -950 338 1893 84
206.6022 -695 256 1892 27
206.6023 -598 837 1891 7
206.6024 -454 672 1890 93
206.6025 -7 980 1889 82
206.6026 -520 68 1888 59
206.6027 -320 769 1887 99
206.6028 -112 657 1886 47
206.6029 -539 962 1885 39
206.6030 -65 889 1884 67
206.6031 -82 577 1883 6
206.6032 -418 197 1882 25
206.6033 -164 138 1881 9
206.6034 -691 104 1880 14
206.6035 -912 233 1879 44
206.6036 -299 598 1878 48
206.6037 -111 520 1877 20
206.6038 -694 82 1876 20
206.6039 -73 716 1875 57
206.6040 -312 609 1874 47
206.6041 -379 814 1873 98
206.6042 -58 157 1872 66
206.6043 -34 952 1871 25
206.6044 -871 697 1870 47
206.6045 -635 959 1869 77
206.6046 -77 286 1868 61
206.6047 -438 993 1867 18
206.6048 -365 634 1866 41
206.6049 -106 99 1865 62
206.6050 -794 490 1864 76
206.6051 -656 319 1863 93
206.6052 -205 409 1862 32
206.6053 -254 780 1861 2
206.6054 -738 694 1860 16
206.6055 -673 165 1859 23
206.6056 -293 425 1858 55
206.6057 -358 770 1857 63
206.6058 -534 796 1856 7
206.6059 -608 859 1855 25
206.6060 -171 829 1854 31
206.6061 -909 610 1853 13
206.6062 -629 297 1852 45
206.6063 -86 861 1851 95
206.6064 -528 927 1850 51
206.6065 -740 677 1849 6
206.6066 -655 918 1848 38
206.6067 -973 566 1847 93
206.6068 -936 813 1846 82
206.6069 -30 946 1845 92
206.6070 -218 174 1844 43
206.6071 -313 686 1843 26
206.6072 -435 500 1842 28
206.6073 -933 434 1841 54
206.6074 -249 451 1840 55
206.6075 -759 684 1839 78
206.6076 -351 446 1838 8
206.6077 -753 110 1837 68
206.6078 -866 897 1836 3
206.6079 -772 488 1835 90
206.6080 -487 175 1834 81
206.6081 -186 982 1833 90
206.6082 -65 737 1832 87
206.6083 -983 984 1831 50
206.6084 -766 769 1830 68
206.6085 -238 704 1829 49
206.6086 -335 402 1828 40
206.6087 -212 644 1827 59
206.6088 -408 131 1826 88
206.6089 -313 93 1825 9
206.6090 -193 908 1824 28
206.6091 -244 26 1823 30
206.6092 -752 376 1822 12
206.6093 -215 817 1821 8
206.6094 -65 194 1820 21
206.6095 -302 82 1819 52
206.6096 -757 809 1818 90
206.6097 -513 711 1817 12
206.6098 -37 793 1816 80
206.6099 -185 808 1815 9
206.6100 -882 985 1814 12
206.6101 -649 179 1813 94
206.6102 -558 39 1812 49
206.6103 -623 864 1811 53
206.6104 -111 689 1810 14
206.6105 -272 624 1809 76
206.6106 -98 780 1808 54
206.6107 -917 318 1807 24
206.6108 -985 708 1806 47
206.6109 -822 974 1805 85
206.6110 -806 172 1804 30
206.6111 -139 455 1803 23
206.6112 -175 955 1802 9
206.6113 -174 387 1801 93
206.6114 -65 386 1800 51
206.6115 -844 218 1799 83
206.6116 -461 301 1798 17
206.6117 -610 767 1797 18
206.6118 -733 623 1796 93
206.6119 -802 549 1795 16
206.6120 -716 70 1794 1
206.6121 -499 141 1793 66
206.6122 -568 155 1792 96
206.6123 -1 423 1791 0
206.6124 -167 672 1790 10
206.6125 -916 665 1789 22
206.6126 -534 992 1788 38
206.6127 -144 248 1787 85
206.6128 -73 770 1786 87
206.6129 -479 145 1785 93
206.6130 -929 350 1784 8
206.6131 -985 701 1783 21
206.6132 -732 963 1782 93
206.6133 -751 891 1781 56
206.6134 -7 888 1780 83
206.6135 -672 837 1779 25
206.6136 -744 531 1778 38
206.6137 -477 975 1777 38
206.6138 -625 944 1776 7
206.6139 -794 845 1775 59
206.6140 -648 868 1774 54
206.6141 -738 286 1773 94
206.6142 -72 363 1772 25
206.6143 -2 733 1771 98
206.6144 -50 583 1770 74
206.6145 -306 867 1769 33
206.6146 -556 993 1768 92
206.6147 -30 318 1767 26
206.6148 -99 477 1766 85
206.6149 -976 43 1765 83
206.6150 -582 605 1764 14
206.6151 -922 691 1763 91
206.6152 -629 272 1762 66
206.6153 -150 236 1761 7
206.6154 -715 409 1760 95
206.6155 -874 406 1759 74
206.6156 -674 660 1758 74
206.6157 -841 415 1757 52
206.6158 -433 21 1756 93
206.6159 -438 684 1755 12
206.6160 -914 235 1754 39
206.6161 -419 244 1753 65
206.6162 -35 595 1752 29
206.6163 -826 118 1751 47
206.6164 -2 206 1750 43
206.6165 -746 995 1749 84
206.6166 -245 223 1748 20
206.6167 -393 595 1747 83
206.6168 -336 807 1746 40
206.6169 -449 728 1745 99
206.6170 -990 734 1744 52
206.6171 -649 366 1743 49
206.6172 -476 813 1742 38
206.6173 -912 44 1741 20
206.6174 -211 594 1740 82
206.6175 -771 640 1739 25
206.6176 -628 366 1738 50
206.6177 -787 425 1737 85
206.6178 -78 412 1736 5
206.6179 -994 470 1735 88
206.6180 -368 29 1734 45
206.6181 -552 111 1733 34
206.6182 -769 173 1732 17
206.6183 -449 385 1731 56
206.6184 -954 567 1730 70
206.6185 -273 755 1729 43
206.6186 -941 649 1728 14
206.6187 -12 793 1727 84
206.6188 -942 170 1726 70
206.6189 -441 428 1725 8
206.6190 -917 117 1724 62
206.6191 -937 167 1723 81
206.6192 -788 609 1722 78
206.6193 -818 863 1721 32
206.6194 -811 261 1720 49
206.6195 -105 296 1719 68
206.6196 -855 301 1718 33
206.6197 -623 132 1717 92
206.6198 -742 624 1716 7
206.6199 -310 457 1715 50
206.6200 -950 811 1714 52
206.6201 -558 32 1713 97
206.6202 -746 462 1712 14
206.6203 -601 825 1711 96
206.6204 -964 814 1710 0
206.6205 -994 348 1709 70
206.6206 -168 403 1708 25
206.6207 -508 858 1707 23
206.6208 -166 569 1706 88
206.6209 -646 976 1705 43
206.6210 -779 544 1704 35
206.6211 -569 829 1703 39
206.6212 -637 180 1702 81
206.6213 -10 962 1701 14
206.6214 -466 301 1700 63
206.6215 -944 455 1699 96
206.6216 -544 17 1698 82
206.6217 -289 351 1697 66
206.6218 -592 448 1696 34
206.6219 -432 72 1695 51
206.6220 -715 967 1694 86
206.6221 -649 579 1693 21
206.6222 -218 667 1692 93
206.6223 -660 507 1691 62
206.6224 -845 666 1690 54
206.6225 -438 143 1689 52
206.6226 -665 166 1688 40
206.6227 -903 317 1687 25
206.6228 -376 823 1686 69
206.6229 -104 651 1685 16
206.6230 -388 657 1684 71
206.6231 -912 279 1683 6
206.6232 -159 303 1682 43
206.6233 -840 82 1681 55
206.6234 -522 23 1680 81
206.6235 -977 121 1679 40
206.6236 -848 144 1678 77
206.6237 -493 558 1677 76
206.6238 -171 536 1676 52
206.6239 -994 443 1675 27
206.6240 -378 651 1674 71
206.6241 -975 635 1673 47
206.6242 -220 872 1672 75
206.6243 -59 742 1671 31
206.6244 -901 407 1670 31
206.6245 -976 634 1669 54
206.6246 -586 10 1668 12
206.6247 -22 234 1667 35
206.6248 -93 255 1666 32
206.6249 -792 555 1665 17
206.6250 -15 240 1664 61
206.6251 -762 723 1663 40
206.6252 -130 433 1662 75
206.6253 -335 0 1661 16
206.6254 -772 772 1660 15
206.6255 -623 415 1659 92
206.6256 -776 774 1658 39
206.6257 -979 32 1657 56
206.6258 -699 145 1656 92
206.6259 -315 561 1655 30
206.6260 -516 212 1654 77
206.6261 -290 648 1653 25
206.6262 -432 593 1652 63
206.6263 -227 2 1651 79
206.6264 -356 233 1650 56
206.6265 -641 534 1649 14
206.6266 -742 826 1648 84
206.6267 -887 634 1647 79
206.6268 -584 628 1646 28
206.6269 -348 524 1645 38
206.6270 -563 523 1644 79
206.6271 -55 620 1643 22
206.6272 -590 838 1642 85
206.6273 -769 231 1641 20
206.6274 -698 414 1640 87
206.6275 -707 300 1639 71
206.6276 -191 51 1638 89
206.6277 -6 516 1637 85
206.6278 -103 896 1636 30
206.6279 -1 585 1635 23
206.6280 -902 572 1634 78
206.6281 -782 368 1633 50
206.6282 -606 653 1632 46
206.6283 -816 333 1631 82
206.6284 -113 155 1630 7
206.6285 -249 815 1629 99
206.6286 -534 44 1628 51
206.6287 -620 551 1627 18
206.6288 -310 67 1626 90
206.6289 -12 451 1625 10
206.6290 -204 276 1624 9
206.6291 -714 42 1623 11
206.6292 -320 644 1622 17
206.6293 -177 750 1621 79
206.6294 -339 79 1620 70
206.6295 -771 475 1619 86
206.6296 -492 330 1618 71
206.6297 -484 282 1617 91
206.6298 -616 800 1616 30
206.6299 -174 3 1615 29
206.6300 -233 979 1614 80
206.6301 -398 943 1613 49
206.6302 -894 385 1612 39
206.6303 -670 87 1611 14
206.6304 -603 839 1610 83
206.6305 -145 148 1609 56
206.6306 -48 800 1608 27
206.6307 -481 605 1607 0
206.6308 -797 10 1606 86
206.6309 -24 491 1605 44
206.6310 -35 317 1604 94
206.6311 -558 95 1603 83
206.6312 -298 252 1602 50
206.6313 -247 304 1601 22
206.6314 -690 268 1600 6
206.6315 -348 290 1599 45
206.6316 -195 269 1598 9
206.6317 -594 140 1597 56
206.6318 -519 426 1596 68
206.6319 -174 499 1595 77
206.6320 -221 106 1594 98
206.6321 -843 330 1593 47
206.6322 -947 280 1592 25
206.6323 -35 157 1591 5
206.6324 -978 607 1590 55
206.6325 -21 361 1589 34
206.6326 -129 529 1588 15
206.6327 -713 883 1587 60
206.6328 -926 910 1586 7
206.6329 -393 784 1585 34
206.6330 -776 511 1584 95
206.6331 -50 217 1583 37
206.6332 -123 209 1582 89
206.6333 -549 493 1581 91
206.6334 -245 214 1580 5
206.6335 -832 189 1579 95
206.6336 -646 551 1578 89
206.6337 -972 526 1577 41
206.6338 -126 729 1576 78
206.6339 -273 392 1575 53
206.6340 -294 574 1574 61
206.6341 -7 482 1573 72
206.6342 -715 982 1572 92
206.6343 -278 855 1571 57
206.6344 -25 100 1570 30
206.6345 -637 65 1569 41
206.6346 -25 476 1568 18
206.6347 -796 628 1567 67
206.6348 -336 253 1566 84
206.6349 -818 916 1565 85
206.6350 -91 891 1564 97
206.6351 -499 798 1563 28
206.6352 -127 353 1562 29
206.6353 -754 270 1561 43
206.6354 -35 889 1560 25
206.6355 -589 227 1559 38
206.6356 -847 511 1558 61
206.6357 -375 828 1557 22
206.6358 -336 992 1556 45
206.6359 -24 874 1555 51
206.6360 -93 693 1554 72
206.6361 -444 994 1553 59
206.6362 -82 854 1552 37
206.6363 -380 184 1551 37
206.6364 -662 864 1550 71
206.6365 -715 775 1549 44
206.6366 -683 383 1548 74
206.6367 -835 768 1547 47
206.6368 -118 941 1546 3
206.6369 -181 792 1545 31
206.6370 -698 134 1544 93
206.6371 -139 220 1543 64
206.6372 -669 999 1542 36
206.6373 -319 653 1541 70
206.6374 -88 273 1540 71
206.6375 -392 703 1539 94
206.6376 -614 270 1538 3
206.6377 -827 432 1537 84
206.6378 -148 727 1536 71
206.6379 -658 380 1535 93
206.6380 -914 282 1534 48
206.6381 -221 286 1533 55
206.6382 -345 659 1532 46
206.6383 -379 983 1531 35
206.6384 -570 771 1530 23
206.6385 -432 915 1529 69
206.6386 -838 182 1528 77
206.6387 -705 132 1527 78
206.6388 -346 778 1526 67
206.6389 -97 455 1525 48
206.6390 -995 922 1524 74
206.6391 -627 89 1523 69
206.6392 -676 119 1522 87
206.6393 -211 119 1521 96
206.6394 -856 534 1520 80
206.6395 -732 919 1519 13
206.6396 -50 990 1518 59
206.6397 -353 107 1517 13
206.6398 -323 189 1516 35
206.6399 -533 745 1515 24
206.6400 -832 51 1514 10
206.6401 -970 817 1513 36
206.6402 -0 908 1512 95
206.6403 -584 157 1511 46
206.6404 -615 671 1510 35
206.6405 -928 542 1509 12
206.6406 -882 461 1508 68
206.6407 -918 774 1507 69
206.6408 -444 109 1506 3
206.6409 -693 147 1505 79
206.6410 -233 733 1504 70
206.6411 -908 417 1503 86
206.6412 -751 486 1502 96
206.6413 -485 109 1501 41
206.6414 -129 230 1500 96
206.6415 -81 442 1499 68
206.6416 -686 984 1498 4
206.6417 -665 666 1497 96
206.6418 -961 240 1496 47
206.6419 -414 89 1495 75
206.6420 -315 838 1494 45
206.6421 -931 892 1493 32
206.6422 -376 554 1492 15
206.6423 -879 445 1491 26
206.6424 -788 282 1490 35
206.6425 -457 640 1489 4
206.6426 -318 81 1488 39
206.6427 -425 490 1487 2
206.6428 -150 723 1486 70
206.6429 -251 291 1485 54
206.6430 -945 134 1484 9
206.6431 -338 167 1483 38
206.6432 -108 891 1482 55
206.6433 -163 909 1481 49
206.6434 -642 308 1480 9
206.6435 -558 653 1479 33
206.6436 -591 373 1478 13
206.6437 -767 316 1477 89
206.6438 -432 156 1476 27
206.6439 -156 449 1475 89
206.6440 -967 713 1474 30
206.6441 -276 829 1473 60
206.6442 -981 58 1472 22
206.6443 -601 405 1471 94
206.6444 -654 760 1470 52
206.6445 -279 191 1469 8
206.6446 -56 246 1468 96
206.6447 -160 617 1467 82
206.6448 -706 375 1466 33
206.6449 -735 593 1465 27
206.6450 -884 698 1464 18
206.6451 -770 377 1463 69
206.6452 -652 284 1462 29
206.6453 -644 424 1461 38
206.6454 -568 437 1460 94
206.6455 -945 115 1459 37
206.6456 -628 143 1458 22
206.6457 -241 489 1457 89
206.6458 -782 58 1456 45
206.6459 -894 86 1455 97
206.6460 -320 498 1454 85
206.6461 -93 396 1453 11
206.6462 -859 914 1452 11
206.6463 -986 433 1451 0
206.6464 -321 571 1450 7
206.6465 -972 151 1449 62
206.6466 -653 327 1448 31
206.6467 -430 441 1447 38
206.6468 -972 482 1446 45
206.6469 -588 120 1445 88
206.6470 -102 736 1444 57
206.6471 -481 996 1443 22
206.6472 -480 109 1442 23
206.6473 -862 931 1441 87
206.6474 -419 453 1440 66
206.6475 -824 306 1439 34
206.6476 -885 930 1438 31
206.6477 -959 927 1437 22
206.6478 -362 571 1436 45
206.6479 -384 313 1435 38
206.6480 -739 347 1434 48
206.6481 -886 993 1433 62
206.6482 -178 360 1432 0
206.6483 -478 207 1431 61
206.6484 -147 316 1430 44
206.6485 -375 29 1429 59
206.6486 -2 96 1428 93
206.6487 -356 764 1427 92
206.6488 -257 74 1426 59
206.6489 -966 897 1425 97
206.6490 -354 865 1424 64
206.6491 -632 619 1423 85
206.6492 -153 382 1422 70
206.6493 -891 175 1421 69
206.6494 -286 846 1420 33
206.6495 -933 657 1419 77
206.6496 -332 11 1418 37
206.6497 -689 329 1417 64
206.6498 -176 618 1416 9
206.6499 -32 333 1415 29
206.6500 -245 791 1414 61
206.6501 -237 144 1413 72
206.6502 -207 9 1412 47
206.6503 -328 368 1411 26
206.6504 -189 559 1410 60
206.6505 -645 397 1409 35
206.6506 -681 727 1408 60
206.6507 -711 547 1407 64
206.6508 -285 807 1406 51
206.6509 -542 679 1405 14
206.6510 -647 890 1404 78
206.6511 -135 242 1403 0
206.6512 -640 217 1402 2
206.6513 -809 656 1401 87
206.6514 -161 251 1400 13
206.6515 -669 752 1399 54
206.6516 -180 958 1398 96
206.6517 -740 129 1397 97
206.6518 -127 368 1396 42
206.6519 -789 357 1395 74
206.6520 -647 778 1394 89
206.6521 -25 978 1393 51
206.6522 -560 151 1392 49
206.6523 -404 739 1391 83
206.6524 -499 594 1390 64
206.6525 -793 580 1389 49
206.6526 -829 993 1388 48
206.6527 -761 544 1387 44
206.6528 -10 682 1386 61
206.6529 -579 848 1385 33
206.6530 -799 382 1384 14
206.6531 -827 17 1383 62
206.6532 -411 663 1382 46
206.6533 -145 184 1381 15
206.6534 -14 154 1380 90
206.6535 -587 3 1379 70
206.6536 -448 48 1378 96
206.6537 -862 828 1377 6
206.6538 -834 274 1376 75
206.6539 -466 195 1375 43
206.6540 -364 520 1374 78
206.6541 -354 156 1373 97
206.6542 -479 308 1372 41
206.6543 -29 251 1371 26
206.6544 -151 198 1370 13
206.6545 -954 742 1369 42
206.6546 -220 895 1368 13
206.6547 -554 317 1367 58
206.6548 -78 319 1366 2
206.6549 -674 650 1365 36
206.6550 -364 808 1364 10
206.6551 -848 555 1363 0
206.6552 -56 149 1362 87
206.6553 -53 135 1361 44
206.6554 -455 703 1360 87
206.6555 -846 287 1359 19
206.6556 -578 552 1358 73
206.6557 -997 558 1357 66
206.6558 -669 659 1356 47
206.6559 -842 266 1355 40
206.6560 -252 91 1354 31
206.6561 -405 134 1353 51
206.6562 -14 425 1352 79
206.6563 -431 572 1351 0
206.6564 -415 680 1350 59
206.6565 -735 462 1349 60
206.6566 -994 68 1348 26
206.6567 -898 190 1347 58
206.6568 -393 72 1346 32
206.6569 -174 92 1345 82
206.6570 -957 794 1344 58
206.6571 -708 724 1343 84
206.6572 -853 787 1342 39
206.6573 -891 405 1341 58
206.6574 -217 989 1340 1
206.6575 -393 340 1339 68
206.6576 -878 687 1338 74
206.6577 -118 252 1337 9
206.6578 -979 501 1336 50
206.6579 -297 237 1335 21
206.6580 -69 742 1334 21
206.6581 -936 456 1333 24
206.6582 -382 808 1332 85
206.6583 -416 566 1331 96
206.6584 -648 335 1330 67
206.6585 -653 940 1329 82
206.6586 -435 644 1328 51
206.6587 -750 591 1327 76
206.6588 -264 285 1326 13
206.6589 -495 2 1325 68
206.6590 -285 968 1324 22
206.6591 -647 393 1323 13
206.6592 -242 893 1322 55
206.6593 -230 287 1321 96
206.6594 -395 849 1320 76
206.6595 -296 308 1319 99
206.6596 -52 755 1318 21
206.6597 -305 621 1317 68
206.6598 -283 456 1316 48
206.6599 -34 453 1315 76
206.6600 -574 94 1314 20
206.6601 -500 578 1313 63
206.6602 -605 587 1312 40
206.6603 -438 198 1311 1
206.6604 -541 772 1310 83
206.6605 -553 777 1309 9
206.6606 -133 533 1308 24
206.6607 -164 198 1307 74
206.6608 -3 716 1306 2
206.6609 -358 560 1305 24
206.6610 -515 570 1304 45
206.6611 -991 233 1303 7
206.6612 -388 393 1302 89
206.6613 -426 176 1301 16
206.6614 -995 736 1300 89
206.6615 -243 856 1299 98
206.6616 -334 495 1298 42
206.6617 -482 724 1297 96
206.6618 -156 773 1296 16
206.6619 -989 789 1295 64
206.6620 -337 386 1294 84
206.6621 -840 178 1293 52
206.6622 -216 728 1292 60
206.6623 -440 270 1291 96
206.6624 -880 909 1290 43
206.6625 -360 566 1289 75
206.6626 -771 451 1288 90
206.6627 -950 807 1287 85
206.6628 -984 517 1286 32
206.6629 -403 801 1285 16
206.6630 -207 318 1284 65
206.6631 -450 922 1283 49
206.6632 -458 639 1282 62
206.6633 -360 531 1281 77
206.6634 -342 679 1280 56
206.6635 -115 842 1279 51
206.6636 -644 57 1278 58
206.6637 -290 526 1277 82
206.6638 -715 158 1276 96
206.6639 -483 515 1275 58
206.6640 -395 155 1274 19
206.6641 -282 873 1273 75
206.6642 -108 847 1272 99
206.6643 -851 216 1271 9
206.6644 -837 40 1270 1
206.6645 -784 931 1269 22
206.6646 -531 768 1268 47
206.6647 -367 853 1267 35
206.6648 -643 385 1266 57
206.6649 -359 385 1265 23
206.6650 -282 437 1264 8
206.6651 -26 765 1263 11
206.6652 -630 894 1262 17
206.6653 -176 79 1261 25
206.6654 -109 790 1260 1
206.6655 -162 757 1259 5
206.6656 -914 115 1258 25
206.6657 -468 780 1257 16
206.6658 -999 342 1256 72
206.6659 -947 143 1255 28
206.6660 -672 975 1254 7
206.6661 -871 939 1253 25
206.6662 -814 916 1252 39
206.6663 -289 243 1251 45
206.6664 -32 961 1250 6
206.6665 -642 798 1249 94
206.6666 -335 90 1248 24
206.6667 -437 439 1247 44
206.6668 -198 440 1246 46
206.6669 -168 205 1245 5
206.6670 -35 822 1244 27
206.6671 -22 860 1243 80
206.6672 -673 940 1242 5
206.6673 -281 387 1241 52
206.6674 -162 119 1240 25
206.6675 -708 698 1239 39
206.6676 -650 802 1238 30
206.6677 -998 977 1237 89
206.6678 -235 417 1236 23
206.6679 -383 776 1235 3
206.6680 -961 474 1234 13
206.6681 -919 744 1233 1
206.6682 -552 530 1232 34
206.6683 -268 268 1231 39
206.6684 -421 866 1230 11
206.6685 -896 83 1229 45
206.6686 -824 408 1228 5
206.6687 -560 659 1227 65
206.6688 -641 208 1226 76
206.6689 -301 897 1225 85
206.6690 -729 120 1224 42
206.6691 -213 663 1223 4
206.6692 -262 958 1222 36
206.6693 -402 272 1221 28
206.6694 -782 664 1220 84
206.6695 -674 396 1219 52
206.6696 -749 405 1218 7
206.6697 -451 889 1217 26
206.6698 -311 911 1216 91
206.6699 -776 430 1215 33
206.6700 -457 379 1214 57
206.6701 -704 675 1213 51
206.6702 -685 81 1212 95
206.6703 -608 438 1211 86
206.6704 -267 321 1210 61
206.6705 -991 453 1209 10
206.6706 -515 806 1208 92
206.6707 -978 345 1207 29
206.6708 -480 579 1206 14
206.6709 -51 768 1205 53
206.6710 -703 55 1204 31
206.6711 -594 564 1203 75
206.6712 -643 91 1202 1
206.6713 -116 240 1201 7
206.6714 -868 512 1200 34
206.6715 -646 182 1199 27
206.6716 -461 627 1198 47
206.6717 -765 158 1197 53
206.6718 -811 605 1196 49
206.6719 -712 214 1195 42
206.6720 -491 567 1194 34
206.6721 -472 733 1193 10
206.6722 -850 942 1192 95
206.6723 -728 735 1191 52
206.6724 -329 65 1190 24
206.6725 -554 799 1189 22
206.6726 -469 938 1188 18
206.6727 -552 39 1187 69
206.6728 -391 69 1186 95
206.6729 -647 80 1185 9
206.6730 -834 239 1184 22
206.6731 -790 157 1183 1
206.6732 -206 423 1182 62
206.6733 -669 278 1181 12
206.6734 -266 25 1180 39
206.6735 -860 37 1179 77
206.6736 -898 489 1178 8
206.6737 -970 741 1177 91
206.6738 -988 855 1176 16
206.6739 -840 878 1175 74
206.6740 -81 201 1174 81
206.6741 -733 396 1173 4
206.6742 -145 499 1172 58
206.6743 -253 723 1171 53
206.6744 -988 623 1170 40
206.6745 -548 689 1169 40
206.6746 -748 169 1168 96
206.6747 -886 755 1167 92
206.6748 -976 416 1166 98
206.6749 -676 931 1165 14
206.6750 -805 769 1164 75
206.6751 -897 458 1163 34
206.6752 -776 48 1162 58
206.6753 -99 133 1161 89
206.6754 -934 997 1160 26
206.6755 -520 443 1159 44
206.6756 -413 34 1158 79
206.6757 -339 946 1157 86
206.6758 -485 833 1156 90
206.6759 -161 389 1155 29
206.6760 -310 410 1154 87
206.6761 -410 758 1153 90
206.6762 -914 696 1152 12
206.6763 -135 627 1151 67
206.6764 -553 824 1150 16
206.6765 -409 640 1149 41
206.6766 -87 937 1148 10
206.6767 -113 952 1147 7
206.6768 -443 610 1146 85
206.6769 -979 428 1145 32
206.6770 -651 963 1144 85
206.6771 -62 787 1143 90
206.6772 -69 444 1142 49
206.6773 -803 511 1141 77
206.6774 -183 750 1140 58
206.6775 -702 307 1139 14
206.6776 -985 32 1138 32
206.6777 -342 220 1137 97
206.6778 -182 530 1136 67
206.6779 -464 472 1135 46
206.6780 -176 950 1134 32
206.6781 -342 404 1133 58
206.6782 -933 717 1132 99
206.6783 -760 196 1131 26
206.6784 -442 437 1130 62
206.6785 -275 822 1129 48
206.6786 -811 347 1128 71
206.6787 -689 304 1127 64
206.6788 -58 205 1126 16
206.6789 -521 136 1125 71
206.6790 -546 737 1124 28
206.6791 -687 596 1123 83
206.6792 -520 727 1122 40
206.6793 -758 645 1121 17
206.6794 -615 139 1120 31
206.6795 -474 763 1119 16
206.6796 -43 73 1118 46
206.6797 -98 483 1117 12
206.6798 -69 442 1116 63
206.6799 -399 429 1115 53
206.6800 -141 455 1114 97
206.6801 -868 423 1113 85
206.6802 -82 236 1112 16
206.6803 -506 855 1111 76
206.6804 -375 150 1110 14
206.6805 -690 702 1109 14
206.6806 -590 342 1108 43
206.6807 -40 491 1107 94
206.6808 -13 93 1106 2
206.6809 -974 562 1105 66
206.6810 -31 115 1104 25
206.6811 -186 692 1103 27
206.6812 -380 405 1102 78
206.6813 -705 618 1101 57
206.6814 -447 1 1100 13
206.6815 -360 711 1099 68
206.6816 -851 484 1098 9
206.6817 -397 916 1097 55
206.6818 -530 359 1096 2
206.6819 -446 411 1095 3
206.6820 -423 986 1094 94
206.6821 -287 485 1093 84
206.6822 -786 210 1092 80
206.6823 -617 445 1091 67
206.6824 -290 445 1090 25
206.6825 -226 585 1089 8
206.6826 -567 549 1088 50
206.6827 -557 523 1087 45
206.6828 -948 987 1086 86
206.6829 -424 97 1085 8
206.6830 -500 97 1084 2
206.6831 -274 38 1083 13
206.6832 -765 131 1082 50
206.6833 -999 416 1081 16
206.6834 -859 170 1080 32
206.6835 -36 578 1079 6
206.6836 -25 55 1078 65
206.6837 -536 586 1077 1
206.6838 -890 782 1076 60
206.6839 -999 60 1075 52
206.6840 -59 887 1074 92
206.6841 -906 634 1073 22
206.6842 -715 332 1072 50
206.6843 -245 841 1071 76
206.6844 -592 263 1070 13
206.6845 -522 404 1069 82
206.6846 -469 648 1068 1
206.6847 -803 401 1067 48
206.6848 -721 85 1066 64
206.6849 -173 599 1065 89
206.6850 -253 697 1064 93
206.6851 -302 717 1063 15
206.6852 -490 742 1062 19
206.6853 -577 626 1061 46
206.6854 -858 316 1060 65
206.6855 -756 812 1059 7
206.6856 -246 521 1058 5
206.6857 -315 843 1057 66
206.6858 -486 755 1056 8
206.6859 -901 950 1055 54
206.6860 -979 787 1054 91
206.6861 -975 961 1053 95
206.6862 -115 722 1052 81
206.6863 -309 816 1051 91
206.6864 -504 581 1050 71
206.6865 -290 18 1049 10
206.6866 -678 386 1048 51
206.6867 -87 584 1047 93
206.6868 -804 533 1046 82
206.6869 -163 628 1045 58
206.6870 -825 968 1044 92
206.6871 -239 139 1043 0
206.6872 -905 899 1042 86
206.6873 -234 193 1041 80
206.6874 -563 616 1040 80
206.6875 -632 591 1039 21
206.6876 -802 579 1038 61
206.6877 -50 101 1037 59
206.6878 -904 243 1036 28
206.6879 -659 663 1035 64
206.6880 -829 917 1034 33
206.6881 -240 143 1033 58
206.6882 -705 54 1032 33
206.6883 -576 0 1031 67
206.6884 -25 590 1030 67
206.6885 -11 602 1029 93
206.6886 -477 21 1028 82
206.6887 -857 307 1027 75
206.6888 -580 642 1026 14
206.6889 -745 302 1025 24
206.6890 -774 751 1024 83
206.6891 -89 252 1023 58
206.6892 -53 663 1022 53
206.6893 -410 999 1021 12
206.6894 -988 739 1020 55
206.6895 -580 101 1019 1
206.6896 -714 78 1018 53
206.6897 -664 604 1017 61
206.6898 -339 902 1016 27
206.6899 -550 414 1015 83
206.6900 -499 240 1014 97
206.6901 -589 54 1013 68
206.6902 -663 406 1012 3
206.6903 -260 577 1011 64
206.6904 -637 538 1010 42
206.6905 -23 479 1009 40
206.6906 -473 914 1008 86
206.6907 -702 342 1007 5
206.6908 -487 442 1006 32
206.6909 -173 863 1005 78
206.6910 -185 285 1004 5
206.6911 -648 649 1003 91
206.6912 -829 392 1002 92
206.6913 -39 221 1001 40
206.6914 -58 13 1000 62
206.6915 -565 542 999 61
206.6916 -571 815 998 54
206.6917 -899 725 997 77
206.6918 -578 535 996 21
206.6919 -578 738 995 31
206.6920 -636 141 994 98
206.6921 -257 984 993 53
206.6922 -170 522 992 81
206.6923 -207 781 991 78
206.6924 -471 7 990 98
206.6925 -726 64 989 49
206.6926 -89 778 988 99
206.6927 -190 556 987 67
206.6928 -797 900 986 32
206.6929 -596 326 985 0
206.6930 -156 450 984 94
206.6931 -461 718 983 37
206.6932 -741 29 982 8
206.6933 -773 809 981 96
206.6934 -942 486 980 73
206.6935 -286 499 979 74
206.6936 -221 321 978 63
206.6937 -656 351 977 89
206.6938 -573 320 976 39
206.6939 -876 59 975 20
206.6940 -731 562 974 44
206.6941 -688 292 973 69
206.6942 -220 123 972 72
206.6943 -322 226 971 96
206.6944 -986 991 970 83
206.6945 -178 107 969 65
206.6946 -970 737 968 6
206.6947 -30 506 967 56
206.6948 -261 192 966 8
206.6949 -496 760 965 69
206.6950 -270 745 964 14
206.6951 -168 974 963 4
206.6952 -896 752 962 46
206.6953 -235 136 961 89
206.6954 -883 174 960 33
206.6955 -369 590 959 80
206.6956 -231 501 958 20
206.6957 -313 480 957 93
206.6958 -432 387 956 76
206.6959 -15 551 955 76
206.6960 -770 101 954 22
206.6961 -221 574 953 10
206.6962 -615 571 952 27
206.6963 -962 561 951 66
206.6964 -584 527 950 35
206.6965 -89 600 949 51
206.6966 -20 268 948 13
206.6967 -93 169 947 91
206.6968 -835 4 946 88
206.6969 -450 539 945 41
206.6970 -526 122 944 24
206.6971 -3 831 943 54
206.6972 -9 609 942 60
206.6973 -34 309 941 65
206.6974 -926 837 940 37
206.6975 -331 375 939 49
206.6976 -98 221 938 6
206.6977 -164 35 937 92
206.6978 -465 464 936 25
206.6979 -416 173 935 38
206.6980 -291 695 934 92
206.6981 -221 943 933 52
206.6982 -299 951 932 99
206.6983 -472 276 931 97
206.6984 -461 882 930 10
206.6985 -154 426 929 59
206.6986 -185 142 928 23
206.6987 -571 668 927 93
206.6988 -291 873 926 69
206.6989 -477 461 925 4
206.6990 -751 401 924 12
206.6991 -991 528 923 6
206.6992 -675 19 922 92
206.6993 -393 867 921 82
206.6994 -455 512 920 1
206.6995 -284 361 919 30
206.6996 -474 298 918 96
206.6997 -794 235 917 61
206.6998 -412 650 916 28
206.6999 -59 923 915 81
206.7000 -873 55 914 72
206.7001 -508 148 913 75
206.7002 -152 94 912 31
206.7003 -354 816 911 28
206.7004 -151 703 910 93
206.7005 -63 338 909 17
206.7006 -63 355 908 81
206.7007 -584 333 907 67
206.7008 -727 467 906 38
206.7009 -867 86 905 35
206.7010 -907 966 904 18
206.7011 -53 443 903 36
206.7012 -277 34 902 35
206.7013 -113 343 901 79
206.7014 -364 766 900 20
206.7015 -983 361 899 8
206.7016 -22 130 898 99
206.7017 -865 296 897 47
206.7018 -380 29 896 85
206.7019 -119 165 895 85
206.7020 -523 821 894 96
206.7021 -409 8 893 85
206.7022 -690 557 892 77
206.7023 -576 595 891 16
206.7024 -405 115 890 74
206.7025 -230 88 889 38
206.7026 -834 520 888 96
206.7027 -266 622 887 15
206.7028 -864 997 886 48
206.7029 -344 898 885 26
206.7030 -812 106 884 59
206.7031 -451 78 883 11
206.7032 -962 611 882 71
206.7033 -479 415 881 11
206.7034 -27 367 880 17
206.7035 -567 420 879 17
206.7036 -898 804 878 39
206.7037 -624 670 877 56
206.7038 -99 224 876 40
206.7039 -791 664 875 51
206.7040 -28 482 874 53
206.7041 -466 395 873 36
206.7042 -195 603 872 48
206.7043 -48 943 871 48
206.7044 -946 995 870 45
206.7045 -616 779 869 45
206.7046 -133 828 868 66
206.7047 -446 164 867 27
206.7048 -559 883 866 52
206.7049 -182 988 865 30
206.7050 -86 169 864 76
206.7051 -791 872 863 56
206.7052 -660 5 862 27
206.7053 -948 30 861 14
206.7054 -215 992 860 10
206.7055 -950 790 859 33
206.7056 -664 394 858 48
206.7057 -281 749 857 68
206.7058 -894 217 856 88
206.7059 -818 544 855 37
206.7060 -296 201 854 9
206.7061 -866 290 853 29
206.7062 -975 123 852 13
206.7063 -37 45 851 71
206.7064 -202 771 850 73
206.7065 -395 847 849 26
206.7066 -645 795 848 28
206.7067 -532 800 847 38
206.7068 -672 508 846 38
206.7069 -343 282 845 7
206.7070 -910 800 844 52
206.7071 -167 163 843 42
206.7072 -78 418 842 89
206.7073 -273 979 841 93
206.7074 -924 467 840 83
206.7075 -52 978 839 80
206.7076 -995 903 838 75
206.7077 -291 995 837 11
206.7078 -226 311 836 85
206.7079 -482 553 835 32
206.7080 -636 92 834 43
206.7081 -744 538 833 74
206.7082 -439 953 832 8
206.7083 -511 102 831 80
206.7084 -489 28 830 34
206.7085 -74 56 829 87
206.7086 -907 636 828 5
206.7087 -684 253 827 70
206.7088 -758 530 826 6
206.7089 -460 896 825 74
206.7090 -554 690 824 84
206.7091 -584 654 823 89
206.7092 -851 284 822 30
206.7093 -73 454 821 92
206.7094 -972 477 820 2
206.7095 -419 814 819 41
206.7096 -383 352 818 16
206.7097 -723 638 817 22
206.7098 -633 320 816 92
206.7099 -205 898 815 29
206.7100 -35 953 814 90
206.7101 -369 586 813 96
206.7102 -829 378 812 73
206.7103 -976 904 811 77
206.7104 -662 607 810 10
206.7105 -462 248 809 55
206.7106 -714 943 808 3
206.7107 -318 297 807 65
206.7108 -421 627 806 8
206.7109 -945 391 805 42
206.7110 -366 936 804 17
206.7111 -208 236 803 66
206.7112 -473 955 802 54
206.7113 -297 675 801 85
206.7114 -358 548 800 31
206.7115 -305 516 799 20
206.7116 -645 377 798 74
206.7117 -669 569 797 39
206.7118 -236 661 796 89
206.7119 -455 257 795 47
206.7120 -699 504 794 57
206.7121 -280 125 793 15
206.7122 -280 687 792 73
206.7123 -126 538 791 17
206.7124 -32 113 790 93
206.7125 -138 452 789 5
206.7126 -808 351 788 65
206.7127 -907 500 787 97
206.7128 -404 419 786 43
206.7129 -753 897 785 78
206.7130 -378 420 784 75
206.7131 -437 423 783 41
206.7132 -149 559 782 0
206.7133 -425 236 781 15
206.7134 -660 885 780 9
206.7135 -101 394 779 89
206.7136 -851 683 778 33
206.7137 -80 542 777 90
206.7138 -522 653 776 50
206.7139 -477 24 775 65
206.7140 -996 336 774 37
206.7141 -864 418 773 94
206.7142 -322 847 772 28
206.7143 -350 59 771 72
206.7144 -491 200 770 76
206.7145 -710 563 769 55
206.7146 -141 429 768 24
206.7147 -889 397 767 77
206.7148 -628 852 766 55
206.7149 -688 276 765 4
206.7150 -917 433 764 48
206.7151 -571 652 763 13
206.7152 -787 564 762 54
206.7153 -859 958 761 97
206.7154 -636 205 760 85
206.7155 -133 309 759 78
206.7156 -32 477 758 56
206.7157 -545 213 757 25
206.7158 -576 513 756 26
206.7159 -843 563 755 93
206.7160 -780 348 754 77
206.7161 -88 590 753 34
206.7162 -605 569 752 78
206.7163 -752 112 751 92
206.7164 -895 79 750 22
206.7165 -832 210 749 50
206.7166 -264 317 748 10
206.7167 -699 991 747 48
206.7168 -949 321 746 96
206.7169 -215 169 745 73
206.7170 -758 424 744 6
206.7171 -21 561 743 69
206.7172 -457 855 742 48
206.7173 -33 706 741 85
206.7174 -868 718 740 85
206.7175 -893 401 739 6
206.7176 -326 614 738 56
206.7177 -669 517 737 56
206.7178 -152 236 736 75
206.7179 -744 669 735 73
206.7180 -862 370 734 45
206.7181 -706 209 733 73
206.7182 -149 629 732 56
206.7183 -987 995 731 42
206.7184 -316 793 730 16
206.7185 -787 496 729 97
206.7186 -97 2 728 56
206.7187 -280 815 727 65
206.7188 -566 15 726 51
206.7189 -299 277 725 40
206.7190 -161 719 724 88
206.7191 -580 173 723 15
206.7192 -633 140 722 55
206.7193 -202 259 721 16
206.7194 -296 189 720 67
206.7195 -494 408 719 52
206.7196 -186 910 718 68
206.7197 -799 138 717 81
206.7198 -737 110 716 71
206.7199 -558 526 715 26
206.7200 -546 725 714 13
206.7201 -33 598 713 58
206.7202 -880 395 712 94
206.7203 -69 490 711 43
206.7204 -780 140 710 90
206.7205 -498 840 709 80
206.7206 -771 872 708 30
206.7207 -28 102 707 38
206.7208 -584 446 706 6
206.7209 -800 129 705 17
206.7210 -126 557 704 1
206.7211 -202 634 703 51
206.7212 -905 515 702 15
206.7213 -350 526 701 81
206.7214 -300 102 700 28
206.7215 -967 495 699 28
206.7216 -770 920 698 72
206.7217 -655 325 697 74
206.7218 -316 882 696 44
206.7219 -572 166 695 78
206.7220 -922 499 694 67
206.7221 -119 360 693 92
206.7222 -989 341 692 29
206.7223 -423 521 691 55
206.7224 -607 6 690 4
206.7225 -575 556 689 33
206.7226 -594 983 688 19
206.7227 -442 298 687 11
206.7228 -716 660 686 33
206.7229 -667 109 685 74
206.7230 -138 750 684 65
206.7231 -18 626 683 80
206.7232 -819 742 682 13
206.7233 -515 504 681 56
206.7234 -449 717 680 81
206.7235 -572 135 679 3
206.7236 -684 82 678 98
206.7237 -637 775 677 15
206.7238 -551 594 676 72
206.7239 -358 94 675 4
206.7240 -124 846 674 52
206.7241 -883 673 673 11
206.7242 -237 564 672 19
206.7243 -787 749 671 30
206.7244 -581 783 670 6
206.7245 -52 51 669 87
206.7246 -306 827 668 88
206.7247 -180 426 667 4
206.7248 -500 677 666 8
206.7249 -247 519 665 19
206.7250 -173 409 664 23
206.7251 -108 920 663 24
206.7252 -814 895 662 64
206.7253 -965 238 661 45
206.7254 -731 188 660 20
206.7255 -224 989 659 52
206.7256 -401 840 658 74
206.7257 -748 961 657 12
206.7258 -158 893 656 68
206.7259 -110 958 655 25
206.7260 -488 993 654 7
206.7261 -25 595 653 6
206.7262 -656 195 652 29
206.7263 -49 244 651 84
206.7264 -199 677 650 23
206.7265 -148 782 649 50
206.7266 -879 620 648 82
206.7267 -67 445 647 65
206.7268 -935 426 646 59
206.7269 -964 179 645 4
206.7270 -398 9 644 62
206.7271 -400 770 643 46
206.7272 -951 445 642 36
206.7273 -566 614 641 60
206.7274 -894 726 640 84
206.7275 -162 684 639 5
206.7276 -174 170 638 26
206.7277 -18 61 637 81
206.7278 -247 543 636 13
206.7279 -169 425 635 97
206.7280 -238 158 634 56
206.7281 -325 94 633 99
206.7282 -830 761 632 44
206.7283 -888 757 631 38
206.7284 -41 798 630 67
206.7285 -514 783 629 73
206.7286 -108 456 628 98
206.7287 -518 679 627 15
206.7288 -117 161 626 77
206.7289 -267 405 625 7
206.7290 -63 567 624 93
206.7291 -333 549 623 91
206.7292 -3 64 622 49
206.7293 -959 712 621 94
206.7294 -15 939 620 84
206.7295 -326 743 619 52
206.7296 -776 833 618 40
206.7297 -518 384 617 59
206.7298 -756 693 616 40
206.7299 -837 147 615 84
206.7300 -18 17 614 20
206.7301 -484 417 613 72
206.7302 -351 554 612 33
206.7303 -772 93 611 4
206.7304 -196 320 610 94
206.7305 -910 120 609 68
206.7306 -449 815 608 55
206.7307 -690 188 607 25
206.7308 -546 551 606 76
206.7309 -129 645 605 91
206.7310 -599 474 604 81
206.7311 -863 399 603 53
206.7312 -460 286 602 13
206.7313 -773 100 601 57
206.7314 -199 255 600 57
206.7315 -304 138 599 28
206.7316 -627 292 598 46
206.7317 -637 495 597 75
206.7318 -906 843 596 14
206.7319 -170 100 595 41
206.7320 -75 285 594 52
206.7321 -112 400 593 73
206.7322 -185 553 592 40
206.7323 -845 2 591 68
206.7324 -116 291 590 57
206.7325 -845 823 589 89
206.7326 -796 703 588 67
206.7327 -652 613 587 99
206.7328 -742 727 586 73
206.7329 -815 886 585 73
206.7330 -884 794 584 9
206.7331 -846 332 583 96
206.7332 -551 716 582 92
206.7333 -711 114 581 33
206.7334 -467 678 580 72
206.7335 -120 217 579 27
206.7336 -89 687 578 4
206.7337 -886 259 577 14
206.7338 -841 995 576 90
206.7339 -92 640 575 92
206.7340 -462 132 574 93
206.7341 -615 35 573 3
206.7342 -602 587 572 29
206.7343 -436 611 571 83
206.7344 -460 457 570 24
206.7345 -529 222 569 34
206.7346 -428 904 568 3
206.7347 -263 234 567 20
206.7348 -355 981 566 4
206.7349 -507 997 565 74
206.7350 -97 892 564 63
206.7351 -447 742 563 84
206.7352 -976 455 562 1
206.7353 -153 595 561 16
206.7354 -234 896 560 97
206.7355 -318 316 559 93
206.7356 -670 827 558 10
206.7357 -252 158 557 16
206.7358 -984 296 556 90
206.7359 -104 118 555 84
206.7360 -150 784 554 41
206.7361 -287 832 553 65
206.7362 -859 848 552 47
206.7363 -699 190 551 82
206.7364 -579 44 550 91
206.7365 -489 829 549 91
206.7366 -668 936 548 64
206.7367 -862 256 547 41
206.7368 -178 60 546 26
206.7369 -333 437 545 88
206.7370 -952 759 544 95
206.7371 -984 180 543 86
206.7372 -657 647 542 42
206.7373 -146 903 541 16
206.7374 -214 3 540 11
206.7375 -892 268 539 9
206.7376 -680 230 538 82
206.7377 -196 149 537 80
206.7378 -622 387 536 68
206.7379 -678 926 535 84
206.7380 -579 91 534 38
206.7381 -532 435 533 96
206.7382 -744 267 532 32
206.7383 -900 40 531 51
206.7384 -735 29 530 93
206.7385 -37 269 529 32
206.7386 -80 14 528 21
206.7387 -762 122 527 48
206.7388 -460 839 526 57
206.7389 -835 462 525 94
206.7390 -656 413 524 9
206.7391 -167 641 523 4
206.7392 -226 815 522 78
206.7393 -11 580 521 84
206.7394 -759 609 520 16
206.7395 -254 109 519 69
206.7396 -892 728 518 95
206.7397 -283 909 517 31
206.7398 -376 630 516 30
206.7399 -48 845 515 62
206.7400 -772 52 514 17
206.7401 -825 258 513 48
206.7402 -235 944 512 94
206.7403 -970 678 511 21
206.7404 -500 467 510 25
206.7405 -380 741 509 50
206.7406 -819 638 508 36
206.7407 -279 15 507 60
206.7408 -785 676 506 90
206.7409 -792 446 505 32
206.7410 -793 690 504 27
206.7411 -313 547 503 94
206.7412 -265 725 502 59
206.7413 -211 963 501 26
206.7414 -726 746 500 47
206.7415 -102 143 499 11
206.7416 -622 752 498 56
206.7417 -339 702 497 54
206.7418 -229 578 496 49
206.7419 -756 51 495 99
206.7420 -142 329 494 99
206.7421 -821 356 493 48
206.7422 -762 326 492 4
206.7423 -216 793 491 5
206.7424 -603 351 490 48
206.7425 -390 558 489 62
206.7426 -50 20 488 47
206.7427 -123 46 487 28
206.7428 -527 501 486 10
206.7429 -722 993 485 47
206.7430 -973 519 484 61
206.7431 -30 432 483 32
206.7432 -532 993 482 5
206.7433 -442 568 481 54
206.7434 -792 861 480 61
206.7435 -537 144 479 21
206.7436 -974 195 478 34
206.7437 -544 174 477 92
206.7438 -508 635 476 59
206.7439 -474 860 475 80
206.7440 -86 292 474 74
206.7441 -438 261 473 94
206.7442 -424 512 472 49
206.7443 -706 933 471 8
206.7444 -717 399 470 65
206.7445 -948 873 469 25
206.7446 -20 413 468 56
206.7447 -539 329 467 42
206.7448 -774 792 466 3
206.7449 -568 55 465 3
206.7450 -30 806 464 38
206.7451 -748 445 463 64
206.7452 -579 408 462 1
206.7453 -533 439 461 71
206.7454 -526 395 460 98
206.7455 -459 691 459 76
206.7456 -84 133 458 92
206.7457 -537 393 457 48
206.7458 -736 2 456 76
206.7459 -249 646 455 20
206.7460 -360 739 454 53
206.7461 -36 633 453 28
206.7462 -969 296 452 16
206.7463 -43 728 451 4
206.7464 -703 220 450 0
206.7465 -558 840 449 6
206.7466 -740 446 448 37
206.7467 -390 716 447 54
206.7468 -355 558 446 80
206.7469 -907 668 445 48
206.7470 -106 256 444 88
206.7471 -337 112 443 32
206.7472 -568 122 442 6
206.7473 -507 40 441 92
206.7474 -379 938 440 34
206.7475 -393 692 439 14
206.7476 -730 827 438 81
206.7477 -157 747 437 34
206.7478 -890 312 436 3
206.7479 -411 599 435 44
206.7480 -144 564 434 80
206.7481 -989 256 433 76
206.7482 -82 142 432 76
206.7483 -101 584 431 6
206.7484 -246 194 430 12
206.7485 -864 327 429 98
206.7486 -80 468 428 66
206.7487 -434 314 427 57
206.7488 -713 587 426 26
206.7489 -35 647 425 47
206.7490 -307 31 424 26
206.7491 -114 0 423 15
206.7492 -557 708 422 90
206.7493 -390 932 421 98
206.7494 -867 141 420 85
206.7495 -859 322 419 38
206.7496 -154 90 418 78
206.7497 -726 305 417 64
206.7498 -939 788 416 72
206.7499 -615 211 415 67
206.7500 -31 112 414 72
206.7501 -291 247 413 19
206.7502 -775 925 412 55
206.7503 -790 126 411 16
206.7504 -819 473 410 52
206.7505 -232 597 409 0
206.7506 -784 138 408 70
206.7507 -517 924 407 42
206.7508 -576 43 406 78
206.7509 -99 950 405 32
206.7510 -864 533 404 58
206.7511 -322 636 403 74
206.7512 -798 389 402 51
206.7513 -653 644 401 98
206.7514 -875 514 400 97
206.7515 -458 302 399 58
206.7516 -214 278 398 44
206.7517 -880 640 397 26
206.7518 -92 463 396 94
206.7519 -417 739 395 47
206.7520 -897 844 394 23
206.7521 -246 224 393 54
206.7522 -745 530 392 52
206.7523 -129 13 391 14
206.7524 -212 385 390 77
206.7525 -24 138 389 41
206.7526 -637 182 388 24
206.7527 -176 325 387 33
206.7528 -723 464 386 78
206.7529 -895 241 385 67
206.7530 -619 693 384 52
206.7531 -694 17 383 65
206.7532 -517 378 382 50
206.7533 -627 367 381 61
206.7534 -247 360 380 91
206.7535 -956 174 379 18
206.7536 -856 909 378 38
206.7537 -860 545 377 46
206.7538 -222 112 376 45
206.7539 -547 155 375 82
206.7540 -675 870 374 27
206.7541 -639 148 373 92
206.7542 -11 886 372 17
206.7543 -6 698 371 88
206.7544 -186 729 370 38
206.7545 -264 801 369 29
206.7546 -363 925 368 9
206.7547 -432 8 367 99
206.7548 -957 624 366 63
206.7549 -285 552 365 67
206.7550 -721 350 364 87
206.7551 -261 748 363 3
206.7552 -188 287 362 62
206.7553 -968 508 361 0
206.7554 -928 89 360 82
206.7555 -875 191 359 92
206.7556 -916 103 358 90
206.7557 -384 358 357 93
206.7558 -71 962 356 47
206.7559 -202 803 355 67
206.7560 -601 835 354 56
206.7561 -461 408 353 45
206.7562 -778 622 352 7
206.7563 -419 183 351 21
206.7564 -897 899 350 3
206.7565 -88 20 349 5
206.7566 -745 970 348 95
206.7567 -395 455 347 53
206.7568 -159 802 346 31
206.7569 -967 109 345 86
206.7570 -426 103 344 60
206.7571 -786 386 343 14
206.7572 -438 853 342 68
206.7573 -284 180 341 35
206.7574 -879 986 340 52
206.7575 -50 94 339 80
206.7576 -514 426 338 34
206.7577 -653 219 337 34
206.7578 -693 444 336 23
206.7579 -5 268 335 19
206.7580 -717 460 334 54
206.7581 -532 457 333 64
206.7582 -673 323 332 34
206.7583 -193 837 331 15
206.7584 -892 711 330 40
206.7585 -667 465 329 82
206.7586 -207 994 328 53
206.7587 -775 112 327 86
206.7588 -175 44 326 95
206.7589 -808 650 325 68
206.7590 -2 900 324 28
206.7591 -133 293 323 18
206.7592 -485 192 322 85
206.7593 -126 749 321 48
206.7594 -246 576 320 30
206.7595 -471 292 319 22
206.7596 -881 674 318 46
206.7597 -68 901 317 43
206.7598 -394 272 316 59
206.7599 -749 398 315 36
206.7600 -607 104 314 80
206.7601 -100 325 313 86
206.7602 -443 378 312 64
206.7603 -172 178 311 35
206.7604 -284 76 310 88
206.7605 -617 763 309 77
206.7606 -773 28 308 59
206.7607 -629 832 307 81
206.7608 -873 232 306 67
206.7609 -294 561 305 64
206.7610 -778 936 304 14
206.7611 -947 221 303 50
206.7612 -199 287 302 65
206.7613 -102 479 301 27
206.7614 -312 105 300 88
206.7615 -735 184 299 66
206.7616 -195 777 298 84
206.7617 -599 139 297 14
206.7618 -671 29 296 75
206.7619 -624 502 295 57
206.7620 -714 635 294 51
206.7621 -934 849 293 83
206.7622 -807 387 292 74
206.7623 -374 381 291 9
206.7624 -921 221 290 78
206.7625 -406 822 289 57
206.7626 -638 700 288 53
206.7627 -109 387 287 59
206.7628 -527 177 286 92
206.7629 -867 62 285 4
206.7630 -785 684 284 91
206.7631 -461 84 283 78
206.7632 -5 649 282 12
206.7633 -160 308 281 43
206.7634 -399 211 280 45
206.7635 -122 38 279 51
206.7636 -312 943 278 76
206.7637 -210 668 277 52
206.7638 -114 880 276 58
206.7639 -377 136 275 65
206.7640 -600 129 274 8
206.7641 -434 654 273 32
206.7642 -341 692 272 45
206.7643 -96 981 271 84
206.7644 -173 937 270 76
206.7645 -95 746 269 27
206.7646 -274 239 268 80
206.7647 -787 946 267 10
206.7648 -743 922 266 9
206.7649 -6 578 265 73
206.7650 -475 757 264 77
206.7651 -961 867 263 16
206.7652 -711 611 262 9
206.7653 -43 84 261 24
206.7654 -190 483 260 92
206.7655 -507 467 259 7
206.7656 -292 708 258 82
206.7657 -23 5 257 48
206.7658 -343 359 256 4
206.7659 -821 958 255 73
206.7660 -889 611 254 53
206.7661 -256 73 253 51
206.7662 -526 848 252 25
206.7663 -600 321 251 66
206.7664 -16 845 250 85
206.7665 -759 258 249 68
206.7666 -703 332 248 21
206.7667 -645 443 247 26
206.7668 -400 307 246 67
206.7669 -347 205 245 52
206.7670 -538 16 244 93
206.7671 -225 264 243 63
206.7672 -526 582 242 72
206.7673 -476 815 241 92
206.7674 -587 168 240 58
206.7675 -925 469 239 25
206.7676 -889 945 238 5
206.7677 -136 589 237 5
206.7678 -101 157 236 24
206.7679 -189 591 235 5
206.7680 -752 297 234 80
206.7681 -681 904 233 31
206.7682 -766 803 232 69
206.7683 -646 341 231 5
206.7684 -699 327 230 88
206.7685 -523 200 229 66
206.7686 -356 997 228 3
206.7687 -431 813 227 75
206.7688 -566 190 226 3
206.7689 -293 244 225 91
206.7690 -393 496 224 43
206.7691 -100 614 223 7
206.7692 -461 648 222 91
206.7693 -13 160 221 11
206.7694 -126 227 220 94
206.7695 -202 626 219 17
206.7696 -184 282 218 16
206.7697 -623 718 217 92
206.7698 -946 122 216 86
206.7699 -747 475 215 27
206.7700 -882 366 214 89
206.7701 -965 155 213 29
206.7702 -487 795 212 63
206.7703 -933 173 211 44
206.7704 -601 770 210 88
206.7705 -343 9 209 92
206.7706 -563 242 208 1
206.7707 -596 58 207 56
206.7708 -646 592 206 67
206.7709 -109 373 205 19
206.7710 -210 606 204 86
206.7711 -360 653 203 91
206.7712 -622 191 202 47
206.7713 -402 560 201 55
206.7714 -761 963 200 33
206.7715 -766 904 199 25
206.7716 -183 458 198 78
206.7717 -466 884 197 96
206.7718 -219 477 196 94
206.7719 -767 333 195 53
206.7720 -952 948 194 89
206.7721 -462 438 193 85
206.7722 -630 923 192 73
206.7723 -597 222 191 21
206.7724 -58 74 190 64
206.7725 -446 477 189 99
206.7726 -573 812 188 58
206.7727 -406 17 187 71
206.7728 -143 413 186 24
206.7729 -384 637 185 45
206.7730 -510 48 184 81
206.7731 -515 112 183 48
206.7732 -700 518 182 83
206.7733 -148 579 181 3
206.7734 -596 645 180 53
206.7735 -664 412 179 61
206.7736 -795 865 178 87
206.7737 -604 470 177 16
206.7738 -775 794 176 26
206.7739 -589 637 175 75
206.7740 -935 324 174 87
206.7741 -594 657 173 99
206.7742 -939 799 172 81
206.7743 -933 494 171 55
206.7744 -233 926 170 55
206.7745 -547 738 169 93
206.7746 -394 706 168 86
206.7747 -675 904 167 19
206.7748 -157 503 166 82
206.7749 -313 885 165 18
206.7750 -667 879 164 65
206.7751 -857 181 163 34
206.7752 -305 261 162 65
206.7753 -567 1 161 0
206.7754 -187 618 160 70
206.7755 -32 63 159 68
206.7756 -801 677 158 15
206.7757 -400 362 157 71
206.7758 -618 642 156 51
206.7759 -6 532 155 84
206.7760 -697 311 154 64
206.7761 -919 685 153 80
206.7762 -260 649 152 55
206.7763 -382 305 151 73
206.7764 -555 14 150 38
206.7765 -385 532 149 15
206.7766 -315 434 148 23
206.7767 -719 200 147 40
206.7768 -109 674 146 78
206.7769 -221 198 145 61
206.7770 -625 836 144 30
206.7771 -36 257 143 77
206.7772 -344 814 142 65
206.7773 -290 357 141 87
206.7774 -481 225 140 82
206.7775 -98 923 139 16
206.7776 -233 829 138 7
206.7777 -525 618 137 59
206.7778 -476 169 136 60
206.7779 -361 304 135 88
206.7780 -578 529 134 59
206.7781 -442 119 133 58
206.7782 -457 780 132 69
206.7783 -131 51 131 5
206.7784 -301 657 130 80
206.7785 -93 99 129 38
206.7786 -210 473 128 86
206.7787 -449 986 127 70
206.7788 -865 721 126 4
206.7789 -774 293 125 11
206.7790 -410 5 124 78
206.7791 -338 897 123 13
206.7792 -729 638 122 98
206.7793 -394 244 121 32
206.7794 -557 426 120 82
206.7795 -625 517 119 20
206.7796 -487 157 118 88
206.7797 -265 658 117 76
206.7798 -427 934 116 58
206.7799 -288 331 115 9
206.7800 -107 647 114 36
206.7801 -258 151 113 7
206.7802 -394 658 112 60
206.7803 -818 496 111 33
206.7804 -908 622 110 83
206.7805 -360 324 109 93
206.7806 -498 121 108 13
206.7807 -724 178 107 22
206.7808 -603 492 106 83
206.7809 -684 727 105 13
206.7810 -495 291 104 18
206.7811 -492 463 103 84
206.7812 -162 273 102 86
206.7813 -873 498 101 57
206.7814 -297 904 100 90
206.7815 -203 793 99 54
206.7816 -943 916 98 86
206.7817 -685 383 97 77
206.7818 -764 699 96 12
206.7819 -436 958 95 91
206.7820 -827 331 94 18
206.7821 -189 984 93 0
206.7822 -775 288 92 32
206.7823 -593 666 91 28
206.7824 -111 361 90 57
206.7825 -877 686 89 9
206.7826 -532 87 88 26
206.7827 -684 653 87 25
206.7828 -740 202 86 92
206.7829 -627 730 85 32
206.7830 -347 184 84 60
206.7831 -695 673 83 63
206.7832 -621 40 82 41
206.7833 -304 712 81 18
206.7834 -675 482 80 48
206.7835 -598 833 79 23
206.7836 -434 3 78 34
206.7837 -450 336 77 84
206.7838 -471 592 76 94
206.7839 -546 719 75 11
206.7840 -510 971 74 28
206.7841 -633 223 73 65
206.7842 -328 231 72 7
206.7843 -229 700 71 31
206.7844 -649 248 70 62
206.7845 -830 888 69 7
206.7846 -666 497 68 16
206.7847 -743 903 67 98
206.7848 -873 831 66 97
206.7849 -747 833 65 92
206.7850 -747 628 64 3
206.7851 -992 576 63 87
206.7852 -530 757 62 30
206.7853 -452 687 61 9
206.7854 -359 552 60 57
206.7855 -391 913 59 81
206.7856 -593 180 58 16
206.7857 -72 4 57 92
206.7858 -997 54 56 87
206.7859 -204 889 55 12
206.7860 -51 157 54 99
206.7861 -819 573 53 75
206.7862 -69 204 52 46
206.7863 -134 520 51 7
206.7864 -639 759 50 9
206.7865 -732 656 49 96
206.7866 -176 240 48 79
206.7867 -950 52 47 52
206.7868 -164 745 46 7
206.7869 -732 125 45 79
206.7870 -584 244 44 15
206.7871 -368 294 43 23
206.7872 -684 383 42 74
206.7873 -760 984 41 93
206.7874 -103 126 40 49
206.7875 -416 169 39 90
206.7876 -187 276 38 55
206.7877 -307 447 37 22
206.7878 -619 281 36 78
206.7879 -881 641 35 43
206.7880 -950 920 34 14
206.7881 -910 482 33 21
206.7882 -398 814 32 68
206.7883 -858 439 31 92
206.7884 -956 588 30 65
206.7885 -893 350 29 68
206.7886 -829 330 28 22
206.7887 -165 440 27 88
206.7888 -639 354 26 68
206.7889 -720 284 25 73
206.7890 -437 931 24 93
206.7891 -667 531 23 3
206.7892 -375 760 22 51
206.7893 -850 266 21 53
206.7894 -238 970 20 90
206.7895 -20 457 19 6
206.7896 -890 348 18 6
206.7897 -86 192 17 66
206.7898 -69 949 16 52
206.7899 -352 807 15 91
206.7900 -400 891 14 28
206.7901 -771 526 13 76
206.7902 -493 972 12 29
206.7903 -296 637 11 52
206.7904 -512 839 10 61
206.7905 -108 998 9 21
206.7906 -156 400 8 12
206.7907 -242 137 7 80
206.7908 -141 606 6 1
206.7909 -916 635 5 71
206.7910 -364 513 4 95
206.7911 -553 477 3 62
206.7912 -335 768 2 27
206.7913 -798 911 1 19
206.7914 -840 394 0 78
206.7915 -@nodes
206.7916 -source 252
206.7917 -@end
207.1 --- a/src/test/error_test.cc Sat May 21 21:04:57 2005 +0000
207.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
207.3 @@ -1,65 +0,0 @@
207.4 -/* -*- C++ -*-
207.5 - * src/test/error_test.cc - Part of LEMON, a generic C++ optimization library
207.6 - *
207.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
207.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
207.9 - *
207.10 - * Permission to use, modify and distribute this software is granted
207.11 - * provided that this copyright notice appears in all copies. For
207.12 - * precise terms see the accompanying LICENSE file.
207.13 - *
207.14 - * This software is provided "AS IS" with no warranty of any kind,
207.15 - * express or implied, and with no claim as to its suitability for any
207.16 - * purpose.
207.17 - *
207.18 - */
207.19 -
207.20 -#include <iostream>
207.21 -
207.22 -#include <lemon/error.h>
207.23 -#include "test_tools.h"
207.24 -using namespace lemon;
207.25 -using std::cout;
207.26 -using std::endl;
207.27 -
207.28 -void faulty_fn() {
207.29 - fault("This is a fault message");
207.30 -}
207.31 -
207.32 -void exception_fn() {
207.33 - throw Exception("This is a fn throwing excpt with some args: ")
207.34 - << 5 << ", " << 18;
207.35 -}
207.36 -
207.37 -void unfinished_fn() {
207.38 - FIXME("unfinished_fn() is unfinished!");
207.39 -}
207.40 -
207.41 -
207.42 -int main() {
207.43 - try {
207.44 - faulty_fn();
207.45 - check(false, "A faulty function did not fail.");
207.46 - }
207.47 - catch(const Exception &e) {
207.48 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
207.49 - }
207.50 -
207.51 - try {
207.52 - exception_fn();
207.53 - check(false, "The function did not throw Exception.");
207.54 - }
207.55 - catch(const Exception &e) {
207.56 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
207.57 - }
207.58 -
207.59 - try {
207.60 - unfinished_fn();
207.61 - check(false, "FIXME macro does not work.");
207.62 - }
207.63 - catch(const Exception &e) {
207.64 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
207.65 - }
207.66 -
207.67 - return 0;
207.68 -}
208.1 --- a/src/test/graph_adaptor_test.cc Sat May 21 21:04:57 2005 +0000
208.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
208.3 @@ -1,75 +0,0 @@
208.4 -/* -*- C++ -*-
208.5 - * src/test/graph_adaptor_test.cc - Part of LEMON, a generic C++ optimization library
208.6 - *
208.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
208.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
208.9 - *
208.10 - * Permission to use, modify and distribute this software is granted
208.11 - * provided that this copyright notice appears in all copies. For
208.12 - * precise terms see the accompanying LICENSE file.
208.13 - *
208.14 - * This software is provided "AS IS" with no warranty of any kind,
208.15 - * express or implied, and with no claim as to its suitability for any
208.16 - * purpose.
208.17 - *
208.18 - */
208.19 -
208.20 -#include<iostream>
208.21 -#include<lemon/concept_check.h>
208.22 -
208.23 -#include<lemon/smart_graph.h>
208.24 -#include<lemon/concept/graph.h>
208.25 -#include<lemon/concept/undir_graph.h>
208.26 -
208.27 -#include<lemon/list_graph.h>
208.28 -#include<lemon/full_graph.h>
208.29 -#include<lemon/graph_adaptor.h>
208.30 -
208.31 -#include"test/test_tools.h"
208.32 -#include"test/graph_test.h"
208.33 -
208.34 -/**
208.35 -\file
208.36 -This test makes consistency checks of graph adaptors.
208.37 -
208.38 -\todo More extensive tests are needed
208.39 -*/
208.40 -
208.41 -using namespace lemon;
208.42 -using namespace lemon::concept;
208.43 -
208.44 -
208.45 -
208.46 -int main()
208.47 -{
208.48 - {
208.49 - typedef StaticGraph Graph;
208.50 - checkConcept<StaticGraph, GraphAdaptor<Graph> >();
208.51 -
208.52 - checkConcept<StaticGraph, RevGraphAdaptor<Graph> >();
208.53 -
208.54 - checkConcept<StaticGraph, SubGraphAdaptor<Graph,
208.55 - Graph::NodeMap<bool> , Graph::EdgeMap<bool> > >();
208.56 - checkConcept<StaticGraph, NodeSubGraphAdaptor<Graph,
208.57 - Graph::NodeMap<bool> > >();
208.58 - checkConcept<StaticGraph, EdgeSubGraphAdaptor<Graph,
208.59 - Graph::EdgeMap<bool> > >();
208.60 -
208.61 - checkConcept<StaticGraph, SubBidirGraphAdaptor<Graph,
208.62 - Graph::EdgeMap<bool>, Graph::EdgeMap<bool> > >();
208.63 - // checkConcept<StaticGraph, BidirGraph<Graph> >();
208.64 - checkConcept<StaticGraph, ResGraphAdaptor<Graph, int,
208.65 - Graph::EdgeMap<int>, Graph::EdgeMap<int> > >();
208.66 -
208.67 - checkConcept<StaticGraph, ErasingFirstGraphAdaptor<Graph,
208.68 - Graph::NodeMap<Graph::Edge> > >();
208.69 -
208.70 - /// \bug why does not compile with StaticGraph
208.71 - checkConcept<BaseIterableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
208.72 - checkConcept<IterableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
208.73 - checkConcept<MappableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
208.74 - }
208.75 - std::cout << __FILE__ ": All tests passed.\n";
208.76 -
208.77 - return 0;
208.78 -}
209.1 --- a/src/test/graph_factory_test.cc Sat May 21 21:04:57 2005 +0000
209.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
209.3 @@ -1,154 +0,0 @@
209.4 -/* -*- C++ -*-
209.5 - * src/test/graph_test.cc - Part of LEMON, a generic C++ optimization library
209.6 - *
209.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
209.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
209.9 - *
209.10 - * Permission to use, modify and distribute this software is granted
209.11 - * provided that this copyright notice appears in all copies. For
209.12 - * precise terms see the accompanying LICENSE file.
209.13 - *
209.14 - * This software is provided "AS IS" with no warranty of any kind,
209.15 - * express or implied, and with no claim as to its suitability for any
209.16 - * purpose.
209.17 - *
209.18 - */
209.19 -
209.20 -#include<iostream>
209.21 -#include<lemon/smart_graph.h>
209.22 -#include<lemon/concept/graph.h>
209.23 -#include<lemon/concept/maps.h>
209.24 -#include<lemon/list_graph_base.h>
209.25 -#include<lemon/full_graph.h>
209.26 -
209.27 -#include"test_tools.h"
209.28 -#include"graph_test.h"
209.29 -
209.30 -/**
209.31 -\file
209.32 -This test makes consistency checks of list graph structures.
209.33 -
209.34 -G.addNode(), G.addEdge(), G.source(), G.target()
209.35 -
209.36 -\todo Checks for empty graphs and isolated points.
209.37 -conversion.
209.38 -*/
209.39 -
209.40 -using namespace lemon;
209.41 -
209.42 -template<class Graph> void bidirPetersen(Graph &G)
209.43 -{
209.44 - typedef typename Graph::Edge Edge;
209.45 - typedef typename Graph::EdgeIt EdgeIt;
209.46 -
209.47 - checkGraphEdgeList(G,15);
209.48 -
209.49 - std::vector<Edge> ee;
209.50 -
209.51 - for(EdgeIt e(G);e!=INVALID;++e) ee.push_back(e);
209.52 -
209.53 - for(typename std::vector<Edge>::iterator p=ee.begin();p!=ee.end();p++)
209.54 - G.addEdge(G.target(*p),G.source(*p));
209.55 -}
209.56 -
209.57 -template<class Graph> void checkPetersen(Graph &G)
209.58 -{
209.59 - typedef typename Graph::Node Node;
209.60 -
209.61 - typedef typename Graph::EdgeIt EdgeIt;
209.62 - typedef typename Graph::NodeIt NodeIt;
209.63 -
209.64 - checkGraphNodeList(G,10);
209.65 - checkGraphEdgeList(G,30);
209.66 -
209.67 - for(NodeIt n(G);n!=INVALID;++n) {
209.68 - checkGraphInEdgeList(G,n,3);
209.69 - checkGraphOutEdgeList(G,n,3);
209.70 - }
209.71 -}
209.72 -
209.73 -//Compile Graph
209.74 -template void lemon::concept::checkCompileStaticGraph<concept::StaticGraph>
209.75 -(concept::StaticGraph &);
209.76 -
209.77 -template
209.78 -void lemon::concept::checkCompileExtendableGraph<concept::ExtendableGraph>
209.79 -(concept::ExtendableGraph &);
209.80 -
209.81 -template
209.82 -void lemon::concept::checkCompileErasableGraph<concept::ErasableGraph>
209.83 -(concept::ErasableGraph &);
209.84 -
209.85 -//Compile SmartGraph
209.86 -template
209.87 -void lemon::concept::checkCompileExtendableGraph<SmartGraph>(SmartGraph &);
209.88 -template
209.89 -void lemon::concept::checkCompileGraphFindEdge<SmartGraph>(SmartGraph &);
209.90 -
209.91 -//Compile SymSmartGraph
209.92 -//template void hugo::checkCompileGraph<SymSmartGraph>(SymSmartGraph &);
209.93 -//template void hugo::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
209.94 -
209.95 -//Compile ListGraph
209.96 -template
209.97 -void lemon::concept::checkCompileExtendableGraph<ListGraph>(ListGraph &);
209.98 -template
209.99 -void lemon::concept::checkCompileErasableGraph<ListGraph>(ListGraph &);
209.100 -template
209.101 -void lemon::concept::checkCompileGraphFindEdge<ListGraph>(ListGraph &);
209.102 -
209.103 -
209.104 -//Compile SymListGraph
209.105 -//template void hugo::checkCompileGraph<SymListGraph>(SymListGraph &);
209.106 -//template void hugo::checkCompileErasableGraph<SymListGraph>(SymListGraph &);
209.107 -//template void hugo::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
209.108 -
209.109 -//Compile FullGraph
209.110 -template void lemon::concept::checkCompileStaticGraph<FullGraph>(FullGraph &);
209.111 -template
209.112 -void lemon::concept::checkCompileGraphFindEdge<FullGraph>(FullGraph &);
209.113 -
209.114 -
209.115 -int main()
209.116 -{
209.117 - {
209.118 - SmartGraph G;
209.119 - addPetersen(G);
209.120 - bidirPetersen(G);
209.121 - checkPetersen(G);
209.122 - }
209.123 - {
209.124 - ListGraph G;
209.125 - addPetersen(G);
209.126 - bidirPetersen(G);
209.127 - checkPetersen(G);
209.128 - }
209.129 - {
209.130 - // SymSmartGraph G;
209.131 - // addPetersen(G);
209.132 - // checkPetersen(G);
209.133 - }
209.134 - {
209.135 - // SymListGraph G;
209.136 - // addPetersen(G);
209.137 - // checkPetersen(G);
209.138 - }
209.139 -
209.140 - ///\file
209.141 - ///\todo map tests.
209.142 - ///\todo copy constr tests.
209.143 -
209.144 -
209.145 - // Some map tests.
209.146 - // FIXME: These shouldn't be here.
209.147 - using namespace concept;
209.148 - function_requires< ReadMapConcept< ReadMap<int,int> > >();
209.149 - function_requires< WriteMapConcept< WriteMap<int,int> > >();
209.150 - function_requires< ReadWriteMapConcept< ReadWriteMap<int,int> > >();
209.151 - function_requires< ReferenceMapConcept< ReferenceMap<int,int> > >();
209.152 -
209.153 -
209.154 - std::cout << __FILE__ ": All tests passed.\n";
209.155 -
209.156 - return 0;
209.157 -}
210.1 --- a/src/test/graph_test.cc Sat May 21 21:04:57 2005 +0000
210.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
210.3 @@ -1,66 +0,0 @@
210.4 -// -*- c++ -*-
210.5 -
210.6 -#include <iostream>
210.7 -#include <vector>
210.8 -
210.9 -#include <lemon/concept/graph.h>
210.10 -#include <lemon/list_graph.h>
210.11 -#include <lemon/smart_graph.h>
210.12 -#include <lemon/full_graph.h>
210.13 -
210.14 -#include "test_tools.h"
210.15 -#include "graph_test.h"
210.16 -#include "map_test.h"
210.17 -
210.18 -
210.19 -using namespace lemon;
210.20 -using namespace lemon::concept;
210.21 -
210.22 -
210.23 -int main() {
210.24 - { // checking graph components
210.25 - checkConcept<BaseGraphComponent, BaseGraphComponent >();
210.26 -
210.27 - checkConcept<BaseIterableGraphComponent, BaseIterableGraphComponent >();
210.28 -
210.29 - checkConcept<IDableGraphComponent, IDableGraphComponent >();
210.30 - checkConcept<MaxIDableGraphComponent, MaxIDableGraphComponent >();
210.31 -
210.32 - checkConcept<BaseExtendableGraphComponent, BaseExtendableGraphComponent >();
210.33 - checkConcept<BaseErasableGraphComponent, BaseErasableGraphComponent >();
210.34 -
210.35 - checkConcept<IterableGraphComponent, IterableGraphComponent >();
210.36 -
210.37 - checkConcept<MappableGraphComponent, MappableGraphComponent >();
210.38 -
210.39 - checkConcept<ExtendableGraphComponent, ExtendableGraphComponent >();
210.40 - checkConcept<ErasableGraphComponent, ErasableGraphComponent >();
210.41 - checkConcept<ClearableGraphComponent, ClearableGraphComponent >();
210.42 - }
210.43 - { // checking skeleton graphs
210.44 - checkConcept<StaticGraph, StaticGraph >();
210.45 - checkConcept<ExtendableGraph, ExtendableGraph >();
210.46 - checkConcept<ErasableGraph, ErasableGraph >();
210.47 - }
210.48 - { // checking list graph
210.49 - checkConcept<ErasableGraph, ListGraph >();
210.50 -
210.51 - checkGraph<ListGraph>();
210.52 - checkGraphNodeMap<ListGraph>();
210.53 - checkGraphEdgeMap<ListGraph>();
210.54 - }
210.55 - { // checking smart graph
210.56 - checkConcept<ExtendableGraph, SmartGraph >();
210.57 -
210.58 - checkGraph<SmartGraph>();
210.59 - checkGraphNodeMap<SmartGraph>();
210.60 - checkGraphEdgeMap<SmartGraph>();
210.61 - }
210.62 - { // checking full graph
210.63 - checkConcept<StaticGraph, FullGraph >();
210.64 - }
210.65 -
210.66 - std::cout << __FILE__ ": All tests passed.\n";
210.67 -
210.68 - return 0;
210.69 -}
211.1 --- a/src/test/graph_test.h Sat May 21 21:04:57 2005 +0000
211.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
211.3 @@ -1,90 +0,0 @@
211.4 -/* -*- C++ -*-
211.5 - * src/test/graph_test.h - Part of LEMON, a generic C++ optimization library
211.6 - *
211.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
211.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
211.9 - *
211.10 - * Permission to use, modify and distribute this software is granted
211.11 - * provided that this copyright notice appears in all copies. For
211.12 - * precise terms see the accompanying LICENSE file.
211.13 - *
211.14 - * This software is provided "AS IS" with no warranty of any kind,
211.15 - * express or implied, and with no claim as to its suitability for any
211.16 - * purpose.
211.17 - *
211.18 - */
211.19 -#ifndef LEMON_TEST_GRAPH_TEST_H
211.20 -#define LEMON_TEST_GRAPH_TEST_H
211.21 -
211.22 -
211.23 -#include "test_tools.h"
211.24 -
211.25 -//! \ingroup misc
211.26 -//! \file
211.27 -//! \brief Some utility and test cases to test graph classes.
211.28 -namespace lemon {
211.29 -
211.30 - template<class Graph> void checkGraphNodeList(Graph &G, int nn)
211.31 - {
211.32 - typename Graph::NodeIt n(G);
211.33 - for(int i=0;i<nn;i++) {
211.34 - check(n!=INVALID,"Wrong Node list linking.");
211.35 - ++n;
211.36 - }
211.37 - check(n==INVALID,"Wrong Node list linking.");
211.38 - }
211.39 -
211.40 - template<class Graph>
211.41 - void checkGraphEdgeList(Graph &G, int nn)
211.42 - {
211.43 - typedef typename Graph::EdgeIt EdgeIt;
211.44 -
211.45 - EdgeIt e(G);
211.46 - for(int i=0;i<nn;i++) {
211.47 - check(e!=INVALID,"Wrong Edge list linking.");
211.48 - ++e;
211.49 - }
211.50 - check(e==INVALID,"Wrong Edge list linking.");
211.51 - }
211.52 -
211.53 - template<class Graph>
211.54 - void checkGraphOutEdgeList(Graph &G, typename Graph::Node n, int nn)
211.55 - {
211.56 - typename Graph::OutEdgeIt e(G,n);
211.57 - for(int i=0;i<nn;i++) {
211.58 - check(e!=INVALID,"Wrong OutEdge list linking.");
211.59 - check(n==G.source(e), "Wrong OutEdge list linking.");
211.60 - ++e;
211.61 - }
211.62 - check(e==INVALID,"Wrong OutEdge list linking.");
211.63 - }
211.64 -
211.65 - template<class Graph> void
211.66 - checkGraphInEdgeList(Graph &G, typename Graph::Node n, int nn)
211.67 - {
211.68 - typename Graph::InEdgeIt e(G,n);
211.69 - for(int i=0;i<nn;i++) {
211.70 - check(e!=INVALID,"Wrong InEdge list linking.");
211.71 - check(n==G.target(e), "Wrong InEdge list linking.");
211.72 - ++e;
211.73 - }
211.74 - check(e==INVALID,"Wrong InEdge list linking.");
211.75 - }
211.76 -
211.77 - template <class Graph>
211.78 - void checkGraph() {
211.79 - const int num = 5;
211.80 - Graph G;
211.81 - addPetersen(G, num);
211.82 - bidirGraph(G);
211.83 - checkBidirPetersen(G, num);
211.84 - }
211.85 -
211.86 - ///\file
211.87 - ///\todo Check target(), source() as well;
211.88 -
211.89 -
211.90 -} //namespace lemon
211.91 -
211.92 -
211.93 -#endif
212.1 --- a/src/test/graph_utils_test.cc Sat May 21 21:04:57 2005 +0000
212.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
212.3 @@ -1,37 +0,0 @@
212.4 -// -*- c++ -*-
212.5 -
212.6 -#include <iostream>
212.7 -#include <vector>
212.8 -
212.9 -#include <lemon/graph_utils.h>
212.10 -
212.11 -#include <lemon/list_graph.h>
212.12 -#include <lemon/smart_graph.h>
212.13 -#include <lemon/full_graph.h>
212.14 -
212.15 -#include "test_tools.h"
212.16 -#include "graph_utils_test.h"
212.17 -
212.18 -
212.19 -using namespace lemon;
212.20 -
212.21 -
212.22 -int main() {
212.23 - ///\file
212.24 - { // checking list graph
212.25 - checkGraphCounters<ListGraph>();
212.26 - }
212.27 - { // checking smart graph
212.28 - checkGraphCounters<SmartGraph>();
212.29 - }
212.30 - {
212.31 - int num = 5;
212.32 - FullGraph fg(num);
212.33 - check(countNodes(fg) == num, "FullGraph: wrong node number.");
212.34 - check(countEdges(fg) == num*num, "FullGraph: wrong edge number.");
212.35 - }
212.36 -
212.37 - std::cout << __FILE__ ": All tests passed.\n";
212.38 -
212.39 - return 0;
212.40 -}
213.1 --- a/src/test/graph_utils_test.h Sat May 21 21:04:57 2005 +0000
213.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
213.3 @@ -1,44 +0,0 @@
213.4 -/* -*- C++ -*-
213.5 - * src/test/graph_utils_test.h - Part of LEMON, a generic C++ optimization library
213.6 - *
213.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
213.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
213.9 - *
213.10 - * Permission to use, modify and distribute this software is granted
213.11 - * provided that this copyright notice appears in all copies. For
213.12 - * precise terms see the accompanying LICENSE file.
213.13 - *
213.14 - * This software is provided "AS IS" with no warranty of any kind,
213.15 - * express or implied, and with no claim as to its suitability for any
213.16 - * purpose.
213.17 - *
213.18 - */
213.19 -#ifndef LEMON_TEST_GRAPH_UTILS_TEST_H
213.20 -#define LEMON_TEST_GRAPH_UTILS_TEST_H
213.21 -
213.22 -
213.23 -#include "test_tools.h"
213.24 -
213.25 -//! \ingroup misc
213.26 -//! \file
213.27 -//! \brief Test cases for graph utils.
213.28 -namespace lemon {
213.29 -
213.30 - template <typename Graph>
213.31 - void checkGraphCounters() {
213.32 - const int num = 5;
213.33 - Graph graph;
213.34 - addPetersen(graph, num);
213.35 - bidirGraph(graph);
213.36 - check(countNodes(graph) == 2*num, "Wrong node number.");
213.37 - check(countEdges(graph) == 6*num, "Wrong edge number.");
213.38 - for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
213.39 - check(countOutEdges(graph, it) == 3, "Wrong out degree number.");
213.40 - check(countInEdges(graph, it) == 3, "Wrong in degree number.");
213.41 - }
213.42 - }
213.43 -
213.44 -} //namespace lemon
213.45 -
213.46 -
213.47 -#endif
214.1 --- a/src/test/heap_test.cc Sat May 21 21:04:57 2005 +0000
214.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
214.3 @@ -1,98 +0,0 @@
214.4 -// -*- c++ -*-
214.5 -
214.6 -#include <iostream>
214.7 -#include <fstream>
214.8 -#include <string>
214.9 -#include <vector>
214.10 -
214.11 -#include <lemon/concept_check.h>
214.12 -#include <lemon/concept/heap.h>
214.13 -
214.14 -#include <lemon/smart_graph.h>
214.15 -
214.16 -#include <lemon/graph_reader.h>
214.17 -
214.18 -#include <lemon/bin_heap.h>
214.19 -#include <lemon/fib_heap.h>
214.20 -#include <lemon/radix_heap.h>
214.21 -
214.22 -#include "test_tools.h"
214.23 -
214.24 -#include "heap_test.h"
214.25 -
214.26 -
214.27 -using namespace lemon;
214.28 -using namespace lemon::concept;
214.29 -
214.30 -
214.31 -int main() {
214.32 -
214.33 - typedef int Item;
214.34 - typedef int Prio;
214.35 - typedef IntIntMap ItemIntMap;
214.36 -
214.37 - typedef ListGraph Graph;
214.38 -
214.39 - typedef Graph::Edge Edge;
214.40 - typedef Graph::Node Node;
214.41 - typedef Graph::EdgeIt EdgeIt;
214.42 - typedef Graph::NodeIt NodeIt;
214.43 - typedef Graph::EdgeMap<int> LengthMap;
214.44 -
214.45 - Graph graph;
214.46 - LengthMap length(graph);
214.47 - Node start;
214.48 -
214.49 - /// \todo create own test graph
214.50 -
214.51 - std::string f_name;
214.52 - if( getenv("srcdir") )
214.53 - f_name = std::string(getenv("srcdir"));
214.54 - else f_name = ".";
214.55 - f_name += "/dijkstra_test.lgf";
214.56 -
214.57 - std::ifstream input(f_name.c_str());
214.58 - check(input, "Input file '" << f_name << "' not found.");
214.59 - readGraph(input, graph, length, start);
214.60 -
214.61 - {
214.62 - std::cerr << "Checking Bin Heap" << std::endl;
214.63 -
214.64 - typedef BinHeap<Item, Prio, ItemIntMap> IntHeap;
214.65 - checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
214.66 - heapSortTest<IntHeap>(100);
214.67 - heapIncreaseTest<IntHeap>(100);
214.68 -
214.69 - typedef FibHeap<Node, Prio, Graph::NodeMap<int> > NodeHeap;
214.70 - checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
214.71 - dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
214.72 - }
214.73 - {
214.74 - std::cerr << "Checking Fib Heap" << std::endl;
214.75 -
214.76 - typedef FibHeap<Item, Prio, ItemIntMap> IntHeap;
214.77 - checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
214.78 - heapSortTest<IntHeap>(100);
214.79 - heapIncreaseTest<IntHeap>(100);
214.80 -
214.81 - typedef FibHeap<Node, Prio, Graph::NodeMap<int> > NodeHeap;
214.82 - checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
214.83 - dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
214.84 - }
214.85 - {
214.86 - std::cerr << "Checking Radix Heap" << std::endl;
214.87 -
214.88 - typedef RadixHeap<Item, ItemIntMap> IntHeap;
214.89 - checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
214.90 - heapSortTest<IntHeap>(100);
214.91 - heapIncreaseTest<IntHeap>(100);
214.92 -
214.93 - typedef RadixHeap<Node, Graph::NodeMap<int> > NodeHeap;
214.94 - checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
214.95 - dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
214.96 - }
214.97 -
214.98 - std::cout << __FILE__ ": All tests passed.\n";
214.99 -
214.100 - return 0;
214.101 -}
215.1 --- a/src/test/heap_test.h Sat May 21 21:04:57 2005 +0000
215.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
215.3 @@ -1,110 +0,0 @@
215.4 -// -+- c++ -+-
215.5 -
215.6 -#include <vector>
215.7 -#include <algorithm>
215.8 -
215.9 -#include <lemon/dijkstra.h>
215.10 -
215.11 -class IntIntMap : public std::vector<int> {
215.12 -public:
215.13 - typedef std::vector<int> Parent;
215.14 -
215.15 - IntIntMap() : Parent() {}
215.16 - IntIntMap(int n) : Parent(n) {}
215.17 - IntIntMap(int n, int v) : Parent(n, v) {}
215.18 -
215.19 - void set(int key, int value) {
215.20 - Parent::operator[](key) = value;
215.21 - }
215.22 -};
215.23 -
215.24 -
215.25 -template <typename _Heap>
215.26 -void heapSortTest(int n) {
215.27 - typedef _Heap Heap;
215.28 - IntIntMap map(n, -1);
215.29 -
215.30 - Heap heap(map);
215.31 -
215.32 - std::vector<int> v(n);
215.33 -
215.34 - for (int i = 0; i < n; ++i) {
215.35 - v[i] = rand() % 1000;
215.36 - heap.push(i, v[i]);
215.37 - }
215.38 - std::sort(v.begin(), v.end());
215.39 - for (int i = 0; i < n; ++i) {
215.40 - check(v[i] == heap.prio() ,"Wrong order in heap sort.");
215.41 - heap.pop();
215.42 - }
215.43 -}
215.44 -
215.45 -template <typename _Heap>
215.46 -void heapIncreaseTest(int n) {
215.47 - typedef _Heap Heap;
215.48 - IntIntMap map(n, -1);
215.49 -
215.50 - Heap heap(map);
215.51 -
215.52 - std::vector<int> v(n);
215.53 -
215.54 - for (int i = 0; i < n; ++i) {
215.55 - v[i] = rand() % 1000;
215.56 - heap.push(i, v[i]);
215.57 - }
215.58 - for (int i = 0; i < n; ++i) {
215.59 - v[i] += rand() % 1000;
215.60 - heap.increase(i, v[i]);
215.61 - }
215.62 - std::sort(v.begin(), v.end());
215.63 - for (int i = 0; i < n; ++i) {
215.64 - check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
215.65 - heap.pop();
215.66 - }
215.67 -}
215.68 -
215.69 -
215.70 -
215.71 -template <typename _Traits, typename _Heap>
215.72 -struct DefHeapTraits : public _Traits {
215.73 - typedef _Heap Heap;
215.74 -};
215.75 -
215.76 -template <typename _Graph, typename _LengthMap, typename _Heap>
215.77 -void dijkstraHeapTest(_Graph& graph, _LengthMap& length,
215.78 - typename _Graph::Node& start) {
215.79 -
215.80 - typedef _Heap Heap;
215.81 - typedef _Graph Graph;
215.82 - typedef _LengthMap LengthMap;
215.83 -
215.84 - typedef typename Graph::Node Node;
215.85 - typedef typename Graph::Edge Edge;
215.86 - typedef typename Graph::NodeIt NodeIt;
215.87 - typedef typename Graph::EdgeIt EdgeIt;
215.88 -
215.89 - Dijkstra<Graph, LengthMap,
215.90 - DefHeapTraits<DijkstraDefaultTraits<Graph, LengthMap>, Heap> >
215.91 - dijkstra(graph, length);
215.92 -
215.93 - dijkstra.run(start);
215.94 -
215.95 - for(EdgeIt e(graph); e!=INVALID; ++e) {
215.96 - Node u=graph.source(e);
215.97 - Node v=graph.target(e);
215.98 - if (dijkstra.reached(u)) {
215.99 - check( dijkstra.dist(v) - dijkstra.dist(u) <= length[e],
215.100 - "Error in a shortest path tree edge!");
215.101 - }
215.102 - }
215.103 -
215.104 - for(NodeIt v(graph); v!=INVALID; ++v) {
215.105 - if ( dijkstra.reached(v) && dijkstra.pred(v) != INVALID ) {
215.106 - Edge e=dijkstra.pred(v);
215.107 - Node u=graph.source(e);
215.108 - check( dijkstra.dist(v) - dijkstra .dist(u) == length[e],
215.109 - "Error in a shortest path tree edge!");
215.110 - }
215.111 - }
215.112 -
215.113 -}
216.1 --- a/src/test/kruskal_test.cc Sat May 21 21:04:57 2005 +0000
216.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
216.3 @@ -1,119 +0,0 @@
216.4 -/* -*- C++ -*-
216.5 - * src/test/kruskal_test.cc - Part of LEMON, a generic C++ optimization library
216.6 - *
216.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
216.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
216.9 - *
216.10 - * Permission to use, modify and distribute this software is granted
216.11 - * provided that this copyright notice appears in all copies. For
216.12 - * precise terms see the accompanying LICENSE file.
216.13 - *
216.14 - * This software is provided "AS IS" with no warranty of any kind,
216.15 - * express or implied, and with no claim as to its suitability for any
216.16 - * purpose.
216.17 - *
216.18 - */
216.19 -
216.20 -#include <iostream>
216.21 -#include <vector>
216.22 -
216.23 -#include "test_tools.h"
216.24 -#include <lemon/maps.h>
216.25 -#include <lemon/kruskal.h>
216.26 -#include <lemon/list_graph.h>
216.27 -#include <lemon/concept/maps.h>
216.28 -#include <lemon/concept/graph.h>
216.29 -
216.30 -
216.31 -using namespace std;
216.32 -using namespace lemon;
216.33 -
216.34 -void checkCompileKruskal()
216.35 -{
216.36 - concept::WriteMap<concept::StaticGraph::Edge,bool> w;
216.37 -
216.38 - kruskalEdgeMap(concept::StaticGraph(),
216.39 - concept::ReadMap<concept::StaticGraph::Edge,int>(),
216.40 - w);
216.41 -}
216.42 -
216.43 -int main() {
216.44 -
216.45 - typedef ListGraph::Node Node;
216.46 - typedef ListGraph::Edge Edge;
216.47 - typedef ListGraph::NodeIt NodeIt;
216.48 - typedef ListGraph::EdgeIt EdgeIt;
216.49 -
216.50 - ListGraph G;
216.51 -
216.52 - Node s=G.addNode();
216.53 - Node v1=G.addNode();
216.54 - Node v2=G.addNode();
216.55 - Node v3=G.addNode();
216.56 - Node v4=G.addNode();
216.57 - Node t=G.addNode();
216.58 -
216.59 - Edge e1 = G.addEdge(s, v1);
216.60 - Edge e2 = G.addEdge(s, v2);
216.61 - Edge e3 = G.addEdge(v1, v2);
216.62 - Edge e4 = G.addEdge(v2, v1);
216.63 - Edge e5 = G.addEdge(v1, v3);
216.64 - Edge e6 = G.addEdge(v3, v2);
216.65 - Edge e7 = G.addEdge(v2, v4);
216.66 - Edge e8 = G.addEdge(v4, v3);
216.67 - Edge e9 = G.addEdge(v3, t);
216.68 - Edge e10 = G.addEdge(v4, t);
216.69 -
216.70 - typedef ListGraph::EdgeMap<int> ECostMap;
216.71 - typedef ListGraph::EdgeMap<bool> EBoolMap;
216.72 -
216.73 - ECostMap edge_cost_map(G, 2);
216.74 - EBoolMap tree_map(G);
216.75 -
216.76 -
216.77 - //Test with const map.
216.78 - check(kruskalEdgeMap(G, ConstMap<ListGraph::Edge,int>(2), tree_map)==10,
216.79 - "Total cost should be 10");
216.80 - //Test with a edge map (filled with uniform costs).
216.81 - check(kruskalEdgeMap(G, edge_cost_map, tree_map)==10,
216.82 - "Total cost should be 10");
216.83 -
216.84 - edge_cost_map.set(e1, -10);
216.85 - edge_cost_map.set(e2, -9);
216.86 - edge_cost_map.set(e3, -8);
216.87 - edge_cost_map.set(e4, -7);
216.88 - edge_cost_map.set(e5, -6);
216.89 - edge_cost_map.set(e6, -5);
216.90 - edge_cost_map.set(e7, -4);
216.91 - edge_cost_map.set(e8, -3);
216.92 - edge_cost_map.set(e9, -2);
216.93 - edge_cost_map.set(e10, -1);
216.94 -
216.95 - vector<Edge> tree_edge_vec;
216.96 -
216.97 - //Test with a edge map and inserter.
216.98 - check(kruskalEdgeMap_IteratorOut(G, edge_cost_map,
216.99 - back_inserter(tree_edge_vec))
216.100 - ==-31,
216.101 - "Total cost should be -31.");
216.102 -
216.103 - tree_edge_vec.clear();
216.104 -
216.105 - //The above test could also be coded like this:
216.106 - check(kruskal(G,
216.107 - makeKruskalMapInput(G, edge_cost_map),
216.108 - makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
216.109 - ==-31,
216.110 - "Total cost should be -31.");
216.111 -
216.112 - check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
216.113 -
216.114 - check(tree_edge_vec[0]==e1 &&
216.115 - tree_edge_vec[1]==e2 &&
216.116 - tree_edge_vec[2]==e5 &&
216.117 - tree_edge_vec[3]==e7 &&
216.118 - tree_edge_vec[4]==e9,
216.119 - "Wrong tree.");
216.120 -
216.121 - return 0;
216.122 -}
217.1 --- a/src/test/lp_test.cc Sat May 21 21:04:57 2005 +0000
217.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
217.3 @@ -1,155 +0,0 @@
217.4 -#include<lemon/lp_skeleton.h>
217.5 -
217.6 -#ifdef HAVE_CONFIG_H
217.7 -#include <config.h>
217.8 -#endif
217.9 -
217.10 -#ifdef HAVE_GLPK
217.11 -#include <lemon/lp_glpk.h>
217.12 -#elif HAVE_CPLEX
217.13 -#include <lemon/lp_cplex.h>
217.14 -#endif
217.15 -
217.16 -using namespace lemon;
217.17 -
217.18 -#ifdef HAVE_GLPK
217.19 -typedef LpGlpk LpDefault;
217.20 -#elif HAVE_CPLEX
217.21 -typedef LpCplex LpDefault;
217.22 -#endif
217.23 -
217.24 -void lpTest(LpSolverBase & lp)
217.25 -{
217.26 - typedef LpSolverBase LP;
217.27 -
217.28 - std::vector<LP::Col> x(10);
217.29 - // for(int i=0;i<10;i++) x.push_back(lp.addCol());
217.30 - lp.addColSet(x);
217.31 -
217.32 - std::vector<LP::Col> y(10);
217.33 - lp.addColSet(y);
217.34 -
217.35 - std::map<int,LP::Col> z;
217.36 -
217.37 - z.insert(std::make_pair(12,INVALID));
217.38 - z.insert(std::make_pair(2,INVALID));
217.39 - z.insert(std::make_pair(7,INVALID));
217.40 - z.insert(std::make_pair(5,INVALID));
217.41 -
217.42 - lp.addColSet(z);
217.43 -
217.44 -
217.45 - LP::Expr e,f,g;
217.46 - LP::Col p1,p2,p3,p4,p5;
217.47 - LP::Constr c;
217.48 -
217.49 - e[p1]=2;
217.50 - e.constComp()=12;
217.51 - e[p1]+=2;
217.52 - e.constComp()+=12;
217.53 - e[p1]-=2;
217.54 - e.constComp()-=12;
217.55 -
217.56 - e=2;
217.57 - e=2.2;
217.58 - e=p1;
217.59 - e=f;
217.60 -
217.61 - e+=2;
217.62 - e+=2.2;
217.63 - e+=p1;
217.64 - e+=f;
217.65 -
217.66 - e-=2;
217.67 - e-=2.2;
217.68 - e-=p1;
217.69 - e-=f;
217.70 -
217.71 - e*=2;
217.72 - e*=2.2;
217.73 - e/=2;
217.74 - e/=2.2;
217.75 -
217.76 - e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
217.77 - (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
217.78 - (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
217.79 - 2.2*f+f*2.2+f/2.2+
217.80 - 2*f+f*2+f/2+
217.81 - 2.2*p1+p1*2.2+p1/2.2+
217.82 - 2*p1+p1*2+p1/2
217.83 - );
217.84 -
217.85 -
217.86 - c = (e <= f );
217.87 - c = (e <= 2.2);
217.88 - c = (e <= 2 );
217.89 - c = (e <= p1 );
217.90 - c = (2.2<= f );
217.91 - c = (2 <= f );
217.92 - c = (p1 <= f );
217.93 - c = (p1 <= p2 );
217.94 - c = (p1 <= 2.2);
217.95 - c = (p1 <= 2 );
217.96 - c = (2.2<= p2 );
217.97 - c = (2 <= p2 );
217.98 -
217.99 - c = (e >= f );
217.100 - c = (e >= 2.2);
217.101 - c = (e >= 2 );
217.102 - c = (e >= p1 );
217.103 - c = (2.2>= f );
217.104 - c = (2 >= f );
217.105 - c = (p1 >= f );
217.106 - c = (p1 >= p2 );
217.107 - c = (p1 >= 2.2);
217.108 - c = (p1 >= 2 );
217.109 - c = (2.2>= p2 );
217.110 - c = (2 >= p2 );
217.111 -
217.112 - c = (e == f );
217.113 - c = (e == 2.2);
217.114 - c = (e == 2 );
217.115 - c = (e == p1 );
217.116 - c = (2.2== f );
217.117 - c = (2 == f );
217.118 - c = (p1 == f );
217.119 - //c = (p1 == p2 );
217.120 - c = (p1 == 2.2);
217.121 - c = (p1 == 2 );
217.122 - c = (2.2== p2 );
217.123 - c = (2 == p2 );
217.124 -
217.125 - c = (2 <= e <= 3);
217.126 - c = (2 <= p1<= 3);
217.127 -
217.128 - c = (2 >= e >= 3);
217.129 - c = (2 >= p1>= 3);
217.130 -
217.131 - e[x[3]]=2;
217.132 - e[x[3]]=4;
217.133 - e[x[3]]=1;
217.134 - e.constComp()=12;
217.135 -
217.136 - lp.addRow(LP::INF,e,23);
217.137 - lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
217.138 - lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
217.139 -
217.140 - lp.addRow(x[1]+x[3]<=x[5]-3);
217.141 - lp.addRow(-7<=x[1]+x[3]-12<=3);
217.142 - lp.addRow(x[1]<=x[5]);
217.143 -
217.144 -
217.145 -
217.146 -}
217.147 -
217.148 -int main()
217.149 -{
217.150 - LpSkeleton lp_skel;
217.151 - lpTest(lp_skel);
217.152 -
217.153 - LpDefault lp;
217.154 -
217.155 - lpTest(lp);
217.156 -
217.157 - return 0;
217.158 -}
218.1 --- a/src/test/map_test.h Sat May 21 21:04:57 2005 +0000
218.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
218.3 @@ -1,95 +0,0 @@
218.4 -/* -*- C++ -*-
218.5 - * src/test/map_test.h - Part of LEMON, a generic C++ optimization library
218.6 - *
218.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
218.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
218.9 - *
218.10 - * Permission to use, modify and distribute this software is granted
218.11 - * provided that this copyright notice appears in all copies. For
218.12 - * precise terms see the accompanying LICENSE file.
218.13 - *
218.14 - * This software is provided "AS IS" with no warranty of any kind,
218.15 - * express or implied, and with no claim as to its suitability for any
218.16 - * purpose.
218.17 - *
218.18 - */
218.19 -#ifndef LEMON_TEST_MAP_TEST_H
218.20 -#define LEMON_TEST_MAP_TEST_H
218.21 -
218.22 -
218.23 -#include <vector>
218.24 -
218.25 -#include "test_tools.h"
218.26 -
218.27 -
218.28 -//! \ingroup misc
218.29 -//! \file
218.30 -//! \brief Some utilities to test map classes.
218.31 -
218.32 -namespace lemon {
218.33 -
218.34 -
218.35 - template <typename Graph>
218.36 - void checkGraphNodeMap() {
218.37 - Graph graph;
218.38 - const int num = 16;
218.39 -
218.40 - typedef typename Graph::Node Node;
218.41 -
218.42 - std::vector<Node> nodes;
218.43 - for (int i = 0; i < num; ++i) {
218.44 - nodes.push_back(graph.addNode());
218.45 - }
218.46 - typedef typename Graph::template NodeMap<int> IntNodeMap;
218.47 - IntNodeMap map(graph, 42);
218.48 - for (int i = 0; i < (int)nodes.size(); ++i) {
218.49 - check(map[nodes[i]] == 42, "Wrong map constructor.");
218.50 - }
218.51 - for (int i = 0; i < num; ++i) {
218.52 - nodes.push_back(graph.addNode());
218.53 - map[nodes.back()] = 23;
218.54 - }
218.55 - graph.clear();
218.56 - nodes.clear();
218.57 - }
218.58 -
218.59 - template <typename Graph>
218.60 - void checkGraphEdgeMap() {
218.61 - Graph graph;
218.62 - const int num = 16;
218.63 -
218.64 - typedef typename Graph::Node Node;
218.65 - typedef typename Graph::Edge Edge;
218.66 -
218.67 - std::vector<Node> nodes;
218.68 - for (int i = 0; i < num; ++i) {
218.69 - nodes.push_back(graph.addNode());
218.70 - }
218.71 -
218.72 - std::vector<Edge> edges;
218.73 - for (int i = 0; i < num; ++i) {
218.74 - for (int j = 0; j < i; ++j) {
218.75 - edges.push_back(graph.addEdge(nodes[i], nodes[j]));
218.76 - }
218.77 - }
218.78 -
218.79 - typedef typename Graph::template EdgeMap<int> IntEdgeMap;
218.80 - IntEdgeMap map(graph, 42);
218.81 -
218.82 - for (int i = 0; i < (int)edges.size(); ++i) {
218.83 - check(map[edges[i]] == 42, "Wrong map constructor.");
218.84 - }
218.85 -
218.86 - for (int i = 0; i < num; ++i) {
218.87 - for (int j = i + 1; j < num; ++j) {
218.88 - edges.push_back(graph.addEdge(nodes[i], nodes[j]));
218.89 - map[edges.back()] = 23;
218.90 - }
218.91 - }
218.92 - graph.clear();
218.93 - edges.clear();
218.94 - }
218.95 -
218.96 -}
218.97 -
218.98 -#endif
219.1 --- a/src/test/maps_test.cc Sat May 21 21:04:57 2005 +0000
219.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
219.3 @@ -1,57 +0,0 @@
219.4 -#include <lemon/concept_check.h>
219.5 -#include <lemon/concept/maps.h>
219.6 -#include <lemon/maps.h>
219.7 -
219.8 -#include "test_tools.h"
219.9 -
219.10 -using namespace lemon;
219.11 -using namespace lemon::concept;
219.12 -
219.13 -struct A {};
219.14 -struct B {};
219.15 -class F
219.16 -{
219.17 -public:
219.18 - B operator()(const A &) const {return B();}
219.19 -};
219.20 -
219.21 -int func(A) {return 3;}
219.22 -
219.23 -typedef ReadMap<A,double> DoubleMap;
219.24 -
219.25 -int main()
219.26 -{ // checking graph components
219.27 -
219.28 - checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
219.29 - checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
219.30 - checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
219.31 - checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
219.32 -
219.33 - checkConcept<ReadMap<A,double>, AddMap<DoubleMap,DoubleMap> >();
219.34 - checkConcept<ReadMap<A,double>, SubMap<DoubleMap,DoubleMap> >();
219.35 - checkConcept<ReadMap<A,double>, MulMap<DoubleMap,DoubleMap> >();
219.36 - checkConcept<ReadMap<A,double>, DivMap<DoubleMap,DoubleMap> >();
219.37 - checkConcept<ReadMap<A,double>, NegMap<DoubleMap> >();
219.38 - checkConcept<ReadMap<A,double>, AbsMap<DoubleMap> >();
219.39 - checkConcept<ReadMap<A,double>, ShiftMap<DoubleMap> >();
219.40 - checkConcept<ReadMap<A,double>, ScaleMap<DoubleMap> >();
219.41 -
219.42 - checkConcept<ReadMap<B,double>, ComposeMap<DoubleMap,ReadMap<B,A> > >();
219.43 -
219.44 - checkConcept<ReadMap<A,B>, FunctorMap<A,B,F> >();
219.45 -
219.46 - int a;
219.47 -
219.48 - a=mapFunctor(constMap<A,int>(2))(A());
219.49 - check(a==2,"Something is wrong with mapFunctor");
219.50 -
219.51 - B b;
219.52 - b=functorMap<A,B>(F())[A()];
219.53 -
219.54 - a=functorMap<A,int>(&func)[A()];
219.55 - check(a==3,"Something is wrong with functorMap");
219.56 -
219.57 - std::cout << __FILE__ ": All tests passed.\n";
219.58 -
219.59 - return 0;
219.60 -}
220.1 --- a/src/test/max_matching_test.cc Sat May 21 21:04:57 2005 +0000
220.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
220.3 @@ -1,183 +0,0 @@
220.4 -/* -*- C++ -*-
220.5 - * src/test/max_matching_test.cc -
220.6 - * Part of LEMON, a generic C++ optimization library
220.7 - *
220.8 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
220.9 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
220.10 - *
220.11 - * Permission to use, modify and distribute this software is granted
220.12 - * provided that this copyright notice appears in all copies. For
220.13 - * precise terms see the accompanying LICENSE file.
220.14 - *
220.15 - * This software is provided "AS IS" with no warranty of any kind,
220.16 - * express or implied, and with no claim as to its suitability for any
220.17 - * purpose.
220.18 - *
220.19 - */
220.20 -
220.21 -#include <iostream>
220.22 -#include <vector>
220.23 -#include <queue>
220.24 -#include <math.h>
220.25 -#include <cstdlib>
220.26 -
220.27 -#include "test_tools.h"
220.28 -#include <lemon/invalid.h>
220.29 -#include <lemon/list_graph.h>
220.30 -#include <lemon/max_matching.h>
220.31 -
220.32 -using namespace std;
220.33 -using namespace lemon;
220.34 -
220.35 -int main() {
220.36 -
220.37 - typedef UndirListGraph Graph;
220.38 -
220.39 - typedef Graph::Edge Edge;
220.40 - typedef Graph::UndirEdgeIt UndirEdgeIt;
220.41 - typedef Graph::IncEdgeIt IncEdgeIt;
220.42 - typedef Graph::NodeIt NodeIt;
220.43 - typedef Graph::Node Node;
220.44 -
220.45 - Graph g;
220.46 - g.clear();
220.47 -
220.48 - std::vector<Graph::Node> nodes;
220.49 - for (int i=0; i<13; ++i)
220.50 - nodes.push_back(g.addNode());
220.51 -
220.52 - g.addEdge(nodes[0], nodes[0]);
220.53 - g.addEdge(nodes[6], nodes[10]);
220.54 - g.addEdge(nodes[5], nodes[10]);
220.55 - g.addEdge(nodes[4], nodes[10]);
220.56 - g.addEdge(nodes[3], nodes[11]);
220.57 - g.addEdge(nodes[1], nodes[6]);
220.58 - g.addEdge(nodes[4], nodes[7]);
220.59 - g.addEdge(nodes[1], nodes[8]);
220.60 - g.addEdge(nodes[0], nodes[8]);
220.61 - g.addEdge(nodes[3], nodes[12]);
220.62 - g.addEdge(nodes[6], nodes[9]);
220.63 - g.addEdge(nodes[9], nodes[11]);
220.64 - g.addEdge(nodes[2], nodes[10]);
220.65 - g.addEdge(nodes[10], nodes[8]);
220.66 - g.addEdge(nodes[5], nodes[8]);
220.67 - g.addEdge(nodes[6], nodes[3]);
220.68 - g.addEdge(nodes[0], nodes[5]);
220.69 - g.addEdge(nodes[6], nodes[12]);
220.70 -
220.71 - MaxMatching<Graph> max_matching(g);
220.72 - max_matching.runEdmonds(0);
220.73 -
220.74 - int s=0;
220.75 - Graph::NodeMap<Node> mate(g,INVALID);
220.76 - max_matching.writeNMapNode(mate);
220.77 - for(NodeIt v(g); v!=INVALID; ++v) {
220.78 - if ( mate[v]!=INVALID ) ++s;
220.79 - }
220.80 - int size=(int)s/2; //size will be used as the size of a maxmatching
220.81 -
220.82 - for(NodeIt v(g); v!=INVALID; ++v) {
220.83 - max_matching.mate(v);
220.84 - }
220.85 -
220.86 - check ( size == max_matching.size(), "mate() returns a different size matching than max_matching.size()" );
220.87 -
220.88 - Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos0(g);
220.89 - max_matching.writePos(pos0);
220.90 -
220.91 - max_matching.resetMatching();
220.92 - max_matching.runEdmonds(1);
220.93 - s=0;
220.94 - max_matching.writeNMapNode(mate);
220.95 - for(NodeIt v(g); v!=INVALID; ++v) {
220.96 - if ( mate[v]!=INVALID ) ++s;
220.97 - }
220.98 - check ( (int)s/2 == size, "The size does not equal!" );
220.99 -
220.100 - Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos1(g);
220.101 - max_matching.writePos(pos1);
220.102 -
220.103 - max_matching.run();
220.104 - s=0;
220.105 - max_matching.writeNMapNode(mate);
220.106 - for(NodeIt v(g); v!=INVALID; ++v) {
220.107 - if ( mate[v]!=INVALID ) ++s;
220.108 - }
220.109 - check ( (int)s/2 == size, "The size does not equal!" );
220.110 -
220.111 - Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos2(g);
220.112 - max_matching.writePos(pos2);
220.113 -
220.114 - max_matching.resetMatching();
220.115 - max_matching.run();
220.116 - s=0;
220.117 - max_matching.writeNMapNode(mate);
220.118 - for(NodeIt v(g); v!=INVALID; ++v) {
220.119 - if ( mate[v]!=INVALID ) ++s;
220.120 - }
220.121 - check ( (int)s/2 == size, "The size does not equal!" );
220.122 -
220.123 - Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos(g);
220.124 - max_matching.writePos(pos);
220.125 -
220.126 - bool ismatching=true;
220.127 - for(NodeIt v(g); v!=INVALID; ++v) {
220.128 - if ( mate[v]!=INVALID ) {
220.129 - Node u=mate[v];
220.130 - if (mate[u]!=v) ismatching=false;
220.131 - }
220.132 - }
220.133 - check ( ismatching, "It is not a matching!" );
220.134 -
220.135 - bool coincide=true;
220.136 - for(NodeIt v(g); v!=INVALID; ++v) {
220.137 - if ( pos0[v] != pos1[v] || pos1[v]!=pos2[v] || pos2[v]!=pos[v] ) {
220.138 - coincide=false;
220.139 - }
220.140 - }
220.141 - check ( coincide, "The decompositions do not coincide! " );
220.142 -
220.143 - bool noedge=true;
220.144 - for(UndirEdgeIt e(g); e!=INVALID; ++e) {
220.145 - if ( (pos[g.target(e)]==max_matching.C && pos[g.source(e)]==max_matching.D) ||
220.146 - (pos[g.target(e)]==max_matching.D && pos[g.source(e)]==max_matching.C) )
220.147 - noedge=false;
220.148 - }
220.149 - check ( noedge, "There are edges between D and C!" );
220.150 -
220.151 - bool oddcomp=true;
220.152 - Graph::NodeMap<bool> todo(g,true);
220.153 - int num_comp=0;
220.154 - for(NodeIt v(g); v!=INVALID; ++v) {
220.155 - if ( pos[v]==max_matching.D && todo[v] ) {
220.156 - int comp_size=1;
220.157 - ++num_comp;
220.158 - std::queue<Node> Q;
220.159 - Q.push(v);
220.160 - todo.set(v,false);
220.161 - while (!Q.empty()) {
220.162 - Node w=Q.front();
220.163 - Q.pop();
220.164 - for(IncEdgeIt e(g,w); e!=INVALID; ++e) {
220.165 - Node u=g.runningNode(e);
220.166 - if ( pos[u]==max_matching.D && todo[u] ) {
220.167 - ++comp_size;
220.168 - Q.push(u);
220.169 - todo.set(u,false);
220.170 - }
220.171 - }
220.172 - }
220.173 - if ( !(comp_size % 2) ) oddcomp=false;
220.174 - }
220.175 - }
220.176 - check ( oddcomp, "A component of g[D] is not odd." );
220.177 -
220.178 - int barrier=0;
220.179 - for(NodeIt v(g); v!=INVALID; ++v) {
220.180 - if ( pos[v]==max_matching.A ) ++barrier;
220.181 - }
220.182 - int expected_size=(int)( countNodes(g)-num_comp+barrier)/2;
220.183 - check ( size==expected_size, "The size of the matching is wrong." );
220.184 -
220.185 - return 0;
220.186 -}
221.1 --- a/src/test/min_cost_flow_test.cc Sat May 21 21:04:57 2005 +0000
221.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
221.3 @@ -1,126 +0,0 @@
221.4 -/* -*- C++ -*-
221.5 - * src/test/min_cost_flow_test.cc - Part of LEMON, a generic C++ optimization library
221.6 - *
221.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
221.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
221.9 - *
221.10 - * Permission to use, modify and distribute this software is granted
221.11 - * provided that this copyright notice appears in all copies. For
221.12 - * precise terms see the accompanying LICENSE file.
221.13 - *
221.14 - * This software is provided "AS IS" with no warranty of any kind,
221.15 - * express or implied, and with no claim as to its suitability for any
221.16 - * purpose.
221.17 - *
221.18 - */
221.19 -
221.20 -#include <iostream>
221.21 -#include "test_tools.h"
221.22 -#include <lemon/list_graph.h>
221.23 -#include <lemon/min_cost_flow.h>
221.24 -//#include <path.h>
221.25 -//#include <maps.h>
221.26 -
221.27 -using namespace lemon;
221.28 -
221.29 -
221.30 -bool passed = true;
221.31 -/*
221.32 -void check(bool rc, char *msg="") {
221.33 - passed = passed && rc;
221.34 - if(!rc) {
221.35 - std::cerr << "Test failed! ("<< msg << ")" << std::endl; \
221.36 -
221.37 -
221.38 - }
221.39 -}
221.40 -*/
221.41 -
221.42 -
221.43 -int main()
221.44 -{
221.45 - typedef ListGraph Graph;
221.46 - typedef Graph::Node Node;
221.47 - typedef Graph::Edge Edge;
221.48 -
221.49 - Graph graph;
221.50 -
221.51 - //Ahuja könyv példája
221.52 -
221.53 - Node s=graph.addNode();
221.54 - Node v1=graph.addNode();
221.55 - Node v2=graph.addNode();
221.56 - Node v3=graph.addNode();
221.57 - Node v4=graph.addNode();
221.58 - Node v5=graph.addNode();
221.59 - Node t=graph.addNode();
221.60 -
221.61 - Edge s_v1=graph.addEdge(s, v1);
221.62 - Edge v1_v2=graph.addEdge(v1, v2);
221.63 - Edge s_v3=graph.addEdge(s, v3);
221.64 - Edge v2_v4=graph.addEdge(v2, v4);
221.65 - Edge v2_v5=graph.addEdge(v2, v5);
221.66 - Edge v3_v5=graph.addEdge(v3, v5);
221.67 - Edge v4_t=graph.addEdge(v4, t);
221.68 - Edge v5_t=graph.addEdge(v5, t);
221.69 -
221.70 -
221.71 - Graph::EdgeMap<int> length(graph);
221.72 -
221.73 - length.set(s_v1, 6);
221.74 - length.set(v1_v2, 4);
221.75 - length.set(s_v3, 10);
221.76 - length.set(v2_v4, 5);
221.77 - length.set(v2_v5, 1);
221.78 - length.set(v3_v5, 4);
221.79 - length.set(v4_t, 8);
221.80 - length.set(v5_t, 8);
221.81 -
221.82 - Graph::EdgeMap<int> capacity(graph);
221.83 -
221.84 - capacity.set(s_v1, 2);
221.85 - capacity.set(v1_v2, 2);
221.86 - capacity.set(s_v3, 1);
221.87 - capacity.set(v2_v4, 1);
221.88 - capacity.set(v2_v5, 1);
221.89 - capacity.set(v3_v5, 1);
221.90 - capacity.set(v4_t, 1);
221.91 - capacity.set(v5_t, 2);
221.92 -
221.93 - // ConstMap<Edge, int> const1map(1);
221.94 - std::cout << "Mincostflows algorithm test..." << std::endl;
221.95 -
221.96 - MinCostFlow< Graph, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
221.97 - surb_test(graph, length, capacity, s, t);
221.98 -
221.99 - int k=1;
221.100 -
221.101 - surb_test.augment();
221.102 - check( surb_test.flowValue() == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
221.103 -
221.104 - check( surb_test.run(k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
221.105 -
221.106 - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
221.107 -
221.108 - k=2;
221.109 -
221.110 - check( surb_test.run(k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41");
221.111 -
221.112 - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
221.113 -
221.114 - surb_test.augment();
221.115 - surb_test.augment();
221.116 - surb_test.augment();
221.117 - k=4;
221.118 -
221.119 - check( surb_test.run(k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64");
221.120 -
221.121 - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
221.122 -
221.123 -
221.124 - std::cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
221.125 - << std::endl;
221.126 -
221.127 - return passed ? 0 : 1;
221.128 -
221.129 -}
222.1 --- a/src/test/path_test.cc Sat May 21 21:04:57 2005 +0000
222.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
222.3 @@ -1,96 +0,0 @@
222.4 -/* -*- C++ -*-
222.5 - * src/test/path_test.cc - Part of LEMON, a generic C++ optimization library
222.6 - *
222.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
222.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
222.9 - *
222.10 - * Permission to use, modify and distribute this software is granted
222.11 - * provided that this copyright notice appears in all copies. For
222.12 - * precise terms see the accompanying LICENSE file.
222.13 - *
222.14 - * This software is provided "AS IS" with no warranty of any kind,
222.15 - * express or implied, and with no claim as to its suitability for any
222.16 - * purpose.
222.17 - *
222.18 - */
222.19 -
222.20 -#include <string>
222.21 -#include <iostream>
222.22 -#include <lemon/concept/path.h>
222.23 -#include <lemon/path.h>
222.24 -#include <lemon/list_graph.h>
222.25 -
222.26 -using namespace std;
222.27 -using namespace lemon;
222.28 -using namespace lemon::concept;
222.29 -
222.30 -template<class Path> void checkCompilePath(Path &P)
222.31 -{
222.32 - typedef typename Path::EdgeIt EdgeIt;
222.33 - typedef typename Path::NodeIt NodeIt;
222.34 - typedef typename Path::GraphNode GraphNode;
222.35 - typedef typename Path::GraphEdge GraphEdge;
222.36 - //typedef typename Path::Builder Builder;
222.37 - //??? ha csinalok ilyet es siman Builderrel peldanyositok, akkor warningol. Talan friend miatt? De ki az?
222.38 -
222.39 - EdgeIt ei;
222.40 - NodeIt ni;
222.41 - GraphNode gn;
222.42 - GraphEdge ge;
222.43 -
222.44 - size_t st;
222.45 - bool b;
222.46 -
222.47 - //Path(const Graph &_G) {} //the constructor has been already called
222.48 -
222.49 - st=P.length(); //size_t length() const {return 0;}
222.50 - b=P.empty(); //bool empty() const {}
222.51 - P.clear(); //void clear() {}
222.52 -
222.53 - gn=P.target(); //GraphNode/*It*/ target() const {return INVALID;}
222.54 - gn=P.source(); //GraphNode/*It*/ source() const {return INVALID;}
222.55 -
222.56 - ei=P.first(ei); //It& first(It &i) const { return i=It(*this); }
222.57 -
222.58 - ni=P.target(ei); //NodeIt target(const EdgeIt& e) const {}
222.59 - ni=P.source(ei); //NodeIt source(const EdgeIt& e) const {}
222.60 -
222.61 -
222.62 - ListGraph lg;
222.63 - Path p(lg);
222.64 -
222.65 - EdgeIt i; //EdgeIt() {}
222.66 - EdgeIt j(INVALID); //EdgeIt(Invalid) {}
222.67 - EdgeIt k(p); //EdgeIt(const Path &_p) {}
222.68 -
222.69 - i=++j; //EdgeIt& operator++() {}
222.70 - ++k;
222.71 - b=(i==j); //bool operator==(const EdgeIt& e) const {return true;}
222.72 - b=(i!=j); //bool operator!=(const EdgeIt& e) const {return true;}
222.73 -
222.74 -
222.75 - NodeIt l; //NodeIt() {}
222.76 - NodeIt m(INVALID); //NodeIt(Invalid) {}
222.77 - NodeIt n(p); //NodeIt(const Path &_p) {}
222.78 -
222.79 - l=++m; //NodeIt& operator++() {}
222.80 - b=(m==n); //bool operator==(const NodeIt& e) const {}
222.81 - b=(m!=n); //bool operator!=(const NodeIt& e) const {}
222.82 -
222.83 - typename Path::Builder builder(p); //Builder(Path &_P) : P(_P) {}
222.84 - builder.setStartNode(gn); //void setStartNode(const GraphNode &) {}
222.85 - builder.pushFront(ge); //void pushFront(const GraphEdge& e) {}
222.86 - builder.pushBack(ge); //void pushBack(const GraphEdge& e) {}
222.87 - builder.commit(); //void commit() {}
222.88 - builder.reserveFront(st); //void reserveFront(size_t r) {}
222.89 - builder.reserveBack(st); //void reserveBack(size_t r) {}
222.90 -
222.91 -}
222.92 -
222.93 -template void checkCompilePath< concept::Path<ListGraph> >(concept::Path<ListGraph> &);
222.94 -template void checkCompilePath< DirPath<ListGraph> >(DirPath<ListGraph> &);
222.95 -template void checkCompilePath< UndirPath<ListGraph> >(UndirPath<ListGraph> &);
222.96 -
222.97 -int main()
222.98 -{
222.99 -}
223.1 --- a/src/test/preflow_graph.dim Sat May 21 21:04:57 2005 +0000
223.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
223.3 @@ -1,20 +0,0 @@
223.4 -p max 10 17
223.5 -n 2 s
223.6 -n 9 t
223.7 -a 1 2 20
223.8 -a 1 3 0
223.9 -a 2 2 3
223.10 -a 2 3 8
223.11 -a 2 4 8
223.12 -a 3 6 5
223.13 -a 4 3 5
223.14 -a 4 6 5
223.15 -a 4 7 5
223.16 -a 5 4 3
223.17 -a 6 8 3
223.18 -a 6 7 10
223.19 -a 6 9 10
223.20 -a 7 9 8
223.21 -a 9 10 20
223.22 -a 9 2 5
223.23 -a 10 6 5
223.24 \ No newline at end of file
224.1 --- a/src/test/preflow_test.cc Sat May 21 21:04:57 2005 +0000
224.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
224.3 @@ -1,201 +0,0 @@
224.4 -/* -*- C++ -*-
224.5 - * src/test/preflow_test.cc - Part of LEMON, a generic C++ optimization library
224.6 - *
224.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
224.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
224.9 - *
224.10 - * Permission to use, modify and distribute this software is granted
224.11 - * provided that this copyright notice appears in all copies. For
224.12 - * precise terms see the accompanying LICENSE file.
224.13 - *
224.14 - * This software is provided "AS IS" with no warranty of any kind,
224.15 - * express or implied, and with no claim as to its suitability for any
224.16 - * purpose.
224.17 - *
224.18 - */
224.19 -
224.20 -#include <fstream>
224.21 -#include <string>
224.22 -
224.23 -#include "test_tools.h"
224.24 -#include <lemon/smart_graph.h>
224.25 -#include <lemon/dimacs.h>
224.26 -#include <lemon/preflow.h>
224.27 -#include <lemon/concept/graph.h>
224.28 -#include <lemon/concept/maps.h>
224.29 -
224.30 -using namespace lemon;
224.31 -
224.32 -void check_Preflow()
224.33 -{
224.34 - typedef int VType;
224.35 - typedef concept::StaticGraph Graph;
224.36 -
224.37 - typedef Graph::Node Node;
224.38 - typedef Graph::Edge Edge;
224.39 - typedef concept::ReadMap<Edge,VType> CapMap;
224.40 - typedef concept::ReadWriteMap<Edge,VType> FlowMap;
224.41 - typedef concept::ReadWriteMap<Node,bool> CutMap;
224.42 -
224.43 - typedef Preflow<Graph, int, CapMap, FlowMap> PType;
224.44 -
224.45 - Graph g;
224.46 - Node n;
224.47 - CapMap cap;
224.48 - FlowMap flow;
224.49 - CutMap cut;
224.50 -
224.51 - PType preflow_test(g,n,n,cap,flow);
224.52 -
224.53 - preflow_test.run();
224.54 - preflow_test.flowValue();
224.55 - preflow_test.source(n);
224.56 - preflow_test.flowMap(flow);
224.57 -
224.58 - preflow_test.phase1(PType::NO_FLOW);
224.59 - preflow_test.minCut(cut);
224.60 -
224.61 - preflow_test.phase2();
224.62 - preflow_test.target(n);
224.63 - preflow_test.capacityMap(cap);
224.64 - preflow_test.minMinCut(cut);
224.65 - preflow_test.maxMinCut(cut);
224.66 -}
224.67 -
224.68 -int cut_value ( SmartGraph& g, SmartGraph::NodeMap<bool>& cut,
224.69 - SmartGraph::EdgeMap<int>& cap) {
224.70 -
224.71 - int c=0;
224.72 - for(SmartGraph::EdgeIt e(g); e!=INVALID; ++e) {
224.73 - if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
224.74 - }
224.75 - return c;
224.76 -}
224.77 -
224.78 -int main() {
224.79 -
224.80 - typedef SmartGraph Graph;
224.81 -
224.82 - typedef Graph::Node Node;
224.83 - typedef Graph::NodeIt NodeIt;
224.84 - typedef Graph::EdgeIt EdgeIt;
224.85 - typedef Graph::EdgeMap<int> CapMap;
224.86 - typedef Graph::EdgeMap<int> FlowMap;
224.87 - typedef Graph::NodeMap<bool> CutMap;
224.88 -
224.89 - typedef Preflow<Graph, int> PType;
224.90 -
224.91 - std::string f_name;
224.92 - if( getenv("srcdir") )
224.93 - f_name = std::string(getenv("srcdir"));
224.94 - else f_name = ".";
224.95 - f_name += "/preflow_graph.dim";
224.96 -
224.97 - std::ifstream file(f_name.c_str());
224.98 -
224.99 - check(file, "Input file '" << f_name << "' not found.");
224.100 -
224.101 - Graph g;
224.102 - Node s, t;
224.103 - CapMap cap(g);
224.104 - readDimacs(file, g, cap, s, t);
224.105 -
224.106 - FlowMap flow(g,0);
224.107 -
224.108 -
224.109 -
224.110 - PType preflow_test(g, s, t, cap, flow);
224.111 - preflow_test.run(PType::ZERO_FLOW);
224.112 -
224.113 - CutMap min_cut(g,false);
224.114 - preflow_test.minCut(min_cut);
224.115 - int min_cut_value=cut_value(g,min_cut,cap);
224.116 -
224.117 - CutMap min_min_cut(g,false);
224.118 - preflow_test.minMinCut(min_min_cut);
224.119 - int min_min_cut_value=cut_value(g,min_min_cut,cap);
224.120 -
224.121 - CutMap max_min_cut(g,false);
224.122 - preflow_test.maxMinCut(max_min_cut);
224.123 - int max_min_cut_value=cut_value(g,max_min_cut,cap);
224.124 -
224.125 - check(preflow_test.flowValue() == min_cut_value &&
224.126 - min_cut_value == min_min_cut_value &&
224.127 - min_min_cut_value == max_min_cut_value,
224.128 - "The max flow value is not equal to the three min cut values.");
224.129 -
224.130 - int flow_value=preflow_test.flowValue();
224.131 -
224.132 -
224.133 -
224.134 - for(EdgeIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
224.135 - preflow_test.capacityMap(cap);
224.136 -
224.137 - preflow_test.phase1(PType::PRE_FLOW);
224.138 -
224.139 - CutMap min_cut1(g,false);
224.140 - preflow_test.minCut(min_cut1);
224.141 - min_cut_value=cut_value(g,min_cut1,cap);
224.142 -
224.143 - check(preflow_test.flowValue() == min_cut_value &&
224.144 - min_cut_value == 2*flow_value,
224.145 - "The max flow value or the min cut value is wrong.");
224.146 -
224.147 - preflow_test.phase2();
224.148 -
224.149 - CutMap min_cut2(g,false);
224.150 - preflow_test.minCut(min_cut2);
224.151 - min_cut_value=cut_value(g,min_cut2,cap);
224.152 -
224.153 - CutMap min_min_cut2(g,false);
224.154 - preflow_test.minMinCut(min_min_cut2);
224.155 - min_min_cut_value=cut_value(g,min_min_cut2,cap);
224.156 -
224.157 - preflow_test.maxMinCut(max_min_cut);
224.158 - max_min_cut_value=cut_value(g,max_min_cut,cap);
224.159 -
224.160 - check(preflow_test.flowValue() == min_cut_value &&
224.161 - min_cut_value == min_min_cut_value &&
224.162 - min_min_cut_value == max_min_cut_value &&
224.163 - min_cut_value == 2*flow_value,
224.164 - "The max flow value or the three min cut values were not doubled");
224.165 -
224.166 -
224.167 -
224.168 - EdgeIt e(g);
224.169 - for( int i=1; i==10; ++i ) {
224.170 - flow.set(e,0);
224.171 - ++e;
224.172 - }
224.173 -
224.174 - preflow_test.flowMap(flow);
224.175 -
224.176 - NodeIt tmp1(g,s);
224.177 - ++tmp1;
224.178 - if ( tmp1 != INVALID ) s=tmp1;
224.179 -
224.180 - NodeIt tmp2(g,t);
224.181 - ++tmp2;
224.182 - if ( tmp2 != INVALID ) t=tmp2;
224.183 -
224.184 - preflow_test.source(s);
224.185 - preflow_test.target(t);
224.186 -
224.187 - preflow_test.run();
224.188 -
224.189 - CutMap min_cut3(g,false);
224.190 - preflow_test.minCut(min_cut3);
224.191 - min_cut_value=cut_value(g,min_cut3,cap);
224.192 -
224.193 - CutMap min_min_cut3(g,false);
224.194 - preflow_test.minMinCut(min_min_cut3);
224.195 - min_min_cut_value=cut_value(g,min_min_cut3,cap);
224.196 -
224.197 - preflow_test.maxMinCut(max_min_cut);
224.198 - max_min_cut_value=cut_value(g,max_min_cut,cap);
224.199 -
224.200 - check(preflow_test.flowValue() == min_cut_value &&
224.201 - min_cut_value == min_min_cut_value &&
224.202 - min_min_cut_value == max_min_cut_value,
224.203 - "The max flow value or the three min cut values are incorrect.");
224.204 -}
225.1 --- a/src/test/suurballe_test.cc Sat May 21 21:04:57 2005 +0000
225.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
225.3 @@ -1,108 +0,0 @@
225.4 -/* -*- C++ -*-
225.5 - * src/test/suurballe_test.cc - Part of LEMON, a generic C++ optimization library
225.6 - *
225.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
225.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
225.9 - *
225.10 - * Permission to use, modify and distribute this software is granted
225.11 - * provided that this copyright notice appears in all copies. For
225.12 - * precise terms see the accompanying LICENSE file.
225.13 - *
225.14 - * This software is provided "AS IS" with no warranty of any kind,
225.15 - * express or implied, and with no claim as to its suitability for any
225.16 - * purpose.
225.17 - *
225.18 - */
225.19 -
225.20 -#include <iostream>
225.21 -#include <lemon/list_graph.h>
225.22 -#include <lemon/suurballe.h>
225.23 -//#include <path.h>
225.24 -#include "test_tools.h"
225.25 -
225.26 -using namespace lemon;
225.27 -
225.28 -
225.29 -bool passed = true;
225.30 -
225.31 -
225.32 -int main()
225.33 -{
225.34 - typedef ListGraph Graph;
225.35 - typedef Graph::Node Node;
225.36 - typedef Graph::Edge Edge;
225.37 -
225.38 - Graph graph;
225.39 -
225.40 - //Ahuja könyv példája
225.41 -
225.42 - Node s=graph.addNode();
225.43 - Node v1=graph.addNode();
225.44 - Node v2=graph.addNode();
225.45 - Node v3=graph.addNode();
225.46 - Node v4=graph.addNode();
225.47 - Node v5=graph.addNode();
225.48 - Node t=graph.addNode();
225.49 -
225.50 - Edge s_v1=graph.addEdge(s, v1);
225.51 - Edge v1_v2=graph.addEdge(v1, v2);
225.52 - Edge s_v3=graph.addEdge(s, v3);
225.53 - Edge v2_v4=graph.addEdge(v2, v4);
225.54 - Edge v2_v5=graph.addEdge(v2, v5);
225.55 - Edge v3_v5=graph.addEdge(v3, v5);
225.56 - Edge v4_t=graph.addEdge(v4, t);
225.57 - Edge v5_t=graph.addEdge(v5, t);
225.58 -
225.59 -
225.60 - Graph::EdgeMap<int> length(graph);
225.61 -
225.62 - length.set(s_v1, 6);
225.63 - length.set(v1_v2, 4);
225.64 - length.set(s_v3, 10);
225.65 - length.set(v2_v4, 5);
225.66 - length.set(v2_v5, 1);
225.67 - length.set(v3_v5, 5);
225.68 - length.set(v4_t, 8);
225.69 - length.set(v5_t, 8);
225.70 -
225.71 - std::cout << "Minlengthpaths algorithm test..." << std::endl;
225.72 -
225.73 -
225.74 - int k=3;
225.75 - Suurballe< Graph, Graph::EdgeMap<int> >
225.76 - surb_test(graph, length, s, t);
225.77 -
225.78 - check( surb_test.run(k) == 2 && surb_test.totalLength() == 46,
225.79 - "Two paths, total length should be 46");
225.80 -
225.81 - check( surb_test.checkComplementarySlackness(),
225.82 - "Complementary slackness conditions are not met.");
225.83 -
225.84 - // typedef DirPath<Graph> DPath;
225.85 - // DPath P(graph);
225.86 -
225.87 - /*
225.88 - surb_test.getPath(P,0);
225.89 - check(P.length() == 4, "First path should contain 4 edges.");
225.90 - std::cout<<P.length()<<std::endl;
225.91 - surb_test.getPath(P,1);
225.92 - check(P.length() == 3, "Second path: 3 edges.");
225.93 - std::cout<<P.length()<<std::endl;
225.94 - */
225.95 -
225.96 - k=1;
225.97 - check( surb_test.run(k) == 1 && surb_test.totalLength() == 19,
225.98 - "One path, total length should be 19");
225.99 -
225.100 - check( surb_test.checkComplementarySlackness(),
225.101 - "Complementary slackness conditions are not met.");
225.102 -
225.103 - // surb_test.getPath(P,0);
225.104 - // check(P.length() == 4, "First path should contain 4 edges.");
225.105 -
225.106 - std::cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
225.107 - << std::endl;
225.108 -
225.109 - return passed ? 0 : 1;
225.110 -
225.111 -}
226.1 --- a/src/test/sym_graph_test.cc Sat May 21 21:04:57 2005 +0000
226.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
226.3 @@ -1,98 +0,0 @@
226.4 -/* -*- C++ -*-
226.5 - * src/test/sym_graph_test.cc - Part of LEMON, a generic C++ optimization library
226.6 - *
226.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
226.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
226.9 - *
226.10 - * Permission to use, modify and distribute this software is granted
226.11 - * provided that this copyright notice appears in all copies. For
226.12 - * precise terms see the accompanying LICENSE file.
226.13 - *
226.14 - * This software is provided "AS IS" with no warranty of any kind,
226.15 - * express or implied, and with no claim as to its suitability for any
226.16 - * purpose.
226.17 - *
226.18 - */
226.19 -
226.20 -#include<iostream>
226.21 -
226.22 -#include<lemon/concept/sym_graph.h>
226.23 -
226.24 -#include<lemon/list_graph.h>
226.25 -#include<lemon/smart_graph.h>
226.26 -#include<lemon/full_graph.h>
226.27 -
226.28 -#include"test_tools.h"
226.29 -#include"graph_test.h"
226.30 -#include"sym_graph_test.h"
226.31 -
226.32 -/**
226.33 -\file
226.34 -This test makes consistency checks of list graph structures.
226.35 -
226.36 -G.addNode(), G.addEdge(), G.source(), G.target()
226.37 -
226.38 -\todo Checks for empty graphs and isolated points.
226.39 -conversion.
226.40 -*/
226.41 -
226.42 -using namespace lemon;
226.43 -
226.44 -template<class Graph> void checkPetersen(Graph &G)
226.45 -{
226.46 - typedef typename Graph::NodeIt NodeIt;
226.47 -
226.48 -
226.49 - checkGraphNodeList(G,10);
226.50 - checkGraphEdgeList(G,30);
226.51 - checkGraphSymEdgeList(G,15);
226.52 -
226.53 - for(NodeIt n(G);n!=INVALID;++n) {
226.54 - checkGraphInEdgeList(G,n,3);
226.55 - checkGraphOutEdgeList(G,n,3);
226.56 - }
226.57 -}
226.58 -
226.59 -//Compile Graph
226.60 -template void lemon::checkCompileStaticSymGraph<concept::StaticSymGraph>
226.61 -(concept::StaticSymGraph &);
226.62 -
226.63 -template void lemon::checkCompileSymGraph<concept::ExtendableSymGraph>
226.64 -(concept::ExtendableSymGraph &);
226.65 -
226.66 -template void lemon::checkCompileErasableSymGraph<concept::ErasableSymGraph>
226.67 -(concept::ErasableSymGraph &);
226.68 -
226.69 -
226.70 -//Compile SymSmartGraph
226.71 -template void lemon::checkCompileSymGraph<SymSmartGraph>(SymSmartGraph &);
226.72 -template
226.73 -void lemon::concept::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
226.74 -
226.75 -//Compile SymListGraph
226.76 -template void lemon::checkCompileSymGraph<SymListGraph>(SymListGraph &);
226.77 -template void lemon::checkCompileErasableSymGraph<SymListGraph>(SymListGraph &);
226.78 -template
226.79 -void lemon::concept::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
226.80 -
226.81 -int main()
226.82 -{
226.83 - {
226.84 - SymSmartGraph G;
226.85 - addSymPetersen(G);
226.86 - checkPetersen(G);
226.87 - }
226.88 - {
226.89 - SymListGraph G;
226.90 - addSymPetersen(G);
226.91 - checkPetersen(G);
226.92 - }
226.93 -
226.94 - ///\file
226.95 - ///\todo map tests.
226.96 - ///\todo copy constr tests.
226.97 -
226.98 - std::cout << __FILE__ ": All tests passed.\n";
226.99 -
226.100 - return 0;
226.101 -}
227.1 --- a/src/test/sym_graph_test.h Sat May 21 21:04:57 2005 +0000
227.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
227.3 @@ -1,183 +0,0 @@
227.4 -/* -*- C++ -*-
227.5 - * src/test/sym_graph_test.h - Part of LEMON, a generic C++ optimization library
227.6 - *
227.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
227.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
227.9 - *
227.10 - * Permission to use, modify and distribute this software is granted
227.11 - * provided that this copyright notice appears in all copies. For
227.12 - * precise terms see the accompanying LICENSE file.
227.13 - *
227.14 - * This software is provided "AS IS" with no warranty of any kind,
227.15 - * express or implied, and with no claim as to its suitability for any
227.16 - * purpose.
227.17 - *
227.18 - */
227.19 -#ifndef LEMON_TEST_SYM_GRAPH_TEST_H
227.20 -#define LEMON_TEST_SYM_GRAPH_TEST_H
227.21 -
227.22 -
227.23 -#include "graph_test.h"
227.24 -#include "test_tools.h"
227.25 -
227.26 -//! \ingroup misc
227.27 -//! \file
227.28 -//! \brief Some utility to test symmetric graph classes.
227.29 -namespace lemon {
227.30 -
227.31 - /// \e
227.32 -
227.33 - /// \todo This should go to lemon/concept/symgraph.h
227.34 - ///
227.35 - template<class Graph> void checkCompileStaticSymGraph(Graph &G)
227.36 - {
227.37 - typedef typename Graph::Node Node;
227.38 - typedef typename Graph::NodeIt NodeIt;
227.39 - typedef typename Graph::SymEdge SymEdge;
227.40 - typedef typename Graph::SymEdgeIt SymEdgeIt;
227.41 - typedef typename Graph::Edge Edge;
227.42 - typedef typename Graph::EdgeIt EdgeIt;
227.43 - typedef typename Graph::InEdgeIt InEdgeIt;
227.44 - typedef typename Graph::OutEdgeIt OutEdgeIt;
227.45 -
227.46 - lemon::concept::checkCompileStaticGraph(G);
227.47 -
227.48 - {
227.49 - SymEdge i; SymEdge j(i); SymEdge k(INVALID);
227.50 - i=j;
227.51 - bool b; b=true;
227.52 - b=(i==INVALID); b=(i!=INVALID);
227.53 - b=(i==j); b=(i!=j); b=(i<j);
227.54 - Edge e;
227.55 - e = G.forward(i);
227.56 - e = G.backward(i);
227.57 - }
227.58 - {
227.59 - SymEdgeIt i; SymEdgeIt j(i); SymEdgeIt k(INVALID); SymEdgeIt l(G);
227.60 - i=j;
227.61 - j=G.first(i);
227.62 - j=++i;
227.63 - bool b; b=true;
227.64 - b=(i==INVALID); b=(i!=INVALID);
227.65 - SymEdge n(i);
227.66 - n=i;
227.67 - b=(i==j); b=(i!=j); b=(i<j);
227.68 - //SymEdge ->SymEdgeIt conversion
227.69 - SymEdgeIt ni(G,n);
227.70 - }
227.71 - {
227.72 - Edge i, j;
227.73 - j = G.opposite(i);
227.74 - }
227.75 - {
227.76 - Node n;
227.77 - SymEdge se;
227.78 - se=INVALID;
227.79 - n=G.source(se);
227.80 - n=G.target(se);
227.81 - }
227.82 - // id tests
227.83 - { SymEdge n; int i=G.id(n); i=i; }
227.84 - //SymEdgeMap tests
227.85 - {
227.86 - SymEdge k;
227.87 - typename Graph::template SymEdgeMap<int> m(G);
227.88 - typename Graph::template SymEdgeMap<int> const &cm = m; //Const map
227.89 - //Inicialize with default value
227.90 - typename Graph::template SymEdgeMap<int> mdef(G,12);
227.91 - typename Graph::template SymEdgeMap<int> mm(cm); //Copy
227.92 - typename Graph::template SymEdgeMap<double> dm(cm); //Copy from another type
227.93 - int v;
227.94 - v=m[k]; m[k]=v; m.set(k,v);
227.95 - v=cm[k];
227.96 -
227.97 - m=cm;
227.98 - dm=cm; //Copy from another type
227.99 - {
227.100 - //Check the typedef's
227.101 - typename Graph::template SymEdgeMap<int>::Value val;
227.102 - val = 1;
227.103 - typename Graph::template SymEdgeMap<int>::Key key;
227.104 - key = typename Graph::SymEdgeIt(G);
227.105 - }
227.106 - }
227.107 - { //bool SymEdgeMap
227.108 - SymEdge k;
227.109 - typename Graph::template SymEdgeMap<bool> m(G);
227.110 - typename Graph::template SymEdgeMap<bool> const &cm = m; //Const map
227.111 - //Inicialize with default value
227.112 - typename Graph::template SymEdgeMap<bool> mdef(G,12);
227.113 - typename Graph::template SymEdgeMap<bool> mm(cm); //Copy
227.114 - typename Graph::template SymEdgeMap<int> dm(cm); //Copy from another type
227.115 - bool v;
227.116 - v=m[k]; m[k]=v; m.set(k,v);
227.117 - v=cm[k];
227.118 -
227.119 - m=cm;
227.120 - dm=cm; //Copy from another type
227.121 - m=dm; //Copy to another type
227.122 - {
227.123 - //Check the typedef's
227.124 - typename Graph::template SymEdgeMap<bool>::Value val;
227.125 - val=true;
227.126 - typename Graph::template SymEdgeMap<bool>::Key key;
227.127 - key= typename Graph::SymEdgeIt(G);
227.128 - }
227.129 - }
227.130 - }
227.131 -
227.132 - template<class Graph> void checkCompileSymGraph(Graph &G)
227.133 - {
227.134 - checkCompileStaticSymGraph(G);
227.135 -
227.136 - typedef typename Graph::Node Node;
227.137 - typedef typename Graph::NodeIt NodeIt;
227.138 - typedef typename Graph::SymEdge SymEdge;
227.139 - typedef typename Graph::SymEdgeIt SymEdgeIt;
227.140 - typedef typename Graph::Edge Edge;
227.141 - typedef typename Graph::EdgeIt EdgeIt;
227.142 - typedef typename Graph::InEdgeIt InEdgeIt;
227.143 - typedef typename Graph::OutEdgeIt OutEdgeIt;
227.144 -
227.145 - Node n,m;
227.146 - n=G.addNode();
227.147 - m=G.addNode();
227.148 - SymEdge e;
227.149 - e = G.addEdge(n,m);
227.150 -
227.151 - // G.clear();
227.152 - }
227.153 -
227.154 - template<class Graph> void checkCompileSymGraphEraseSymEdge(Graph &G)
227.155 - {
227.156 - typename Graph::SymEdge n;
227.157 - G.erase(n);
227.158 - }
227.159 -
227.160 - template<class Graph> void checkCompileErasableSymGraph(Graph &G)
227.161 - {
227.162 - checkCompileSymGraph(G);
227.163 - lemon::concept::checkCompileGraphEraseNode(G);
227.164 - checkCompileSymGraphEraseSymEdge(G);
227.165 - }
227.166 -
227.167 - template<class Graph> void checkGraphSymEdgeList(Graph &G, int nn)
227.168 - {
227.169 - typedef typename Graph::SymEdgeIt SymEdgeIt;
227.170 -
227.171 - SymEdgeIt e(G);
227.172 - for(int i=0;i<nn;i++) {
227.173 - check(e!=INVALID,"Wrong SymEdge list linking.");
227.174 - ++e;
227.175 - }
227.176 - check(e==INVALID,"Wrong SymEdge list linking.");
227.177 - }
227.178 -
227.179 - ///\file
227.180 - ///\todo Check target(), source() as well;
227.181 -
227.182 -
227.183 -} //namespace lemon
227.184 -
227.185 -
227.186 -#endif
228.1 --- a/src/test/test_tools.h Sat May 21 21:04:57 2005 +0000
228.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
228.3 @@ -1,173 +0,0 @@
228.4 -/* -*- C++ -*-
228.5 - * src/test/test_tools.h - Part of LEMON, a generic C++ optimization library
228.6 - *
228.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
228.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
228.9 - *
228.10 - * Permission to use, modify and distribute this software is granted
228.11 - * provided that this copyright notice appears in all copies. For
228.12 - * precise terms see the accompanying LICENSE file.
228.13 - *
228.14 - * This software is provided "AS IS" with no warranty of any kind,
228.15 - * express or implied, and with no claim as to its suitability for any
228.16 - * purpose.
228.17 - *
228.18 - */
228.19 -
228.20 -#ifndef LEMON_TEST_TEST_TOOLS_H
228.21 -#define LEMON_TEST_TEST_TOOLS_H
228.22 -
228.23 -#include <iostream>
228.24 -#include <vector>
228.25 -
228.26 -#include <lemon/invalid.h>
228.27 -
228.28 -using namespace lemon;
228.29 -
228.30 -//! \ingroup misc
228.31 -//! \file
228.32 -//! \brief Some utilities to write test programs.
228.33 -
228.34 -
228.35 -///If \c rc is fail, writes an error message end exit.
228.36 -
228.37 -///If \c rc is fail, writes an error message end exit.
228.38 -///The error message contains the file name and the line number of the
228.39 -///source code in a standard from, which makes it possible to go there
228.40 -///using good source browsers like e.g. \c emacs.
228.41 -///
228.42 -///For example
228.43 -///\code check(0==1,"This is obviously false.");\endcode will
228.44 -///print this (and then exits).
228.45 -///\verbatim graph_test.cc:123: error: This is obviously false. \endverbatim
228.46 -///
228.47 -///\todo It should be in \c error.h
228.48 -#define check(rc, msg) \
228.49 - if(!(rc)) { \
228.50 - std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
228.51 - exit(1); \
228.52 - } else { } \
228.53 -
228.54 -///Structure returned by \ref addPetersen().
228.55 -
228.56 -///Structure returned by \ref addPetersen().
228.57 -///
228.58 -template<class Graph> struct PetStruct
228.59 -{
228.60 - ///Vector containing the outer nodes.
228.61 - std::vector<typename Graph::Node> outer;
228.62 - ///Vector containing the inner nodes.
228.63 - std::vector<typename Graph::Node> inner;
228.64 - ///Vector containing the edges of the inner circle.
228.65 - std::vector<typename Graph::Edge> incir;
228.66 - ///Vector containing the edges of the outer circle.
228.67 - std::vector<typename Graph::Edge> outcir;
228.68 - ///Vector containing the chord edges.
228.69 - std::vector<typename Graph::Edge> chords;
228.70 -};
228.71 -
228.72 -
228.73 -
228.74 -///Adds a Petersen graph to \c G.
228.75 -
228.76 -///Adds a Petersen graph to \c G.
228.77 -///\return The nodes and edges of the generated graph.
228.78 -
228.79 -template<typename Graph>
228.80 -PetStruct<Graph> addPetersen(Graph &G,int num = 5)
228.81 -{
228.82 - PetStruct<Graph> n;
228.83 -
228.84 - for(int i=0;i<num;i++) {
228.85 - n.outer.push_back(G.addNode());
228.86 - n.inner.push_back(G.addNode());
228.87 - }
228.88 -
228.89 - for(int i=0;i<num;i++) {
228.90 - n.chords.push_back(G.addEdge(n.outer[i],n.inner[i]));
228.91 - n.outcir.push_back(G.addEdge(n.outer[i],n.outer[(i+1) % num]));
228.92 - n.incir.push_back(G.addEdge(n.inner[i],n.inner[(i+2) % num]));
228.93 - }
228.94 - return n;
228.95 -}
228.96 -
228.97 -/// \brief Adds to the graph the reverse pair of all edges.
228.98 -///
228.99 -/// Adds to the graph the reverse pair of all edges.
228.100 -///
228.101 -template<class Graph> void bidirGraph(Graph &G)
228.102 -{
228.103 - typedef typename Graph::Edge Edge;
228.104 - typedef typename Graph::EdgeIt EdgeIt;
228.105 -
228.106 - std::vector<Edge> ee;
228.107 -
228.108 - for(EdgeIt e(G);e!=INVALID;++e) ee.push_back(e);
228.109 -
228.110 - for(typename std::vector<Edge>::iterator p=ee.begin();p!=ee.end();p++)
228.111 - G.addEdge(G.target(*p),G.source(*p));
228.112 -}
228.113 -
228.114 -
228.115 -/// \brief Checks the bidirectioned Petersen graph.
228.116 -///
228.117 -/// Checks the bidirectioned Petersen graph.
228.118 -///
228.119 -template<class Graph> void checkBidirPetersen(Graph &G, int num = 5)
228.120 -{
228.121 - typedef typename Graph::Node Node;
228.122 -
228.123 - typedef typename Graph::EdgeIt EdgeIt;
228.124 - typedef typename Graph::NodeIt NodeIt;
228.125 -
228.126 - checkGraphNodeList(G, 2 * num);
228.127 - checkGraphEdgeList(G, 6 * num);
228.128 -
228.129 - for(NodeIt n(G);n!=INVALID;++n) {
228.130 - checkGraphInEdgeList(G, n, 3);
228.131 - checkGraphOutEdgeList(G, n, 3);
228.132 - }
228.133 -}
228.134 -
228.135 -///Structure returned by \ref addSymPetersen().
228.136 -
228.137 -///Structure returned by \ref addSymPetersen().
228.138 -///
228.139 -template<class Graph> struct SymPetStruct
228.140 -{
228.141 - ///Vector containing the outer nodes.
228.142 - std::vector<typename Graph::Node> outer;
228.143 - ///Vector containing the inner nodes.
228.144 - std::vector<typename Graph::Node> inner;
228.145 - ///Vector containing the edges of the inner circle.
228.146 - std::vector<typename Graph::SymEdge> incir;
228.147 - ///Vector containing the edges of the outer circle.
228.148 - std::vector<typename Graph::SymEdge> outcir;
228.149 - ///Vector containing the chord edges.
228.150 - std::vector<typename Graph::SymEdge> chords;
228.151 -};
228.152 -
228.153 -///Adds a Petersen graph to the symmetric \c G.
228.154 -
228.155 -///Adds a Petersen graph to the symmetric \c G.
228.156 -///\return The nodes and edges of the generated graph.
228.157 -
228.158 -template<typename Graph>
228.159 -SymPetStruct<Graph> addSymPetersen(Graph &G,int num=5)
228.160 -{
228.161 - SymPetStruct<Graph> n;
228.162 -
228.163 - for(int i=0;i<num;i++) {
228.164 - n.outer.push_back(G.addNode());
228.165 - n.inner.push_back(G.addNode());
228.166 - }
228.167 -
228.168 - for(int i=0;i<num;i++) {
228.169 - n.chords.push_back(G.addEdge(n.outer[i],n.inner[i]));
228.170 - n.outcir.push_back(G.addEdge(n.outer[i],n.outer[(i+1)%5]));
228.171 - n.incir.push_back(G.addEdge(n.inner[i],n.inner[(i+2)%5]));
228.172 - }
228.173 - return n;
228.174 -}
228.175 -
228.176 -#endif
229.1 --- a/src/test/test_tools_fail.cc Sat May 21 21:04:57 2005 +0000
229.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
229.3 @@ -1,23 +0,0 @@
229.4 -/* -*- C++ -*-
229.5 - * src/test/test_tools_fail.cc - Part of LEMON, a generic C++ optimization library
229.6 - *
229.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
229.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
229.9 - *
229.10 - * Permission to use, modify and distribute this software is granted
229.11 - * provided that this copyright notice appears in all copies. For
229.12 - * precise terms see the accompanying LICENSE file.
229.13 - *
229.14 - * This software is provided "AS IS" with no warranty of any kind,
229.15 - * express or implied, and with no claim as to its suitability for any
229.16 - * purpose.
229.17 - *
229.18 - */
229.19 -
229.20 -#include "test_tools.h"
229.21 -
229.22 -int main()
229.23 -{
229.24 - check(false, "Don't panic. Failing is the right behaviour here.");
229.25 - return 0;
229.26 -}
230.1 --- a/src/test/test_tools_pass.cc Sat May 21 21:04:57 2005 +0000
230.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
230.3 @@ -1,23 +0,0 @@
230.4 -/* -*- C++ -*-
230.5 - * src/test/test_tools_pass.cc - Part of LEMON, a generic C++ optimization library
230.6 - *
230.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
230.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
230.9 - *
230.10 - * Permission to use, modify and distribute this software is granted
230.11 - * provided that this copyright notice appears in all copies. For
230.12 - * precise terms see the accompanying LICENSE file.
230.13 - *
230.14 - * This software is provided "AS IS" with no warranty of any kind,
230.15 - * express or implied, and with no claim as to its suitability for any
230.16 - * purpose.
230.17 - *
230.18 - */
230.19 -
230.20 -#include "test_tools.h"
230.21 -
230.22 -int main()
230.23 -{
230.24 - check(true, "It should pass.");
230.25 - return 0;
230.26 -}
231.1 --- a/src/test/time_measure_test.cc Sat May 21 21:04:57 2005 +0000
231.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
231.3 @@ -1,36 +0,0 @@
231.4 -/* -*- C++ -*-
231.5 - * src/test/time_measure_test.cc - Part of LEMON, a generic C++ optimization library
231.6 - *
231.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
231.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
231.9 - *
231.10 - * Permission to use, modify and distribute this software is granted
231.11 - * provided that this copyright notice appears in all copies. For
231.12 - * precise terms see the accompanying LICENSE file.
231.13 - *
231.14 - * This software is provided "AS IS" with no warranty of any kind,
231.15 - * express or implied, and with no claim as to its suitability for any
231.16 - * purpose.
231.17 - *
231.18 - */
231.19 -
231.20 -#include <lemon/time_measure.h>
231.21 -
231.22 -///\file \brief Test cases for time_measure.h
231.23 -///
231.24 -///\todo To be extended
231.25 -
231.26 -
231.27 -using namespace lemon;
231.28 -
231.29 -int main()
231.30 -{
231.31 - Timer T;
231.32 - while(T.getRealTime()<1.0) ;
231.33 - std::cout << T << '\n';
231.34 - T.reset();
231.35 - while(T.getRealTime()<2.0) ;
231.36 - std::cout << T << '\n';
231.37 -
231.38 - return 0;
231.39 -}
232.1 --- a/src/test/undir_graph_test.cc Sat May 21 21:04:57 2005 +0000
232.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
232.3 @@ -1,120 +0,0 @@
232.4 -// -*- C++ -*-
232.5 -
232.6 -#include <lemon/bits/undir_graph_extender.h>
232.7 -#include <lemon/concept/undir_graph.h>
232.8 -#include <lemon/list_graph.h>
232.9 -#include <lemon/smart_graph.h>
232.10 -#include <lemon/full_graph.h>
232.11 -
232.12 -#include <lemon/graph_utils.h>
232.13 -
232.14 -#include "test_tools.h"
232.15 -
232.16 -
232.17 -using namespace lemon;
232.18 -using namespace lemon::concept;
232.19 -
232.20 -void check_concepts() {
232.21 - typedef UndirGraphExtender<ListGraphBase> UndirListGraphBase;
232.22 -
232.23 - typedef IterableUndirGraphExtender<
232.24 - AlterableUndirGraphExtender<UndirListGraphBase> > IterableUndirListGraph;
232.25 -
232.26 - typedef MappableUndirGraphExtender<IterableUndirListGraph>
232.27 - MappableUndirListGraph;
232.28 -
232.29 - typedef ErasableUndirGraphExtender<
232.30 - ClearableUndirGraphExtender<
232.31 - ExtendableUndirGraphExtender<MappableUndirListGraph> > > Graph;
232.32 -
232.33 - checkConcept<BaseIterableUndirGraphConcept, Graph>();
232.34 - checkConcept<IterableUndirGraphConcept, Graph>();
232.35 - checkConcept<MappableUndirGraphConcept, Graph>();
232.36 -
232.37 - checkConcept<UndirGraph, Graph>();
232.38 - checkConcept<ErasableUndirGraph, Graph>();
232.39 -
232.40 - checkConcept<UndirGraph, UndirListGraph>();
232.41 - checkConcept<ErasableUndirGraph, UndirListGraph>();
232.42 -
232.43 - checkConcept<UndirGraph, UndirSmartGraph>();
232.44 - checkConcept<ExtendableUndirGraph, UndirSmartGraph>();
232.45 -
232.46 - checkConcept<UndirGraph, UndirGraph>();
232.47 -}
232.48 -
232.49 -template <typename Graph>
232.50 -void check_item_counts(Graph &g, int n, int e) {
232.51 - check(countNodes(g)==n, "Wrong node number.");
232.52 - check(countEdges(g)==2*e, "Wrong edge number.");
232.53 -}
232.54 -
232.55 -template <typename Graph>
232.56 -void print_items(Graph &g) {
232.57 -
232.58 - typedef typename Graph::NodeIt NodeIt;
232.59 - typedef typename Graph::UndirEdgeIt UEdgeIt;
232.60 - typedef typename Graph::EdgeIt EdgeIt;
232.61 -
232.62 - std::cout << "Nodes" << std::endl;
232.63 - int i=0;
232.64 - for(NodeIt it(g); it!=INVALID; ++it, ++i) {
232.65 - std::cout << " " << i << ": " << g.id(it) << std::endl;
232.66 - }
232.67 -
232.68 - std::cout << "UndirEdge" << std::endl;
232.69 - i=0;
232.70 - for(UEdgeIt it(g); it!=INVALID; ++it, ++i) {
232.71 - std::cout << " " << i << ": " << g.id(it)
232.72 - << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it))
232.73 - << ")" << std::endl;
232.74 - }
232.75 -
232.76 - std::cout << "Edge" << std::endl;
232.77 - i=0;
232.78 - for(EdgeIt it(g); it!=INVALID; ++it, ++i) {
232.79 - std::cout << " " << i << ": " << g.id(it)
232.80 - << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it))
232.81 - << ")" << std::endl;
232.82 - }
232.83 -
232.84 -}
232.85 -
232.86 -template <typename Graph>
232.87 -void check_graph() {
232.88 -
232.89 - typedef typename Graph::Node Node;
232.90 - typedef typename Graph::UndirEdge UEdge;
232.91 - typedef typename Graph::Edge Edge;
232.92 - typedef typename Graph::NodeIt NodeIt;
232.93 - typedef typename Graph::UndirEdgeIt UEdgeIt;
232.94 - typedef typename Graph::EdgeIt EdgeIt;
232.95 -
232.96 - Graph g;
232.97 -
232.98 - check_item_counts(g,0,0);
232.99 -
232.100 - Node
232.101 - n1 = g.addNode(),
232.102 - n2 = g.addNode(),
232.103 - n3 = g.addNode();
232.104 -
232.105 - UEdge
232.106 - e1 = g.addEdge(n1, n2),
232.107 - e2 = g.addEdge(n2, n3);
232.108 -
232.109 - // print_items(g);
232.110 -
232.111 - check_item_counts(g,3,2);
232.112 -
232.113 -
232.114 -}
232.115 -
232.116 -int main() {
232.117 - check_concepts();
232.118 -
232.119 - check_graph<UndirListGraph>();
232.120 - check_graph<UndirSmartGraph>();
232.121 -
232.122 - return 0;
232.123 -}
233.1 --- a/src/test/unionfind_test.cc Sat May 21 21:04:57 2005 +0000
233.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
233.3 @@ -1,208 +0,0 @@
233.4 -/* -*- C++ -*-
233.5 - * src/test/unionfind_test.cc - Part of LEMON, a generic C++ optimization library
233.6 - *
233.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
233.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
233.9 - *
233.10 - * Permission to use, modify and distribute this software is granted
233.11 - * provided that this copyright notice appears in all copies. For
233.12 - * precise terms see the accompanying LICENSE file.
233.13 - *
233.14 - * This software is provided "AS IS" with no warranty of any kind,
233.15 - * express or implied, and with no claim as to its suitability for any
233.16 - * purpose.
233.17 - *
233.18 - */
233.19 -
233.20 -#include <iostream>
233.21 -
233.22 -#include <lemon/maps.h>
233.23 -#include <lemon/unionfind.h>
233.24 -#include "test_tools.h"
233.25 -
233.26 -using namespace lemon;
233.27 -using namespace std;
233.28 -
233.29 -template <typename T>
233.30 -class BaseMap : public StdMap<int,T> {};
233.31 -
233.32 -typedef UnionFindEnum<int, BaseMap> UFE;
233.33 -
233.34 -void print(UFE const &ufe) {
233.35 - UFE::ClassIt cit;
233.36 - cout << "Print the classes of the structure:" << endl;
233.37 - int i = 1;
233.38 - for (ufe.first(cit); ufe.valid(cit); ufe.next(cit)) {
233.39 - cout << " " << i << " (" << cit << "):" << flush;
233.40 - UFE::ItemIt iit;
233.41 - for (ufe.first(iit, cit); ufe.valid(iit); ufe.next(iit)) {
233.42 - cout << " " << iit << flush;
233.43 - }
233.44 - cout << endl;
233.45 - i++;
233.46 - }
233.47 - cout << "done" << endl;
233.48 -}
233.49 -
233.50 -
233.51 -int main() {
233.52 - UFE::MapType base;
233.53 - UFE U(base);
233.54 -
233.55 -// print(U);
233.56 -
233.57 - cout << "Insert 1..." << endl;
233.58 - U.insert(1);
233.59 -// print(U);
233.60 -
233.61 - cout << "Insert 2..." << endl;
233.62 - U.insert(2);
233.63 -// print(U);
233.64 -
233.65 - cout << "Join 1 and 2..." << endl;
233.66 - check(U.join(1,2),"Test failed.");
233.67 -// print(U);
233.68 -
233.69 - cout << "Insert 3, 4, 5, 6, 7..." << endl;
233.70 - U.insert(3);
233.71 - U.insert(4);
233.72 - U.insert(5);
233.73 - U.insert(6);
233.74 - U.insert(7);
233.75 -// print (U);
233.76 -
233.77 - cout << "Join 1 - 4, 2 - 4 and 3 - 5 ..." << endl;
233.78 - check(U.join(1,4),"Test failed.");
233.79 - check(!U.join(2,4),"Test failed.");
233.80 - check(U.join(3,5),"Test failed.");
233.81 -// print(U);
233.82 -
233.83 - cout << "Insert 8 to the component of 5 ..." << endl;
233.84 - U.insert(8,5);
233.85 -// print(U);
233.86 -
233.87 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.88 - check(U.size(4) == 3,"Test failed.");
233.89 - cout << "Size of the class of 5: " << U.size(5) << endl;
233.90 - check(U.size(5) == 3,"Test failed.");
233.91 - cout << "Size of the class of 6: " << U.size(6) << endl;
233.92 - check(U.size(6) == 1,"Test failed.");
233.93 - cout << "Size of the class of 2: " << U.size(2) << endl;
233.94 - check(U.size(2) == 3,"Test failed.");
233.95 -
233.96 - cout << "Insert 9 ..." << endl;
233.97 - U.insert(9);
233.98 -// print(U);
233.99 - cout << "Insert 10 to the component of 9 ..." << endl;
233.100 - U.insert(10,9);
233.101 -// print(U);
233.102 -
233.103 - cout << "Join 8 and 10..." << endl;
233.104 - check(U.join(8,10),"Test failed.");
233.105 -// print(U);
233.106 -
233.107 - cout << "Move 9 to the class of 4 ..." << endl;
233.108 - check(U.move(9,4),"Test failed.");
233.109 -// print(U);
233.110 -
233.111 - cout << "Move 9 to the class of 2 ..." << endl;
233.112 - check(!U.move(9,2),"Test failed.");
233.113 -// print(U);
233.114 -
233.115 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.116 - check(U.size(4) == 4,"Test failed.");
233.117 - cout << "Size of the class of 9: " << U.size(9) << endl;
233.118 - check(U.size(9) == 4,"Test failed.");
233.119 -
233.120 - cout << "Move 5 to the class of 6 ..." << endl;
233.121 - check(U.move(5,6),"Test failed.");
233.122 -// print(U);
233.123 -
233.124 - cout << "Size of the class of 5: " << U.size(5) << endl;
233.125 - check(U.size(5) == 2,"Test failed.");
233.126 - cout << "Size of the class of 8: " << U.size(8) << endl;
233.127 - check(U.size(8) == 3,"Test failed.");
233.128 -
233.129 - cout << "Move 7 to the class of 10 ..." << endl;
233.130 - check(U.move(7,10),"Test failed.");
233.131 -// print(U);
233.132 -
233.133 - cout << "Size of the class of 7: " << U.size(7) << endl;
233.134 - check(U.size(7) == 4,"Test failed.");
233.135 -
233.136 - cout <<"Erase 9... " << endl;
233.137 - U.erase(9);
233.138 -// print(U);
233.139 -
233.140 - cout <<"Erase 1... " << endl;
233.141 - U.erase(1);
233.142 -// print(U);
233.143 -
233.144 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.145 - check(U.size(4) == 2,"Test failed.");
233.146 - cout << "Size of the class of 2: " << U.size(2) << endl;
233.147 - check(U.size(2) == 2,"Test failed.");
233.148 -
233.149 -
233.150 - cout <<"Erase 1... " << endl;
233.151 - U.erase(1);
233.152 -// print(U);
233.153 -
233.154 - cout <<"Erase 6... " << endl;
233.155 - U.erase(6);
233.156 -// print(U);
233.157 -
233.158 - cout << "Split the class of 8... " << endl;
233.159 - U.split(8);
233.160 -// print(U);
233.161 -
233.162 -
233.163 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.164 - check(U.size(4) == 2,"Test failed.");
233.165 - cout << "Size of the class of 3: " << U.size(3) << endl;
233.166 - check(U.size(3) == 1,"Test failed.");
233.167 - cout << "Size of the class of 2: " << U.size(2) << endl;
233.168 - check(U.size(2) == 2,"Test failed.");
233.169 -
233.170 -
233.171 - cout << "Join 3 - 4 and 2 - 4 ..." << endl;
233.172 - check(U.join(3,4),"Test failed.");
233.173 - check(!U.join(2,4),"Test failed.");
233.174 -// print(U);
233.175 -
233.176 -
233.177 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.178 - check(U.size(4) == 3,"Test failed.");
233.179 - cout << "Size of the class of 3: " << U.size(3) << endl;
233.180 - check(U.size(3) == 3,"Test failed.");
233.181 - cout << "Size of the class of 2: " << U.size(2) << endl;
233.182 - check(U.size(2) == 3,"Test failed.");
233.183 -
233.184 - cout << "Calling makeRep(4)..." << endl;
233.185 - U.makeRep(4);
233.186 -// print(U);
233.187 - cout << "Calling makeRep(3)..." << endl;
233.188 - U.makeRep(3);
233.189 -// print(U);
233.190 - cout << "Calling makeRep(2)..." << endl;
233.191 - U.makeRep(2);
233.192 -// print(U);
233.193 -
233.194 - cout << "Size of the class of 4: " << U.size(4) << endl;
233.195 - check(U.size(4) == 3,"Test failed.");
233.196 - cout << "Size of the class of 3: " << U.size(3) << endl;
233.197 - check(U.size(3) == 3,"Test failed.");
233.198 - cout << "Size of the class of 2: " << U.size(2) << endl;
233.199 - check(U.size(2) == 3,"Test failed.");
233.200 -
233.201 -
233.202 - cout << "eraseClass 4 ..." << endl;
233.203 - U.eraseClass(4);
233.204 -// print(U);
233.205 -
233.206 - cout << "eraseClass 7 ..." << endl;
233.207 - U.eraseClass(7);
233.208 -// print(U);
233.209 -
233.210 - cout << "done." << endl;
233.211 -}
234.1 --- a/src/test/xy_test.cc Sat May 21 21:04:57 2005 +0000
234.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
234.3 @@ -1,80 +0,0 @@
234.4 -/* -*- C++ -*-
234.5 - * src/test/xy_test.cc - Part of LEMON, a generic C++ optimization library
234.6 - *
234.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
234.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
234.9 - *
234.10 - * Permission to use, modify and distribute this software is granted
234.11 - * provided that this copyright notice appears in all copies. For
234.12 - * precise terms see the accompanying LICENSE file.
234.13 - *
234.14 - * This software is provided "AS IS" with no warranty of any kind,
234.15 - * express or implied, and with no claim as to its suitability for any
234.16 - * purpose.
234.17 - *
234.18 - */
234.19 -
234.20 -#include <lemon/xy.h>
234.21 -#include <iostream>
234.22 -#include "test_tools.h"
234.23 -
234.24 -using namespace std;
234.25 -using namespace lemon;
234.26 -int main()
234.27 -{
234.28 -
234.29 - cout << "Testing classes `xy' and `boundingbox'." << endl;
234.30 -
234.31 - typedef xy<int> XY;
234.32 -
234.33 - XY seged;
234.34 - XY a(1,2);
234.35 - XY b(3,4);
234.36 -
234.37 - seged = a+b;
234.38 - check(seged.x==4 && seged.y==6, "Wrong vector addition");
234.39 -
234.40 - seged = a-b;
234.41 - check(seged.x==-2 && seged.y==-2, "a-b");
234.42 -
234.43 - check(a.normSquare()==5,"Wrong norm calculation");
234.44 - check(a*b==11, "a*b");
234.45 -
234.46 - int l=2;
234.47 - seged = a*l;
234.48 - check(seged.x==2 && seged.y==4, "a*l");
234.49 -
234.50 - seged = b/l;
234.51 - check(seged.x==1 && seged.y==2, "b/l");
234.52 -
234.53 - typedef BoundingBox<int> BB;
234.54 - BB doboz1;
234.55 - check(doboz1.empty(), "It should be empty.");
234.56 -
234.57 - doboz1 += a;
234.58 - check(!doboz1.empty(), "It should not be empty.");
234.59 - doboz1 += b;
234.60 -
234.61 - check(doboz1.bottomLeft().x==1 &&
234.62 - doboz1.bottomLeft().y==2 &&
234.63 - doboz1.topRight().x==3 &&
234.64 - doboz1.topRight().y==4,
234.65 - "added points to box");
234.66 -
234.67 - seged.x=2;seged.y=3;
234.68 - check(doboz1.inside(seged),"It should be inside.");
234.69 -
234.70 - seged.x=1;seged.y=3;
234.71 - check(doboz1.inside(seged),"It should be inside.");
234.72 -
234.73 - seged.x=0;seged.y=3;
234.74 - check(!doboz1.inside(seged),"It should not be inside.");
234.75 -
234.76 - BB doboz2(seged);
234.77 - check(!doboz2.empty(),
234.78 - "It should not be empty. Constructed from 1 point.");
234.79 -
234.80 - doboz2 += doboz1;
234.81 - check(doboz2.inside(seged),
234.82 - "It should be inside. Incremented a box with an other.");
234.83 -}
235.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
235.2 +++ b/test/Makefile.am Mon May 23 04:48:14 2005 +0000
235.3 @@ -0,0 +1,69 @@
235.4 +AM_CPPFLAGS = -I$(top_srcdir)
235.5 +LDADD = $(top_builddir)/lemon/libemon.la
235.6 +
235.7 +EXTRA_DIST = preflow_graph.dim dijkstra_test.lgf
235.8 +
235.9 +noinst_HEADERS = \
235.10 + test_tools.h \
235.11 + graph_test.h \
235.12 + sym_graph_test.h \
235.13 + map_test.h \
235.14 + graph_utils_test.h \
235.15 + heap_test.h
235.16 +
235.17 +check_PROGRAMS = \
235.18 + bfs_test \
235.19 + dfs_test \
235.20 + dijkstra_test \
235.21 + graph_test \
235.22 + graph_adaptor_test \
235.23 + graph_utils_test \
235.24 + kruskal_test \
235.25 + max_matching_test \
235.26 + maps_test \
235.27 + min_cost_flow_test \
235.28 + suurballe_test \
235.29 + path_test \
235.30 + preflow_test \
235.31 + test_tools_fail \
235.32 + test_tools_pass \
235.33 + time_measure_test \
235.34 + unionfind_test \
235.35 + undir_graph_test \
235.36 + xy_test \
235.37 + heap_test
235.38 +
235.39 +if HAVE_GLPK
235.40 +check_PROGRAMS += lp_test
235.41 +else !HAVE_GLPK
235.42 +if HAVE_CPLEX
235.43 +check_PROGRAMS += lp_test
235.44 +endif HAVE_CPLEX
235.45 +endif !HAVE_GLPK
235.46 +
235.47 +TESTS = $(check_PROGRAMS)
235.48 +XFAIL_TESTS = test_tools_fail$(EXEEXT)
235.49 +
235.50 +bfs_test_SOURCES = bfs_test.cc
235.51 +dfs_test_SOURCES = dfs_test.cc
235.52 +dijkstra_test_SOURCES = dijkstra_test.cc
235.53 +graph_test_SOURCES = graph_test.cc
235.54 +graph_utils_test_SOURCES = graph_utils_test.cc
235.55 +graph_adaptor_test_SOURCES = graph_adaptor_test.cc
235.56 +kruskal_test_SOURCES = kruskal_test.cc
235.57 +maps_test_SOURCES = maps_test.cc
235.58 +min_cost_flow_test_SOURCES = min_cost_flow_test.cc
235.59 +max_matching_test_SOURCES = max_matching_test.cc
235.60 +suurballe_test_SOURCES = suurballe_test.cc
235.61 +path_test_SOURCES = path_test.cc
235.62 +preflow_test_SOURCES = preflow_test.cc
235.63 +time_measure_test_SOURCES = time_measure_test.cc
235.64 +test_tools_fail_SOURCES = test_tools_fail.cc
235.65 +test_tools_pass_SOURCES = test_tools_pass.cc
235.66 +unionfind_test_SOURCES = unionfind_test.cc
235.67 +xy_test_SOURCES = xy_test.cc
235.68 +undir_graph_test_SOURCES = undir_graph_test.cc
235.69 +heap_test_SOURCES = heap_test.cc
235.70 +
235.71 +lp_test_SOURCES = lp_test.cc
235.72 +lp_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
236.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
236.2 +++ b/test/bfs_test.cc Mon May 23 04:48:14 2005 +0000
236.3 @@ -0,0 +1,135 @@
236.4 +/* -*- C++ -*-
236.5 + * test/bfs_test.cc - Part of LEMON, a generic C++ optimization library
236.6 + *
236.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
236.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
236.9 + *
236.10 + * Permission to use, modify and distribute this software is granted
236.11 + * provided that this copyright notice appears in all copies. For
236.12 + * precise terms see the accompanying LICENSE file.
236.13 + *
236.14 + * This software is provided "AS IS" with no warranty of any kind,
236.15 + * express or implied, and with no claim as to its suitability for any
236.16 + * purpose.
236.17 + *
236.18 + */
236.19 +
236.20 +#include "test_tools.h"
236.21 +#include <lemon/smart_graph.h>
236.22 +#include <lemon/bfs.h>
236.23 +#include <lemon/path.h>
236.24 +#include<lemon/concept/graph.h>
236.25 +
236.26 +using namespace lemon;
236.27 +
236.28 +const int PET_SIZE =5;
236.29 +
236.30 +
236.31 +void check_Bfs_Compile()
236.32 +{
236.33 + typedef concept::StaticGraph Graph;
236.34 +
236.35 + typedef Graph::Edge Edge;
236.36 + typedef Graph::Node Node;
236.37 + typedef Graph::EdgeIt EdgeIt;
236.38 + typedef Graph::NodeIt NodeIt;
236.39 +
236.40 + typedef Bfs<Graph> BType;
236.41 +
236.42 + Graph G;
236.43 + Node n;
236.44 + Edge e;
236.45 + int l;
236.46 + bool b;
236.47 + BType::DistMap d(G);
236.48 + BType::PredMap p(G);
236.49 + // BType::PredNodeMap pn(G);
236.50 +
236.51 + BType bfs_test(G);
236.52 +
236.53 + bfs_test.run(n);
236.54 +
236.55 + l = bfs_test.dist(n);
236.56 + e = bfs_test.pred(n);
236.57 + n = bfs_test.predNode(n);
236.58 + d = bfs_test.distMap();
236.59 + p = bfs_test.predMap();
236.60 + // pn = bfs_test.predNodeMap();
236.61 + b = bfs_test.reached(n);
236.62 +
236.63 + DirPath<Graph> pp(G);
236.64 + bfs_test.getPath(pp,n);
236.65 +}
236.66 +
236.67 +void check_Bfs_Function_Compile()
236.68 +{
236.69 + typedef int VType;
236.70 + typedef concept::StaticGraph Graph;
236.71 +
236.72 + typedef Graph::Edge Edge;
236.73 + typedef Graph::Node Node;
236.74 + typedef Graph::EdgeIt EdgeIt;
236.75 + typedef Graph::NodeIt NodeIt;
236.76 + typedef concept::ReadMap<Edge,VType> LengthMap;
236.77 +
236.78 + bfs(Graph(),Node()).run();
236.79 + bfs(Graph()).source(Node()).run();
236.80 + bfs(Graph())
236.81 + .predMap(concept::WriteMap<Node,Edge>())
236.82 + .distMap(concept::WriteMap<Node,VType>())
236.83 + .reachedMap(concept::ReadWriteMap<Node,bool>())
236.84 + .processedMap(concept::WriteMap<Node,bool>())
236.85 + .run(Node());
236.86 +
236.87 +}
236.88 +
236.89 +int main()
236.90 +{
236.91 +
236.92 + typedef SmartGraph Graph;
236.93 +
236.94 + typedef Graph::Edge Edge;
236.95 + typedef Graph::Node Node;
236.96 + typedef Graph::EdgeIt EdgeIt;
236.97 + typedef Graph::NodeIt NodeIt;
236.98 + typedef Graph::EdgeMap<int> LengthMap;
236.99 +
236.100 + Graph G;
236.101 + Node s, t;
236.102 + PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
236.103 +
236.104 + s=ps.outer[2];
236.105 + t=ps.inner[0];
236.106 +
236.107 + Bfs<Graph> bfs_test(G);
236.108 + bfs_test.run(s);
236.109 +
236.110 + check(bfs_test.dist(t)==3,"Bfs found a wrong path. " << bfs_test.dist(t));
236.111 +
236.112 + DirPath<Graph> p(G);
236.113 + check(bfs_test.getPath(p,t),"getPath() failed to set the path.");
236.114 + check(p.length()==3,"getPath() found a wrong path.");
236.115 +
236.116 +
236.117 + for(EdgeIt e(G); e==INVALID; ++e) {
236.118 + Node u=G.source(e);
236.119 + Node v=G.target(e);
236.120 + check( !bfs_test.reached(u) ||
236.121 + (bfs_test.dist(v) > bfs_test.dist(u)+1),
236.122 + "Wrong output.");
236.123 + }
236.124 +
236.125 + for(NodeIt v(G); v==INVALID; ++v) {
236.126 + check(bfs_test.reached(v),"Each node should be reached.");
236.127 + if ( bfs_test.pred(v)!=INVALID ) {
236.128 + Edge e=bfs_test.pred(v);
236.129 + Node u=G.source(e);
236.130 + check(u==bfs_test.predNode(v),"Wrong tree.");
236.131 + check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
236.132 + "Wrong distance. Difference: "
236.133 + << std::abs(bfs_test.dist(v) - bfs_test.dist(u)
236.134 + - 1));
236.135 + }
236.136 + }
236.137 +}
236.138 +
237.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
237.2 +++ b/test/dfs_test.cc Mon May 23 04:48:14 2005 +0000
237.3 @@ -0,0 +1,124 @@
237.4 +/* -*- C++ -*-
237.5 + * test/dfs_test.cc - Part of LEMON, a generic C++ optimization library
237.6 + *
237.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
237.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
237.9 + *
237.10 + * Permission to use, modify and distribute this software is granted
237.11 + * provided that this copyright notice appears in all copies. For
237.12 + * precise terms see the accompanying LICENSE file.
237.13 + *
237.14 + * This software is provided "AS IS" with no warranty of any kind,
237.15 + * express or implied, and with no claim as to its suitability for any
237.16 + * purpose.
237.17 + *
237.18 + */
237.19 +
237.20 +#include "test_tools.h"
237.21 +#include <lemon/smart_graph.h>
237.22 +#include <lemon/dfs.h>
237.23 +#include <lemon/path.h>
237.24 +#include <lemon/concept/graph.h>
237.25 +
237.26 +using namespace lemon;
237.27 +
237.28 +const int PET_SIZE =5;
237.29 +
237.30 +
237.31 +void check_Dfs_SmartGraph_Compile()
237.32 +{
237.33 + typedef concept::StaticGraph Graph;
237.34 +
237.35 + typedef Graph::Edge Edge;
237.36 + typedef Graph::Node Node;
237.37 + typedef Graph::EdgeIt EdgeIt;
237.38 + typedef Graph::NodeIt NodeIt;
237.39 +
237.40 + typedef Dfs<Graph> DType;
237.41 +
237.42 + Graph G;
237.43 + Node n;
237.44 + Edge e;
237.45 + int l;
237.46 + bool b;
237.47 + DType::DistMap d(G);
237.48 + DType::PredMap p(G);
237.49 + // DType::PredNodeMap pn(G);
237.50 +
237.51 + DType dfs_test(G);
237.52 +
237.53 + dfs_test.run(n);
237.54 +
237.55 + l = dfs_test.dist(n);
237.56 + e = dfs_test.pred(n);
237.57 + n = dfs_test.predNode(n);
237.58 + d = dfs_test.distMap();
237.59 + p = dfs_test.predMap();
237.60 + // pn = dfs_test.predNodeMap();
237.61 + b = dfs_test.reached(n);
237.62 +
237.63 + DirPath<Graph> pp(G);
237.64 + dfs_test.getPath(pp,n);
237.65 +}
237.66 +
237.67 +
237.68 +void check_Dfs_Function_Compile()
237.69 +{
237.70 + typedef int VType;
237.71 + typedef concept::StaticGraph Graph;
237.72 +
237.73 + typedef Graph::Edge Edge;
237.74 + typedef Graph::Node Node;
237.75 + typedef Graph::EdgeIt EdgeIt;
237.76 + typedef Graph::NodeIt NodeIt;
237.77 + typedef concept::ReadMap<Edge,VType> LengthMap;
237.78 +
237.79 + dfs(Graph(),Node()).run();
237.80 + dfs(Graph()).source(Node()).run();
237.81 + dfs(Graph())
237.82 + .predMap(concept::WriteMap<Node,Edge>())
237.83 + .distMap(concept::WriteMap<Node,VType>())
237.84 + .reachedMap(concept::ReadWriteMap<Node,bool>())
237.85 + .processedMap(concept::WriteMap<Node,bool>())
237.86 + .run(Node());
237.87 +
237.88 +}
237.89 +
237.90 +int main()
237.91 +{
237.92 +
237.93 + typedef SmartGraph Graph;
237.94 +
237.95 + typedef Graph::Edge Edge;
237.96 + typedef Graph::Node Node;
237.97 + typedef Graph::EdgeIt EdgeIt;
237.98 + typedef Graph::NodeIt NodeIt;
237.99 + typedef Graph::EdgeMap<int> LengthMap;
237.100 +
237.101 + Graph G;
237.102 + Node s, t;
237.103 + PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
237.104 +
237.105 + s=ps.outer[2];
237.106 + t=ps.inner[0];
237.107 +
237.108 + Dfs<Graph> dfs_test(G);
237.109 + dfs_test.run(s);
237.110 +
237.111 + DirPath<Graph> p(G);
237.112 + check(dfs_test.getPath(p,t),"getPath() failed to set the path.");
237.113 + check(p.length()==dfs_test.dist(t),"getPath() found a wrong path.");
237.114 +
237.115 + for(NodeIt v(G); v!=INVALID; ++v) {
237.116 + check(dfs_test.reached(v),"Each node should be reached.");
237.117 + if ( dfs_test.pred(v)!=INVALID ) {
237.118 + Edge e=dfs_test.pred(v);
237.119 + Node u=G.source(e);
237.120 + check(u==dfs_test.predNode(v),"Wrong tree.");
237.121 + check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
237.122 + "Wrong distance. (" << dfs_test.dist(u) << "->"
237.123 + <<dfs_test.dist(v) << ')');
237.124 + }
237.125 + }
237.126 +}
237.127 +
238.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
238.2 +++ b/test/dijkstra_test.cc Mon May 23 04:48:14 2005 +0000
238.3 @@ -0,0 +1,155 @@
238.4 +/* -*- C++ -*-
238.5 + * test/dijkstra_test.cc - Part of LEMON, a generic C++ optimization library
238.6 + *
238.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
238.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
238.9 + *
238.10 + * Permission to use, modify and distribute this software is granted
238.11 + * provided that this copyright notice appears in all copies. For
238.12 + * precise terms see the accompanying LICENSE file.
238.13 + *
238.14 + * This software is provided "AS IS" with no warranty of any kind,
238.15 + * express or implied, and with no claim as to its suitability for any
238.16 + * purpose.
238.17 + *
238.18 + */
238.19 +
238.20 +#include "test_tools.h"
238.21 +#include <lemon/smart_graph.h>
238.22 +#include <lemon/dijkstra.h>
238.23 +#include <lemon/path.h>
238.24 +#include <lemon/maps.h>
238.25 +#include <lemon/concept/graph.h>
238.26 +#include <lemon/concept/maps.h>
238.27 +using namespace lemon;
238.28 +
238.29 +const int PET_SIZE =5;
238.30 +
238.31 +
238.32 +void check_Dijkstra_BinHeap_Compile()
238.33 +{
238.34 + typedef int VType;
238.35 + typedef concept::StaticGraph Graph;
238.36 +
238.37 + typedef Graph::Edge Edge;
238.38 + typedef Graph::Node Node;
238.39 + typedef Graph::EdgeIt EdgeIt;
238.40 + typedef Graph::NodeIt NodeIt;
238.41 + typedef concept::ReadMap<Edge,VType> LengthMap;
238.42 +
238.43 + typedef Dijkstra<Graph, LengthMap> DType;
238.44 +
238.45 + Graph G;
238.46 + Node n;
238.47 + Edge e;
238.48 + VType l;
238.49 + bool b;
238.50 + DType::DistMap d(G);
238.51 + DType::PredMap p(G);
238.52 + // DType::PredNodeMap pn(G);
238.53 + LengthMap cap;
238.54 +
238.55 + DType dijkstra_test(G,cap);
238.56 +
238.57 + dijkstra_test.run(n);
238.58 +
238.59 + l = dijkstra_test.dist(n);
238.60 + e = dijkstra_test.pred(n);
238.61 + n = dijkstra_test.predNode(n);
238.62 + d = dijkstra_test.distMap();
238.63 + p = dijkstra_test.predMap();
238.64 + // pn = dijkstra_test.predNodeMap();
238.65 + b = dijkstra_test.reached(n);
238.66 +
238.67 + DirPath<Graph> pp(G);
238.68 + dijkstra_test.getPath(pp,n);
238.69 +}
238.70 +
238.71 +void check_Dijkstra_Function_Compile()
238.72 +{
238.73 + typedef int VType;
238.74 + typedef concept::StaticGraph Graph;
238.75 +
238.76 + typedef Graph::Edge Edge;
238.77 + typedef Graph::Node Node;
238.78 + typedef Graph::EdgeIt EdgeIt;
238.79 + typedef Graph::NodeIt NodeIt;
238.80 + typedef concept::ReadMap<Edge,VType> LengthMap;
238.81 +
238.82 + dijkstra(Graph(),LengthMap(),Node()).run();
238.83 + dijkstra(Graph(),LengthMap()).source(Node()).run();
238.84 + dijkstra(Graph(),LengthMap())
238.85 + .predMap(concept::WriteMap<Node,Edge>())
238.86 + .distMap(concept::WriteMap<Node,VType>())
238.87 + .run(Node());
238.88 +
238.89 +}
238.90 +
238.91 +
238.92 +int main()
238.93 +{
238.94 +
238.95 + typedef SmartGraph Graph;
238.96 +
238.97 + typedef Graph::Edge Edge;
238.98 + typedef Graph::Node Node;
238.99 + typedef Graph::EdgeIt EdgeIt;
238.100 + typedef Graph::NodeIt NodeIt;
238.101 + typedef Graph::EdgeMap<int> LengthMap;
238.102 +
238.103 + Graph G;
238.104 + Node s, t;
238.105 + LengthMap cap(G);
238.106 + PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
238.107 +
238.108 + for(int i=0;i<PET_SIZE;i++) {
238.109 + cap[ps.outcir[i]]=4;
238.110 + cap[ps.incir[i]]=1;
238.111 + cap[ps.chords[i]]=10;
238.112 + }
238.113 + s=ps.outer[0];
238.114 + t=ps.inner[1];
238.115 +
238.116 + Dijkstra<Graph, LengthMap>
238.117 + dijkstra_test(G, cap);
238.118 + dijkstra_test.run(s);
238.119 +
238.120 + check(dijkstra_test.dist(t)==13,"Dijkstra found a wrong path.");
238.121 +
238.122 +
238.123 + DirPath<Graph> p(G);
238.124 + check(dijkstra_test.getPath(p,t),"getPath() failed to set the path.");
238.125 + check(p.length()==4,"getPath() found a wrong path.");
238.126 +
238.127 +
238.128 + for(EdgeIt e(G); e!=INVALID; ++e) {
238.129 + Node u=G.source(e);
238.130 + Node v=G.target(e);
238.131 + check( !dijkstra_test.reached(u) ||
238.132 + (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= cap[e]),
238.133 + "dist(target)-dist(source)- edge_length= "
238.134 + << dijkstra_test.dist(v) - dijkstra_test.dist(u)
238.135 + - cap[e]);
238.136 + }
238.137 +
238.138 + ///\bug This works only for integer lengths
238.139 + for(NodeIt v(G); v!=INVALID; ++v){
238.140 + check(dijkstra_test.reached(v),"Each node should be reached.");
238.141 + if ( dijkstra_test.pred(v)!=INVALID ) {
238.142 + Edge e=dijkstra_test.pred(v);
238.143 + Node u=G.source(e);
238.144 + check(u==dijkstra_test.predNode(v),"Wrong tree.");
238.145 + check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == cap[e],
238.146 + "Wrong distance! Difference: "
238.147 + << std::abs(dijkstra_test.dist(v) - dijkstra_test.dist(u)
238.148 + - cap[e]));
238.149 + }
238.150 + }
238.151 +
238.152 +
238.153 + {
238.154 + NullMap<Node,Edge> myPredMap;
238.155 + dijkstra(G,cap).predMap(myPredMap).run(s);
238.156 + }
238.157 + return 0;
238.158 +}
239.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239.2 +++ b/test/dijkstra_test.lgf Mon May 23 04:48:14 2005 +0000
239.3 @@ -0,0 +1,7914 @@
239.4 +@nodeset
239.5 +id
239.6 +999
239.7 +998
239.8 +997
239.9 +996
239.10 +995
239.11 +994
239.12 +993
239.13 +992
239.14 +991
239.15 +990
239.16 +989
239.17 +988
239.18 +987
239.19 +986
239.20 +985
239.21 +984
239.22 +983
239.23 +982
239.24 +981
239.25 +980
239.26 +979
239.27 +978
239.28 +977
239.29 +976
239.30 +975
239.31 +974
239.32 +973
239.33 +972
239.34 +971
239.35 +970
239.36 +969
239.37 +968
239.38 +967
239.39 +966
239.40 +965
239.41 +964
239.42 +963
239.43 +962
239.44 +961
239.45 +960
239.46 +959
239.47 +958
239.48 +957
239.49 +956
239.50 +955
239.51 +954
239.52 +953
239.53 +952
239.54 +951
239.55 +950
239.56 +949
239.57 +948
239.58 +947
239.59 +946
239.60 +945
239.61 +944
239.62 +943
239.63 +942
239.64 +941
239.65 +940
239.66 +939
239.67 +938
239.68 +937
239.69 +936
239.70 +935
239.71 +934
239.72 +933
239.73 +932
239.74 +931
239.75 +930
239.76 +929
239.77 +928
239.78 +927
239.79 +926
239.80 +925
239.81 +924
239.82 +923
239.83 +922
239.84 +921
239.85 +920
239.86 +919
239.87 +918
239.88 +917
239.89 +916
239.90 +915
239.91 +914
239.92 +913
239.93 +912
239.94 +911
239.95 +910
239.96 +909
239.97 +908
239.98 +907
239.99 +906
239.100 +905
239.101 +904
239.102 +903
239.103 +902
239.104 +901
239.105 +900
239.106 +899
239.107 +898
239.108 +897
239.109 +896
239.110 +895
239.111 +894
239.112 +893
239.113 +892
239.114 +891
239.115 +890
239.116 +889
239.117 +888
239.118 +887
239.119 +886
239.120 +885
239.121 +884
239.122 +883
239.123 +882
239.124 +881
239.125 +880
239.126 +879
239.127 +878
239.128 +877
239.129 +876
239.130 +875
239.131 +874
239.132 +873
239.133 +872
239.134 +871
239.135 +870
239.136 +869
239.137 +868
239.138 +867
239.139 +866
239.140 +865
239.141 +864
239.142 +863
239.143 +862
239.144 +861
239.145 +860
239.146 +859
239.147 +858
239.148 +857
239.149 +856
239.150 +855
239.151 +854
239.152 +853
239.153 +852
239.154 +851
239.155 +850
239.156 +849
239.157 +848
239.158 +847
239.159 +846
239.160 +845
239.161 +844
239.162 +843
239.163 +842
239.164 +841
239.165 +840
239.166 +839
239.167 +838
239.168 +837
239.169 +836
239.170 +835
239.171 +834
239.172 +833
239.173 +832
239.174 +831
239.175 +830
239.176 +829
239.177 +828
239.178 +827
239.179 +826
239.180 +825
239.181 +824
239.182 +823
239.183 +822
239.184 +821
239.185 +820
239.186 +819
239.187 +818
239.188 +817
239.189 +816
239.190 +815
239.191 +814
239.192 +813
239.193 +812
239.194 +811
239.195 +810
239.196 +809
239.197 +808
239.198 +807
239.199 +806
239.200 +805
239.201 +804
239.202 +803
239.203 +802
239.204 +801
239.205 +800
239.206 +799
239.207 +798
239.208 +797
239.209 +796
239.210 +795
239.211 +794
239.212 +793
239.213 +792
239.214 +791
239.215 +790
239.216 +789
239.217 +788
239.218 +787
239.219 +786
239.220 +785
239.221 +784
239.222 +783
239.223 +782
239.224 +781
239.225 +780
239.226 +779
239.227 +778
239.228 +777
239.229 +776
239.230 +775
239.231 +774
239.232 +773
239.233 +772
239.234 +771
239.235 +770
239.236 +769
239.237 +768
239.238 +767
239.239 +766
239.240 +765
239.241 +764
239.242 +763
239.243 +762
239.244 +761
239.245 +760
239.246 +759
239.247 +758
239.248 +757
239.249 +756
239.250 +755
239.251 +754
239.252 +753
239.253 +752
239.254 +751
239.255 +750
239.256 +749
239.257 +748
239.258 +747
239.259 +746
239.260 +745
239.261 +744
239.262 +743
239.263 +742
239.264 +741
239.265 +740
239.266 +739
239.267 +738
239.268 +737
239.269 +736
239.270 +735
239.271 +734
239.272 +733
239.273 +732
239.274 +731
239.275 +730
239.276 +729
239.277 +728
239.278 +727
239.279 +726
239.280 +725
239.281 +724
239.282 +723
239.283 +722
239.284 +721
239.285 +720
239.286 +719
239.287 +718
239.288 +717
239.289 +716
239.290 +715
239.291 +714
239.292 +713
239.293 +712
239.294 +711
239.295 +710
239.296 +709
239.297 +708
239.298 +707
239.299 +706
239.300 +705
239.301 +704
239.302 +703
239.303 +702
239.304 +701
239.305 +700
239.306 +699
239.307 +698
239.308 +697
239.309 +696
239.310 +695
239.311 +694
239.312 +693
239.313 +692
239.314 +691
239.315 +690
239.316 +689
239.317 +688
239.318 +687
239.319 +686
239.320 +685
239.321 +684
239.322 +683
239.323 +682
239.324 +681
239.325 +680
239.326 +679
239.327 +678
239.328 +677
239.329 +676
239.330 +675
239.331 +674
239.332 +673
239.333 +672
239.334 +671
239.335 +670
239.336 +669
239.337 +668
239.338 +667
239.339 +666
239.340 +665
239.341 +664
239.342 +663
239.343 +662
239.344 +661
239.345 +660
239.346 +659
239.347 +658
239.348 +657
239.349 +656
239.350 +655
239.351 +654
239.352 +653
239.353 +652
239.354 +651
239.355 +650
239.356 +649
239.357 +648
239.358 +647
239.359 +646
239.360 +645
239.361 +644
239.362 +643
239.363 +642
239.364 +641
239.365 +640
239.366 +639
239.367 +638
239.368 +637
239.369 +636
239.370 +635
239.371 +634
239.372 +633
239.373 +632
239.374 +631
239.375 +630
239.376 +629
239.377 +628
239.378 +627
239.379 +626
239.380 +625
239.381 +624
239.382 +623
239.383 +622
239.384 +621
239.385 +620
239.386 +619
239.387 +618
239.388 +617
239.389 +616
239.390 +615
239.391 +614
239.392 +613
239.393 +612
239.394 +611
239.395 +610
239.396 +609
239.397 +608
239.398 +607
239.399 +606
239.400 +605
239.401 +604
239.402 +603
239.403 +602
239.404 +601
239.405 +600
239.406 +599
239.407 +598
239.408 +597
239.409 +596
239.410 +595
239.411 +594
239.412 +593
239.413 +592
239.414 +591
239.415 +590
239.416 +589
239.417 +588
239.418 +587
239.419 +586
239.420 +585
239.421 +584
239.422 +583
239.423 +582
239.424 +581
239.425 +580
239.426 +579
239.427 +578
239.428 +577
239.429 +576
239.430 +575
239.431 +574
239.432 +573
239.433 +572
239.434 +571
239.435 +570
239.436 +569
239.437 +568
239.438 +567
239.439 +566
239.440 +565
239.441 +564
239.442 +563
239.443 +562
239.444 +561
239.445 +560
239.446 +559
239.447 +558
239.448 +557
239.449 +556
239.450 +555
239.451 +554
239.452 +553
239.453 +552
239.454 +551
239.455 +550
239.456 +549
239.457 +548
239.458 +547
239.459 +546
239.460 +545
239.461 +544
239.462 +543
239.463 +542
239.464 +541
239.465 +540
239.466 +539
239.467 +538
239.468 +537
239.469 +536
239.470 +535
239.471 +534
239.472 +533
239.473 +532
239.474 +531
239.475 +530
239.476 +529
239.477 +528
239.478 +527
239.479 +526
239.480 +525
239.481 +524
239.482 +523
239.483 +522
239.484 +521
239.485 +520
239.486 +519
239.487 +518
239.488 +517
239.489 +516
239.490 +515
239.491 +514
239.492 +513
239.493 +512
239.494 +511
239.495 +510
239.496 +509
239.497 +508
239.498 +507
239.499 +506
239.500 +505
239.501 +504
239.502 +503
239.503 +502
239.504 +501
239.505 +500
239.506 +499
239.507 +498
239.508 +497
239.509 +496
239.510 +495
239.511 +494
239.512 +493
239.513 +492
239.514 +491
239.515 +490
239.516 +489
239.517 +488
239.518 +487
239.519 +486
239.520 +485
239.521 +484
239.522 +483
239.523 +482
239.524 +481
239.525 +480
239.526 +479
239.527 +478
239.528 +477
239.529 +476
239.530 +475
239.531 +474
239.532 +473
239.533 +472
239.534 +471
239.535 +470
239.536 +469
239.537 +468
239.538 +467
239.539 +466
239.540 +465
239.541 +464
239.542 +463
239.543 +462
239.544 +461
239.545 +460
239.546 +459
239.547 +458
239.548 +457
239.549 +456
239.550 +455
239.551 +454
239.552 +453
239.553 +452
239.554 +451
239.555 +450
239.556 +449
239.557 +448
239.558 +447
239.559 +446
239.560 +445
239.561 +444
239.562 +443
239.563 +442
239.564 +441
239.565 +440
239.566 +439
239.567 +438
239.568 +437
239.569 +436
239.570 +435
239.571 +434
239.572 +433
239.573 +432
239.574 +431
239.575 +430
239.576 +429
239.577 +428
239.578 +427
239.579 +426
239.580 +425
239.581 +424
239.582 +423
239.583 +422
239.584 +421
239.585 +420
239.586 +419
239.587 +418
239.588 +417
239.589 +416
239.590 +415
239.591 +414
239.592 +413
239.593 +412
239.594 +411
239.595 +410
239.596 +409
239.597 +408
239.598 +407
239.599 +406
239.600 +405
239.601 +404
239.602 +403
239.603 +402
239.604 +401
239.605 +400
239.606 +399
239.607 +398
239.608 +397
239.609 +396
239.610 +395
239.611 +394
239.612 +393
239.613 +392
239.614 +391
239.615 +390
239.616 +389
239.617 +388
239.618 +387
239.619 +386
239.620 +385
239.621 +384
239.622 +383
239.623 +382
239.624 +381
239.625 +380
239.626 +379
239.627 +378
239.628 +377
239.629 +376
239.630 +375
239.631 +374
239.632 +373
239.633 +372
239.634 +371
239.635 +370
239.636 +369
239.637 +368
239.638 +367
239.639 +366
239.640 +365
239.641 +364
239.642 +363
239.643 +362
239.644 +361
239.645 +360
239.646 +359
239.647 +358
239.648 +357
239.649 +356
239.650 +355
239.651 +354
239.652 +353
239.653 +352
239.654 +351
239.655 +350
239.656 +349
239.657 +348
239.658 +347
239.659 +346
239.660 +345
239.661 +344
239.662 +343
239.663 +342
239.664 +341
239.665 +340
239.666 +339
239.667 +338
239.668 +337
239.669 +336
239.670 +335
239.671 +334
239.672 +333
239.673 +332
239.674 +331
239.675 +330
239.676 +329
239.677 +328
239.678 +327
239.679 +326
239.680 +325
239.681 +324
239.682 +323
239.683 +322
239.684 +321
239.685 +320
239.686 +319
239.687 +318
239.688 +317
239.689 +316
239.690 +315
239.691 +314
239.692 +313
239.693 +312
239.694 +311
239.695 +310
239.696 +309
239.697 +308
239.698 +307
239.699 +306
239.700 +305
239.701 +304
239.702 +303
239.703 +302
239.704 +301
239.705 +300
239.706 +299
239.707 +298
239.708 +297
239.709 +296
239.710 +295
239.711 +294
239.712 +293
239.713 +292
239.714 +291
239.715 +290
239.716 +289
239.717 +288
239.718 +287
239.719 +286
239.720 +285
239.721 +284
239.722 +283
239.723 +282
239.724 +281
239.725 +280
239.726 +279
239.727 +278
239.728 +277
239.729 +276
239.730 +275
239.731 +274
239.732 +273
239.733 +272
239.734 +271
239.735 +270
239.736 +269
239.737 +268
239.738 +267
239.739 +266
239.740 +265
239.741 +264
239.742 +263
239.743 +262
239.744 +261
239.745 +260
239.746 +259
239.747 +258
239.748 +257
239.749 +256
239.750 +255
239.751 +254
239.752 +253
239.753 +252
239.754 +251
239.755 +250
239.756 +249
239.757 +248
239.758 +247
239.759 +246
239.760 +245
239.761 +244
239.762 +243
239.763 +242
239.764 +241
239.765 +240
239.766 +239
239.767 +238
239.768 +237
239.769 +236
239.770 +235
239.771 +234
239.772 +233
239.773 +232
239.774 +231
239.775 +230
239.776 +229
239.777 +228
239.778 +227
239.779 +226
239.780 +225
239.781 +224
239.782 +223
239.783 +222
239.784 +221
239.785 +220
239.786 +219
239.787 +218
239.788 +217
239.789 +216
239.790 +215
239.791 +214
239.792 +213
239.793 +212
239.794 +211
239.795 +210
239.796 +209
239.797 +208
239.798 +207
239.799 +206
239.800 +205
239.801 +204
239.802 +203
239.803 +202
239.804 +201
239.805 +200
239.806 +199
239.807 +198
239.808 +197
239.809 +196
239.810 +195
239.811 +194
239.812 +193
239.813 +192
239.814 +191
239.815 +190
239.816 +189
239.817 +188
239.818 +187
239.819 +186
239.820 +185
239.821 +184
239.822 +183
239.823 +182
239.824 +181
239.825 +180
239.826 +179
239.827 +178
239.828 +177
239.829 +176
239.830 +175
239.831 +174
239.832 +173
239.833 +172
239.834 +171
239.835 +170
239.836 +169
239.837 +168
239.838 +167
239.839 +166
239.840 +165
239.841 +164
239.842 +163
239.843 +162
239.844 +161
239.845 +160
239.846 +159
239.847 +158
239.848 +157
239.849 +156
239.850 +155
239.851 +154
239.852 +153
239.853 +152
239.854 +151
239.855 +150
239.856 +149
239.857 +148
239.858 +147
239.859 +146
239.860 +145
239.861 +144
239.862 +143
239.863 +142
239.864 +141
239.865 +140
239.866 +139
239.867 +138
239.868 +137
239.869 +136
239.870 +135
239.871 +134
239.872 +133
239.873 +132
239.874 +131
239.875 +130
239.876 +129
239.877 +128
239.878 +127
239.879 +126
239.880 +125
239.881 +124
239.882 +123
239.883 +122
239.884 +121
239.885 +120
239.886 +119
239.887 +118
239.888 +117
239.889 +116
239.890 +115
239.891 +114
239.892 +113
239.893 +112
239.894 +111
239.895 +110
239.896 +109
239.897 +108
239.898 +107
239.899 +106
239.900 +105
239.901 +104
239.902 +103
239.903 +102
239.904 +101
239.905 +100
239.906 +99
239.907 +98
239.908 +97
239.909 +96
239.910 +95
239.911 +94
239.912 +93
239.913 +92
239.914 +91
239.915 +90
239.916 +89
239.917 +88
239.918 +87
239.919 +86
239.920 +85
239.921 +84
239.922 +83
239.923 +82
239.924 +81
239.925 +80
239.926 +79
239.927 +78
239.928 +77
239.929 +76
239.930 +75
239.931 +74
239.932 +73
239.933 +72
239.934 +71
239.935 +70
239.936 +69
239.937 +68
239.938 +67
239.939 +66
239.940 +65
239.941 +64
239.942 +63
239.943 +62
239.944 +61
239.945 +60
239.946 +59
239.947 +58
239.948 +57
239.949 +56
239.950 +55
239.951 +54
239.952 +53
239.953 +52
239.954 +51
239.955 +50
239.956 +49
239.957 +48
239.958 +47
239.959 +46
239.960 +45
239.961 +44
239.962 +43
239.963 +42
239.964 +41
239.965 +40
239.966 +39
239.967 +38
239.968 +37
239.969 +36
239.970 +35
239.971 +34
239.972 +33
239.973 +32
239.974 +31
239.975 +30
239.976 +29
239.977 +28
239.978 +27
239.979 +26
239.980 +25
239.981 +24
239.982 +23
239.983 +22
239.984 +21
239.985 +20
239.986 +19
239.987 +18
239.988 +17
239.989 +16
239.990 +15
239.991 +14
239.992 +13
239.993 +12
239.994 +11
239.995 +10
239.996 +9
239.997 +8
239.998 +7
239.999 +6
239.1000 +5
239.1001 +4
239.1002 +3
239.1003 +2
239.1004 +1
239.1005 +0
239.1006 +@edgeset
239.1007 + id capacity
239.1008 +75 377 6906 27
239.1009 +417 515 6905 69
239.1010 +603 249 6904 80
239.1011 +246 344 6903 69
239.1012 +382 827 6902 19
239.1013 +714 879 6901 76
239.1014 +13 481 6900 22
239.1015 +863 754 6899 97
239.1016 +19 530 6898 64
239.1017 +122 597 6897 78
239.1018 +861 579 6896 17
239.1019 +266 888 6895 65
239.1020 +905 105 6894 81
239.1021 +516 501 6893 35
239.1022 +948 430 6892 86
239.1023 +398 535 6891 66
239.1024 +727 258 6890 70
239.1025 +223 322 6889 15
239.1026 +933 864 6888 84
239.1027 +17 604 6887 89
239.1028 +691 520 6886 26
239.1029 +782 843 6885 59
239.1030 +604 457 6884 36
239.1031 +70 492 6883 38
239.1032 +895 195 6882 56
239.1033 +277 968 6881 55
239.1034 +935 550 6880 67
239.1035 +457 306 6879 50
239.1036 +260 946 6878 29
239.1037 +84 636 6877 91
239.1038 +677 665 6876 32
239.1039 +385 234 6875 90
239.1040 +964 972 6874 17
239.1041 +296 819 6873 53
239.1042 +227 18 6872 17
239.1043 +418 879 6871 61
239.1044 +243 167 6870 34
239.1045 +359 212 6869 47
239.1046 +310 374 6868 19
239.1047 +970 590 6867 17
239.1048 +431 416 6866 40
239.1049 +261 730 6865 29
239.1050 +152 643 6864 42
239.1051 +800 358 6863 66
239.1052 +139 557 6862 6
239.1053 +711 276 6861 80
239.1054 +954 863 6860 17
239.1055 +838 279 6859 88
239.1056 +784 22 6858 4
239.1057 +173 767 6857 33
239.1058 +686 116 6856 53
239.1059 +87 870 6855 16
239.1060 +284 753 6854 10
239.1061 +801 599 6853 35
239.1062 +281 259 6852 66
239.1063 +412 635 6851 42
239.1064 +583 291 6850 75
239.1065 +257 833 6849 11
239.1066 +254 710 6848 5
239.1067 +651 799 6847 61
239.1068 +245 370 6846 48
239.1069 +117 60 6845 59
239.1070 +153 757 6844 80
239.1071 +339 690 6843 48
239.1072 +624 232 6842 52
239.1073 +343 671 6841 86
239.1074 +457 639 6840 82
239.1075 +123 62 6839 32
239.1076 +910 442 6838 0
239.1077 +429 124 6837 60
239.1078 +310 888 6836 40
239.1079 +303 796 6835 12
239.1080 +66 319 6834 96
239.1081 +457 963 6833 81
239.1082 +560 651 6832 71
239.1083 +32 39 6831 28
239.1084 +577 502 6830 88
239.1085 +620 323 6829 33
239.1086 +318 400 6828 21
239.1087 +235 196 6827 48
239.1088 +92 277 6826 11
239.1089 +477 164 6825 0
239.1090 +356 149 6824 23
239.1091 +311 98 6823 60
239.1092 +612 435 6822 89
239.1093 +537 394 6821 52
239.1094 +179 552 6820 45
239.1095 +923 121 6819 95
239.1096 +203 731 6818 30
239.1097 +918 362 6817 8
239.1098 +112 111 6816 14
239.1099 +15 770 6815 61
239.1100 +51 628 6814 12
239.1101 +663 711 6813 4
239.1102 +41 368 6812 69
239.1103 +841 73 6811 7
239.1104 +431 497 6810 35
239.1105 +389 655 6809 25
239.1106 +369 218 6808 71
239.1107 +250 939 6807 28
239.1108 +341 528 6806 80
239.1109 +141 493 6805 9
239.1110 +916 76 6804 96
239.1111 +343 345 6803 38
239.1112 +294 623 6802 62
239.1113 +575 717 6801 19
239.1114 +842 102 6800 41
239.1115 +437 535 6799 4
239.1116 +279 435 6798 2
239.1117 +410 478 6797 11
239.1118 +35 709 6796 90
239.1119 +417 132 6795 20
239.1120 +730 576 6794 22
239.1121 +722 766 6793 57
239.1122 +906 422 6792 4
239.1123 +615 788 6791 71
239.1124 +566 369 6790 73
239.1125 +100 21 6789 40
239.1126 +957 901 6788 15
239.1127 +769 209 6787 86
239.1128 +576 708 6786 37
239.1129 +556 975 6785 61
239.1130 +810 651 6784 68
239.1131 +343 524 6783 0
239.1132 +634 330 6782 81
239.1133 +418 984 6781 29
239.1134 +348 328 6780 4
239.1135 +119 246 6779 46
239.1136 +691 289 6778 14
239.1137 +501 492 6777 18
239.1138 +733 758 6776 19
239.1139 +324 930 6775 1
239.1140 +126 679 6774 74
239.1141 +194 192 6773 46
239.1142 +345 524 6772 70
239.1143 +656 242 6771 21
239.1144 +82 582 6770 7
239.1145 +956 322 6769 22
239.1146 +797 955 6768 42
239.1147 +734 994 6767 19
239.1148 +827 173 6766 76
239.1149 +251 273 6765 40
239.1150 +487 279 6764 19
239.1151 +667 757 6763 93
239.1152 +282 492 6762 84
239.1153 +659 145 6761 68
239.1154 +260 840 6760 57
239.1155 +366 801 6759 12
239.1156 +960 236 6758 15
239.1157 +821 422 6757 6
239.1158 +900 358 6756 90
239.1159 +993 211 6755 57
239.1160 +521 265 6754 76
239.1161 +265 83 6753 81
239.1162 +346 159 6752 38
239.1163 +304 114 6751 62
239.1164 +39 448 6750 39
239.1165 +565 965 6749 89
239.1166 +813 96 6748 40
239.1167 +64 155 6747 13
239.1168 +147 330 6746 92
239.1169 +945 812 6745 90
239.1170 +182 943 6744 47
239.1171 +923 434 6743 25
239.1172 +44 763 6742 91
239.1173 +666 222 6741 4
239.1174 +482 505 6740 26
239.1175 +869 487 6739 47
239.1176 +941 266 6738 75
239.1177 +825 217 6737 74
239.1178 +517 14 6736 91
239.1179 +868 435 6735 20
239.1180 +509 214 6734 76
239.1181 +671 338 6733 25
239.1182 +540 876 6732 87
239.1183 +717 776 6731 37
239.1184 +17 791 6730 18
239.1185 +221 721 6729 61
239.1186 +49 2 6728 92
239.1187 +202 831 6727 11
239.1188 +579 716 6726 30
239.1189 +220 437 6725 64
239.1190 +876 505 6724 35
239.1191 +462 379 6723 83
239.1192 +99 500 6722 13
239.1193 +984 195 6721 82
239.1194 +70 569 6720 69
239.1195 +719 685 6719 79
239.1196 +170 812 6718 17
239.1197 +115 806 6717 84
239.1198 +278 660 6716 62
239.1199 +932 288 6715 35
239.1200 +125 521 6714 34
239.1201 +879 707 6713 41
239.1202 +304 308 6712 36
239.1203 +626 123 6711 11
239.1204 +883 903 6710 91
239.1205 +873 624 6709 35
239.1206 +5 325 6708 54
239.1207 +146 223 6707 5
239.1208 +371 264 6706 83
239.1209 +767 14 6705 34
239.1210 +814 929 6704 80
239.1211 +399 52 6703 24
239.1212 +184 246 6702 57
239.1213 +219 201 6701 67
239.1214 +279 563 6700 74
239.1215 +298 801 6699 0
239.1216 +102 494 6698 86
239.1217 +959 217 6697 85
239.1218 +249 491 6696 77
239.1219 +84 538 6695 60
239.1220 +877 560 6694 95
239.1221 +805 671 6693 41
239.1222 +45 896 6692 21
239.1223 +637 935 6691 96
239.1224 +761 733 6690 94
239.1225 +307 142 6689 98
239.1226 +276 7 6688 19
239.1227 +725 85 6687 14
239.1228 +953 169 6686 70
239.1229 +977 650 6685 16
239.1230 +889 538 6684 20
239.1231 +775 200 6683 7
239.1232 +960 248 6682 75
239.1233 +202 24 6681 40
239.1234 +591 959 6680 87
239.1235 +134 785 6679 45
239.1236 +922 51 6678 3
239.1237 +915 433 6677 55
239.1238 +519 545 6676 77
239.1239 +112 957 6675 97
239.1240 +337 134 6674 8
239.1241 +952 312 6673 11
239.1242 +224 351 6672 81
239.1243 +64 532 6671 75
239.1244 +174 421 6670 61
239.1245 +733 422 6669 45
239.1246 +618 479 6668 21
239.1247 +888 778 6667 0
239.1248 +588 797 6666 39
239.1249 +822 886 6665 40
239.1250 +822 974 6664 77
239.1251 +960 299 6663 38
239.1252 +819 55 6662 72
239.1253 +110 147 6661 15
239.1254 +998 154 6660 89
239.1255 +943 244 6659 44
239.1256 +700 204 6658 11
239.1257 +981 610 6657 73
239.1258 +910 989 6656 29
239.1259 +912 631 6655 76
239.1260 +675 389 6654 0
239.1261 +243 657 6653 86
239.1262 +908 567 6652 14
239.1263 +993 268 6651 70
239.1264 +909 450 6650 11
239.1265 +39 324 6649 5
239.1266 +594 385 6648 24
239.1267 +620 430 6647 71
239.1268 +358 533 6646 7
239.1269 +242 765 6645 99
239.1270 +731 138 6644 23
239.1271 +89 720 6643 43
239.1272 +299 433 6642 33
239.1273 +818 596 6641 91
239.1274 +125 56 6640 8
239.1275 +939 813 6639 86
239.1276 +954 523 6638 44
239.1277 +896 647 6637 97
239.1278 +768 73 6636 26
239.1279 +627 760 6635 11
239.1280 +417 805 6634 51
239.1281 +287 96 6633 64
239.1282 +836 420 6632 79
239.1283 +539 831 6631 48
239.1284 +243 213 6630 69
239.1285 +290 423 6629 18
239.1286 +875 472 6628 98
239.1287 +574 710 6627 5
239.1288 +312 146 6626 12
239.1289 +955 605 6625 14
239.1290 +708 868 6624 20
239.1291 +676 850 6623 13
239.1292 +588 310 6622 45
239.1293 +617 787 6621 29
239.1294 +790 507 6620 29
239.1295 +951 201 6619 95
239.1296 +762 926 6618 41
239.1297 +563 930 6617 30
239.1298 +541 987 6616 26
239.1299 +736 930 6615 35
239.1300 +18 78 6614 24
239.1301 +540 680 6613 3
239.1302 +522 153 6612 8
239.1303 +280 0 6611 97
239.1304 +306 343 6610 82
239.1305 +274 538 6609 83
239.1306 +996 114 6608 18
239.1307 +942 38 6607 19
239.1308 +56 904 6606 2
239.1309 +851 111 6605 80
239.1310 +398 213 6604 71
239.1311 +526 944 6603 47
239.1312 +153 116 6602 1
239.1313 +657 143 6601 24
239.1314 +805 988 6600 97
239.1315 +423 650 6599 3
239.1316 +75 990 6598 27
239.1317 +133 175 6597 5
239.1318 +793 218 6596 88
239.1319 +897 86 6595 20
239.1320 +268 240 6594 45
239.1321 +828 459 6593 87
239.1322 +972 776 6592 37
239.1323 +155 266 6591 49
239.1324 +338 943 6590 85
239.1325 +660 753 6589 38
239.1326 +814 223 6588 34
239.1327 +957 169 6587 94
239.1328 +131 680 6586 34
239.1329 +845 751 6585 89
239.1330 +781 580 6584 62
239.1331 +683 498 6583 44
239.1332 +509 877 6582 85
239.1333 +323 644 6581 81
239.1334 +189 470 6580 81
239.1335 +529 33 6579 67
239.1336 +54 406 6578 84
239.1337 +488 601 6577 85
239.1338 +928 444 6576 82
239.1339 +171 267 6575 28
239.1340 +81 188 6574 6
239.1341 +621 585 6573 9
239.1342 +233 37 6572 17
239.1343 +173 0 6571 18
239.1344 +437 138 6570 13
239.1345 +627 832 6569 66
239.1346 +804 989 6568 47
239.1347 +157 30 6567 56
239.1348 +176 539 6566 56
239.1349 +79 222 6565 75
239.1350 +602 966 6564 8
239.1351 +547 923 6563 46
239.1352 +36 988 6562 38
239.1353 +861 51 6561 5
239.1354 +306 473 6560 73
239.1355 +842 185 6559 81
239.1356 +959 908 6558 82
239.1357 +490 5 6557 64
239.1358 +317 802 6556 98
239.1359 +255 668 6555 9
239.1360 +42 628 6554 47
239.1361 +935 72 6553 5
239.1362 +936 328 6552 51
239.1363 +578 323 6551 17
239.1364 +287 925 6550 55
239.1365 +277 987 6549 46
239.1366 +902 176 6548 88
239.1367 +203 665 6547 46
239.1368 +134 883 6546 17
239.1369 +39 621 6545 6
239.1370 +556 420 6544 21
239.1371 +743 544 6543 10
239.1372 +4 335 6542 99
239.1373 +398 619 6541 35
239.1374 +937 91 6540 29
239.1375 +811 580 6539 1
239.1376 +510 414 6538 37
239.1377 +782 295 6537 69
239.1378 +261 111 6536 6
239.1379 +200 848 6535 9
239.1380 +875 105 6534 48
239.1381 +209 107 6533 81
239.1382 +715 641 6532 73
239.1383 +528 67 6531 60
239.1384 +511 280 6530 46
239.1385 +165 635 6529 12
239.1386 +119 675 6528 30
239.1387 +183 630 6527 72
239.1388 +262 973 6526 52
239.1389 +743 612 6525 6
239.1390 +998 669 6524 32
239.1391 +466 74 6523 66
239.1392 +574 132 6522 49
239.1393 +786 145 6521 18
239.1394 +645 334 6520 1
239.1395 +959 824 6519 34
239.1396 +44 573 6518 4
239.1397 +657 206 6517 93
239.1398 +361 459 6516 92
239.1399 +942 736 6515 51
239.1400 +595 658 6514 74
239.1401 +941 172 6513 53
239.1402 +986 305 6512 89
239.1403 +810 170 6511 78
239.1404 +510 671 6510 14
239.1405 +250 299 6509 68
239.1406 +367 109 6508 91
239.1407 +746 15 6507 38
239.1408 +723 401 6506 29
239.1409 +77 774 6505 41
239.1410 +485 212 6504 34
239.1411 +866 640 6503 65
239.1412 +135 103 6502 95
239.1413 +499 647 6501 17
239.1414 +371 454 6500 30
239.1415 +190 771 6499 25
239.1416 +93 526 6498 88
239.1417 +614 92 6497 62
239.1418 +626 876 6496 2
239.1419 +562 71 6495 64
239.1420 +571 693 6494 59
239.1421 +537 698 6493 61
239.1422 +455 779 6492 73
239.1423 +193 875 6491 63
239.1424 +682 40 6490 12
239.1425 +245 376 6489 18
239.1426 +434 262 6488 9
239.1427 +215 597 6487 47
239.1428 +804 376 6486 98
239.1429 +378 54 6485 6
239.1430 +995 973 6484 99
239.1431 +919 886 6483 3
239.1432 +903 95 6482 8
239.1433 +834 508 6481 26
239.1434 +664 946 6480 51
239.1435 +113 84 6479 43
239.1436 +664 618 6478 81
239.1437 +221 490 6477 21
239.1438 +322 924 6476 41
239.1439 +80 72 6475 42
239.1440 +86 956 6474 38
239.1441 +791 952 6473 7
239.1442 +587 820 6472 1
239.1443 +562 750 6471 6
239.1444 +862 74 6470 16
239.1445 +465 626 6469 55
239.1446 +128 592 6468 44
239.1447 +565 806 6467 44
239.1448 +852 985 6466 89
239.1449 +116 42 6465 24
239.1450 +4 307 6464 99
239.1451 +132 60 6463 29
239.1452 +69 946 6462 20
239.1453 +676 899 6461 2
239.1454 +448 619 6460 70
239.1455 +33 101 6459 39
239.1456 +786 6 6458 33
239.1457 +821 544 6457 56
239.1458 +942 656 6456 71
239.1459 +735 246 6455 73
239.1460 +246 699 6454 11
239.1461 +114 90 6453 87
239.1462 +46 179 6452 6
239.1463 +279 324 6451 39
239.1464 +518 303 6450 22
239.1465 +94 58 6449 41
239.1466 +461 774 6448 24
239.1467 +887 849 6447 96
239.1468 +410 976 6446 87
239.1469 +546 624 6445 20
239.1470 +609 239 6444 48
239.1471 +911 810 6443 13
239.1472 +855 668 6442 6
239.1473 +20 165 6441 76
239.1474 +244 812 6440 76
239.1475 +283 168 6439 42
239.1476 +924 281 6438 63
239.1477 +872 86 6437 57
239.1478 +352 671 6436 47
239.1479 +384 718 6435 86
239.1480 +429 355 6434 93
239.1481 +141 65 6433 69
239.1482 +502 300 6432 5
239.1483 +352 5 6431 83
239.1484 +644 338 6430 77
239.1485 +886 790 6429 96
239.1486 +195 59 6428 35
239.1487 +415 96 6427 5
239.1488 +952 614 6426 51
239.1489 +363 925 6425 96
239.1490 +290 239 6424 95
239.1491 +765 642 6423 28
239.1492 +294 221 6422 63
239.1493 +667 58 6421 15
239.1494 +547 814 6420 70
239.1495 +731 601 6419 75
239.1496 +962 307 6418 69
239.1497 +481 532 6417 78
239.1498 +689 551 6416 46
239.1499 +685 14 6415 58
239.1500 +597 666 6414 7
239.1501 +420 649 6413 52
239.1502 +163 488 6412 47
239.1503 +243 441 6411 62
239.1504 +213 950 6410 11
239.1505 +294 66 6409 81
239.1506 +775 911 6408 76
239.1507 +980 317 6407 48
239.1508 +536 873 6406 79
239.1509 +347 516 6405 0
239.1510 +17 548 6404 8
239.1511 +160 54 6403 17
239.1512 +46 842 6402 25
239.1513 +491 508 6401 91
239.1514 +884 302 6400 3
239.1515 +154 48 6399 91
239.1516 +593 287 6398 51
239.1517 +444 688 6397 79
239.1518 +356 789 6396 44
239.1519 +968 915 6395 18
239.1520 +493 911 6394 33
239.1521 +212 920 6393 85
239.1522 +333 337 6392 11
239.1523 +205 889 6391 55
239.1524 +254 112 6390 60
239.1525 +760 398 6389 72
239.1526 +598 725 6388 56
239.1527 +899 350 6387 14
239.1528 +874 254 6386 8
239.1529 +4 858 6385 38
239.1530 +990 474 6384 47
239.1531 +583 742 6383 28
239.1532 +447 558 6382 87
239.1533 +777 947 6381 12
239.1534 +713 878 6380 95
239.1535 +673 168 6379 49
239.1536 +375 411 6378 16
239.1537 +95 61 6377 69
239.1538 +396 699 6376 2
239.1539 +384 913 6375 87
239.1540 +731 193 6374 1
239.1541 +183 403 6373 40
239.1542 +611 750 6372 13
239.1543 +69 177 6371 67
239.1544 +710 456 6370 6
239.1545 +756 332 6369 4
239.1546 +350 461 6368 29
239.1547 +362 675 6367 27
239.1548 +785 154 6366 69
239.1549 +720 856 6365 1
239.1550 +790 605 6364 65
239.1551 +652 272 6363 54
239.1552 +572 464 6362 57
239.1553 +720 607 6361 54
239.1554 +124 22 6360 35
239.1555 +870 742 6359 95
239.1556 +786 17 6358 40
239.1557 +520 580 6357 98
239.1558 +297 686 6356 57
239.1559 +251 359 6355 6
239.1560 +333 104 6354 93
239.1561 +807 975 6353 13
239.1562 +857 30 6352 8
239.1563 +584 182 6351 85
239.1564 +280 405 6350 59
239.1565 +724 547 6349 25
239.1566 +437 418 6348 8
239.1567 +893 410 6347 26
239.1568 +327 512 6346 22
239.1569 +254 133 6345 4
239.1570 +129 793 6344 91
239.1571 +945 56 6343 52
239.1572 +847 227 6342 94
239.1573 +777 256 6341 27
239.1574 +857 342 6340 30
239.1575 +129 169 6339 55
239.1576 +7 817 6338 28
239.1577 +897 43 6337 54
239.1578 +379 176 6336 56
239.1579 +339 128 6335 7
239.1580 +736 392 6334 12
239.1581 +828 576 6333 18
239.1582 +971 676 6332 9
239.1583 +913 969 6331 7
239.1584 +172 749 6330 91
239.1585 +352 267 6329 72
239.1586 +774 744 6328 12
239.1587 +867 977 6327 11
239.1588 +47 493 6326 51
239.1589 +736 947 6325 3
239.1590 +815 941 6324 60
239.1591 +899 85 6323 90
239.1592 +706 27 6322 85
239.1593 +220 150 6321 5
239.1594 +481 191 6320 74
239.1595 +522 607 6319 82
239.1596 +767 11 6318 57
239.1597 +483 592 6317 90
239.1598 +545 478 6316 81
239.1599 +5 436 6315 31
239.1600 +856 695 6314 92
239.1601 +58 50 6313 91
239.1602 +876 798 6312 19
239.1603 +959 317 6311 48
239.1604 +583 920 6310 73
239.1605 +595 242 6309 95
239.1606 +419 671 6308 75
239.1607 +113 86 6307 28
239.1608 +42 508 6306 93
239.1609 +740 390 6305 54
239.1610 +644 4 6304 14
239.1611 +251 722 6303 79
239.1612 +481 706 6302 18
239.1613 +396 747 6301 91
239.1614 +677 779 6300 37
239.1615 +571 203 6299 98
239.1616 +584 471 6298 17
239.1617 +578 345 6297 30
239.1618 +118 397 6296 7
239.1619 +386 391 6295 30
239.1620 +281 350 6294 9
239.1621 +16 617 6293 39
239.1622 +958 263 6292 77
239.1623 +968 541 6291 8
239.1624 +575 387 6290 71
239.1625 +732 811 6289 10
239.1626 +125 870 6288 98
239.1627 +948 235 6287 0
239.1628 +5 768 6286 45
239.1629 +40 205 6285 73
239.1630 +733 703 6284 10
239.1631 +353 622 6283 26
239.1632 +722 685 6282 5
239.1633 +154 365 6281 99
239.1634 +576 612 6280 39
239.1635 +940 120 6279 84
239.1636 +635 979 6278 60
239.1637 +466 546 6277 17
239.1638 +563 727 6276 94
239.1639 +501 627 6275 96
239.1640 +80 838 6274 30
239.1641 +937 208 6273 38
239.1642 +319 67 6272 63
239.1643 +753 597 6271 56
239.1644 +492 549 6270 57
239.1645 +140 235 6269 63
239.1646 +433 430 6268 30
239.1647 +818 233 6267 16
239.1648 +100 977 6266 90
239.1649 +789 658 6265 6
239.1650 +630 925 6264 42
239.1651 +141 749 6263 14
239.1652 +469 62 6262 61
239.1653 +47 990 6261 56
239.1654 +313 941 6260 26
239.1655 +805 331 6259 35
239.1656 +196 135 6258 70
239.1657 +256 266 6257 61
239.1658 +318 841 6256 71
239.1659 +732 640 6255 31
239.1660 +176 277 6254 15
239.1661 +687 526 6253 48
239.1662 +72 50 6252 67
239.1663 +48 305 6251 42
239.1664 +610 909 6250 73
239.1665 +196 644 6249 50
239.1666 +868 92 6248 60
239.1667 +424 895 6247 93
239.1668 +201 407 6246 93
239.1669 +362 152 6245 58
239.1670 +750 669 6244 55
239.1671 +475 817 6243 48
239.1672 +745 249 6242 61
239.1673 +395 688 6241 2
239.1674 +264 225 6240 43
239.1675 +551 898 6239 41
239.1676 +197 669 6238 32
239.1677 +487 2 6237 44
239.1678 +255 351 6236 22
239.1679 +483 29 6235 83
239.1680 +851 67 6234 61
239.1681 +568 874 6233 27
239.1682 +560 591 6232 73
239.1683 +463 584 6231 34
239.1684 +326 25 6230 13
239.1685 +228 86 6229 71
239.1686 +667 883 6228 35
239.1687 +651 220 6227 70
239.1688 +321 385 6226 23
239.1689 +961 226 6225 77
239.1690 +193 336 6224 63
239.1691 +282 544 6223 28
239.1692 +7 380 6222 0
239.1693 +559 219 6221 9
239.1694 +939 417 6220 13
239.1695 +202 358 6219 9
239.1696 +663 645 6218 56
239.1697 +834 477 6217 1
239.1698 +158 459 6216 32
239.1699 +889 140 6215 36
239.1700 +792 349 6214 76
239.1701 +164 274 6213 91
239.1702 +161 911 6212 27
239.1703 +801 960 6211 44
239.1704 +59 38 6210 61
239.1705 +712 536 6209 73
239.1706 +167 545 6208 53
239.1707 +18 686 6207 82
239.1708 +318 969 6206 67
239.1709 +791 591 6205 26
239.1710 +74 857 6204 9
239.1711 +362 635 6203 62
239.1712 +951 827 6202 0
239.1713 +921 828 6201 36
239.1714 +502 882 6200 74
239.1715 +990 198 6199 34
239.1716 +858 709 6198 54
239.1717 +717 153 6197 14
239.1718 +377 406 6196 69
239.1719 +734 172 6195 52
239.1720 +222 469 6194 71
239.1721 +808 625 6193 71
239.1722 +998 642 6192 41
239.1723 +945 618 6191 3
239.1724 +684 394 6190 41
239.1725 +489 801 6189 51
239.1726 +556 396 6188 13
239.1727 +747 449 6187 14
239.1728 +233 172 6186 34
239.1729 +703 810 6185 64
239.1730 +843 4 6184 51
239.1731 +982 300 6183 41
239.1732 +24 381 6182 80
239.1733 +223 612 6181 5
239.1734 +593 906 6180 26
239.1735 +405 380 6179 19
239.1736 +946 990 6178 93
239.1737 +276 800 6177 80
239.1738 +362 697 6176 51
239.1739 +805 131 6175 53
239.1740 +704 97 6174 85
239.1741 +919 604 6173 86
239.1742 +768 757 6172 95
239.1743 +705 790 6171 80
239.1744 +525 66 6170 63
239.1745 +389 262 6169 18
239.1746 +190 123 6168 45
239.1747 +103 295 6167 67
239.1748 +566 983 6166 91
239.1749 +33 670 6165 55
239.1750 +493 998 6164 10
239.1751 +847 902 6163 78
239.1752 +966 157 6162 15
239.1753 +724 170 6161 6
239.1754 +804 441 6160 17
239.1755 +138 729 6159 13
239.1756 +828 788 6158 19
239.1757 +312 756 6157 8
239.1758 +312 356 6156 53
239.1759 +671 455 6155 53
239.1760 +96 316 6154 53
239.1761 +744 633 6153 64
239.1762 +987 87 6152 88
239.1763 +728 882 6151 24
239.1764 +712 43 6150 91
239.1765 +941 936 6149 66
239.1766 +31 112 6148 30
239.1767 +399 550 6147 51
239.1768 +900 3 6146 99
239.1769 +139 993 6145 64
239.1770 +682 893 6144 57
239.1771 +546 765 6143 35
239.1772 +204 638 6142 75
239.1773 +839 322 6141 25
239.1774 +106 253 6140 1
239.1775 +824 356 6139 77
239.1776 +562 793 6138 90
239.1777 +546 516 6137 63
239.1778 +9 359 6136 49
239.1779 +100 65 6135 76
239.1780 +127 223 6134 45
239.1781 +126 595 6133 13
239.1782 +316 497 6132 34
239.1783 +69 242 6131 36
239.1784 +896 246 6130 73
239.1785 +562 860 6129 28
239.1786 +277 277 6128 26
239.1787 +156 132 6127 1
239.1788 +293 737 6126 53
239.1789 +842 305 6125 90
239.1790 +628 319 6124 97
239.1791 +97 795 6123 0
239.1792 +255 976 6122 81
239.1793 +996 632 6121 24
239.1794 +385 450 6120 17
239.1795 +582 20 6119 33
239.1796 +145 245 6118 28
239.1797 +395 478 6117 12
239.1798 +432 626 6116 86
239.1799 +985 937 6115 45
239.1800 +524 971 6114 21
239.1801 +819 190 6113 53
239.1802 +343 563 6112 84
239.1803 +182 73 6111 25
239.1804 +429 839 6110 61
239.1805 +774 48 6109 80
239.1806 +767 164 6108 43
239.1807 +852 257 6107 75
239.1808 +689 411 6106 96
239.1809 +966 237 6105 44
239.1810 +780 683 6104 46
239.1811 +626 688 6103 70
239.1812 +490 583 6102 47
239.1813 +234 647 6101 16
239.1814 +791 807 6100 75
239.1815 +883 365 6099 65
239.1816 +906 687 6098 0
239.1817 +845 787 6097 91
239.1818 +174 515 6096 16
239.1819 +554 986 6095 72
239.1820 +994 755 6094 18
239.1821 +104 229 6093 15
239.1822 +935 315 6092 13
239.1823 +839 407 6091 25
239.1824 +442 99 6090 44
239.1825 +678 646 6089 90
239.1826 +899 92 6088 97
239.1827 +272 752 6087 6
239.1828 +528 439 6086 67
239.1829 +231 537 6085 62
239.1830 +525 31 6084 55
239.1831 +914 18 6083 88
239.1832 +908 880 6082 16
239.1833 +307 812 6081 9
239.1834 +452 536 6080 39
239.1835 +553 929 6079 76
239.1836 +340 916 6078 77
239.1837 +312 389 6077 62
239.1838 +902 51 6076 74
239.1839 +506 60 6075 29
239.1840 +13 669 6074 70
239.1841 +137 720 6073 61
239.1842 +67 72 6072 0
239.1843 +276 698 6071 60
239.1844 +606 633 6070 85
239.1845 +13 985 6069 89
239.1846 +526 151 6068 21
239.1847 +337 882 6067 2
239.1848 +991 447 6066 41
239.1849 +390 590 6065 39
239.1850 +948 95 6064 49
239.1851 +648 604 6063 87
239.1852 +374 405 6062 7
239.1853 +64 744 6061 79
239.1854 +648 956 6060 66
239.1855 +833 685 6059 59
239.1856 +269 185 6058 48
239.1857 +434 617 6057 18
239.1858 +857 13 6056 34
239.1859 +494 903 6055 60
239.1860 +490 617 6054 44
239.1861 +198 805 6053 30
239.1862 +661 278 6052 27
239.1863 +787 121 6051 30
239.1864 +271 76 6050 41
239.1865 +500 105 6049 81
239.1866 +567 298 6048 56
239.1867 +604 842 6047 83
239.1868 +110 746 6046 57
239.1869 +285 157 6045 36
239.1870 +812 141 6044 0
239.1871 +526 26 6043 29
239.1872 +156 965 6042 53
239.1873 +44 893 6041 87
239.1874 +971 600 6040 51
239.1875 +807 251 6039 77
239.1876 +456 729 6038 93
239.1877 +95 257 6037 96
239.1878 +588 213 6036 49
239.1879 +15 359 6035 82
239.1880 +115 712 6034 47
239.1881 +61 753 6033 28
239.1882 +71 664 6032 36
239.1883 +292 356 6031 11
239.1884 +349 745 6030 7
239.1885 +521 837 6029 16
239.1886 +472 970 6028 35
239.1887 +43 469 6027 36
239.1888 +854 667 6026 50
239.1889 +646 352 6025 57
239.1890 +958 186 6024 90
239.1891 +89 915 6023 5
239.1892 +307 257 6022 98
239.1893 +611 38 6021 77
239.1894 +907 910 6020 94
239.1895 +867 811 6019 82
239.1896 +500 991 6018 4
239.1897 +802 854 6017 42
239.1898 +314 933 6016 18
239.1899 +166 672 6015 20
239.1900 +271 845 6014 68
239.1901 +657 65 6013 86
239.1902 +219 209 6012 78
239.1903 +127 836 6011 69
239.1904 +99 114 6010 70
239.1905 +820 778 6009 3
239.1906 +136 621 6008 36
239.1907 +920 238 6007 69
239.1908 +260 981 6006 48
239.1909 +827 519 6005 14
239.1910 +779 819 6004 89
239.1911 +855 87 6003 61
239.1912 +373 85 6002 43
239.1913 +721 991 6001 9
239.1914 +336 664 6000 2
239.1915 +157 671 5999 27
239.1916 +382 669 5998 68
239.1917 +256 210 5997 21
239.1918 +462 338 5996 66
239.1919 +699 253 5995 43
239.1920 +731 281 5994 4
239.1921 +1 174 5993 92
239.1922 +94 346 5992 48
239.1923 +326 63 5991 65
239.1924 +993 749 5990 38
239.1925 +2 595 5989 17
239.1926 +459 467 5988 77
239.1927 +871 555 5987 12
239.1928 +85 226 5986 79
239.1929 +971 385 5985 76
239.1930 +106 123 5984 96
239.1931 +828 441 5983 73
239.1932 +283 831 5982 90
239.1933 +313 265 5981 76
239.1934 +153 206 5980 33
239.1935 +128 403 5979 99
239.1936 +911 649 5978 54
239.1937 +329 331 5977 58
239.1938 +840 31 5976 78
239.1939 +262 794 5975 11
239.1940 +682 237 5974 86
239.1941 +609 823 5973 27
239.1942 +565 139 5972 54
239.1943 +58 434 5971 96
239.1944 +803 342 5970 15
239.1945 +754 447 5969 2
239.1946 +317 955 5968 21
239.1947 +300 801 5967 58
239.1948 +236 672 5966 48
239.1949 +557 248 5965 57
239.1950 +414 586 5964 57
239.1951 +684 733 5963 7
239.1952 +704 575 5962 4
239.1953 +91 809 5961 50
239.1954 +894 133 5960 25
239.1955 +492 809 5959 4
239.1956 +153 634 5958 43
239.1957 +129 93 5957 1
239.1958 +424 909 5956 6
239.1959 +661 998 5955 67
239.1960 +853 506 5954 14
239.1961 +157 29 5953 73
239.1962 +765 536 5952 97
239.1963 +676 251 5951 61
239.1964 +324 207 5950 19
239.1965 +175 611 5949 40
239.1966 +540 419 5948 33
239.1967 +184 953 5947 2
239.1968 +911 384 5946 70
239.1969 +492 536 5945 76
239.1970 +477 412 5944 80
239.1971 +492 750 5943 69
239.1972 +285 367 5942 39
239.1973 +43 415 5941 8
239.1974 +595 795 5940 35
239.1975 +192 62 5939 14
239.1976 +465 315 5938 63
239.1977 +569 319 5937 35
239.1978 +847 941 5936 27
239.1979 +123 955 5935 41
239.1980 +662 111 5934 1
239.1981 +383 305 5933 98
239.1982 +951 301 5932 20
239.1983 +619 737 5931 24
239.1984 +733 202 5930 44
239.1985 +746 513 5929 40
239.1986 +995 279 5928 72
239.1987 +378 82 5927 89
239.1988 +986 854 5926 72
239.1989 +844 403 5925 72
239.1990 +806 30 5924 46
239.1991 +3 776 5923 27
239.1992 +563 965 5922 43
239.1993 +534 793 5921 33
239.1994 +689 44 5920 88
239.1995 +234 677 5919 98
239.1996 +196 829 5918 75
239.1997 +228 175 5917 61
239.1998 +450 997 5916 39
239.1999 +373 262 5915 14
239.2000 +253 182 5914 3
239.2001 +810 847 5913 80
239.2002 +172 99 5912 43
239.2003 +748 445 5911 2
239.2004 +367 899 5910 84
239.2005 +848 236 5909 45
239.2006 +654 132 5908 3
239.2007 +177 225 5907 96
239.2008 +735 250 5906 77
239.2009 +80 103 5905 7
239.2010 +334 235 5904 11
239.2011 +748 363 5903 44
239.2012 +653 410 5902 63
239.2013 +546 183 5901 42
239.2014 +662 390 5900 38
239.2015 +103 417 5899 51
239.2016 +907 70 5898 19
239.2017 +975 189 5897 47
239.2018 +146 701 5896 44
239.2019 +868 957 5895 65
239.2020 +871 676 5894 74
239.2021 +952 804 5893 58
239.2022 +227 214 5892 9
239.2023 +792 41 5891 10
239.2024 +972 862 5890 88
239.2025 +347 325 5889 55
239.2026 +880 716 5888 19
239.2027 +487 34 5887 93
239.2028 +743 786 5886 82
239.2029 +280 909 5885 27
239.2030 +872 159 5884 99
239.2031 +590 492 5883 91
239.2032 +172 987 5882 72
239.2033 +179 223 5881 43
239.2034 +537 324 5880 81
239.2035 +608 363 5879 62
239.2036 +681 264 5878 46
239.2037 +248 101 5877 39
239.2038 +877 552 5876 74
239.2039 +750 280 5875 46
239.2040 +667 77 5874 40
239.2041 +505 193 5873 28
239.2042 +763 290 5872 41
239.2043 +899 614 5871 99
239.2044 +961 194 5870 64
239.2045 +98 158 5869 92
239.2046 +162 73 5868 92
239.2047 +549 648 5867 43
239.2048 +271 280 5866 37
239.2049 +203 54 5865 12
239.2050 +883 126 5864 8
239.2051 +902 864 5863 16
239.2052 +676 424 5862 74
239.2053 +420 351 5861 86
239.2054 +35 712 5860 93
239.2055 +85 2 5859 86
239.2056 +424 493 5858 93
239.2057 +368 62 5857 61
239.2058 +226 244 5856 27
239.2059 +928 42 5855 6
239.2060 +261 921 5854 31
239.2061 +440 420 5853 98
239.2062 +72 877 5852 22
239.2063 +639 925 5851 25
239.2064 +710 75 5850 38
239.2065 +508 927 5849 95
239.2066 +431 322 5848 66
239.2067 +817 334 5847 5
239.2068 +202 210 5846 14
239.2069 +121 748 5845 29
239.2070 +501 338 5844 66
239.2071 +542 754 5843 82
239.2072 +952 970 5842 36
239.2073 +849 871 5841 43
239.2074 +148 434 5840 92
239.2075 +604 289 5839 20
239.2076 +988 603 5838 7
239.2077 +123 914 5837 61
239.2078 +462 844 5836 61
239.2079 +409 631 5835 8
239.2080 +584 845 5834 61
239.2081 +783 453 5833 95
239.2082 +99 935 5832 58
239.2083 +436 504 5831 10
239.2084 +144 726 5830 70
239.2085 +686 124 5829 54
239.2086 +689 464 5828 61
239.2087 +70 998 5827 86
239.2088 +212 534 5826 66
239.2089 +786 461 5825 5
239.2090 +392 660 5824 82
239.2091 +517 369 5823 80
239.2092 +431 487 5822 68
239.2093 +777 401 5821 66
239.2094 +602 157 5820 29
239.2095 +659 927 5819 45
239.2096 +465 751 5818 99
239.2097 +464 203 5817 61
239.2098 +72 608 5816 85
239.2099 +800 227 5815 42
239.2100 +291 23 5814 39
239.2101 +881 117 5813 87
239.2102 +85 21 5812 8
239.2103 +243 370 5811 65
239.2104 +230 833 5810 17
239.2105 +175 461 5809 94
239.2106 +548 378 5808 19
239.2107 +594 760 5807 0
239.2108 +380 432 5806 39
239.2109 +204 31 5805 27
239.2110 +905 519 5804 50
239.2111 +96 787 5803 40
239.2112 +650 432 5802 79
239.2113 +536 479 5801 84
239.2114 +372 231 5800 1
239.2115 +82 748 5799 5
239.2116 +618 192 5798 62
239.2117 +328 609 5797 95
239.2118 +400 120 5796 21
239.2119 +512 762 5795 17
239.2120 +731 99 5794 29
239.2121 +354 613 5793 80
239.2122 +953 954 5792 44
239.2123 +247 829 5791 11
239.2124 +482 958 5790 16
239.2125 +555 427 5789 28
239.2126 +583 673 5788 46
239.2127 +489 740 5787 29
239.2128 +357 37 5786 92
239.2129 +662 877 5785 88
239.2130 +486 489 5784 78
239.2131 +659 364 5783 37
239.2132 +124 331 5782 40
239.2133 +871 949 5781 70
239.2134 +530 874 5780 76
239.2135 +754 826 5779 92
239.2136 +933 173 5778 97
239.2137 +702 362 5777 9
239.2138 +160 40 5776 13
239.2139 +387 107 5775 69
239.2140 +124 403 5774 17
239.2141 +33 975 5773 82
239.2142 +381 695 5772 53
239.2143 +74 940 5771 25
239.2144 +48 838 5770 34
239.2145 +652 953 5769 77
239.2146 +810 879 5768 82
239.2147 +322 961 5767 23
239.2148 +932 436 5766 54
239.2149 +704 519 5765 77
239.2150 +427 348 5764 26
239.2151 +279 293 5763 9
239.2152 +755 280 5762 65
239.2153 +101 913 5761 30
239.2154 +884 564 5760 2
239.2155 +74 955 5759 39
239.2156 +917 590 5758 84
239.2157 +525 688 5757 48
239.2158 +916 768 5756 38
239.2159 +170 510 5755 22
239.2160 +55 171 5754 27
239.2161 +12 439 5753 14
239.2162 +366 345 5752 52
239.2163 +349 280 5751 65
239.2164 +609 630 5750 21
239.2165 +364 553 5749 81
239.2166 +901 354 5748 15
239.2167 +919 98 5747 39
239.2168 +258 161 5746 60
239.2169 +339 951 5745 74
239.2170 +731 129 5744 11
239.2171 +94 623 5743 4
239.2172 +64 870 5742 64
239.2173 +649 436 5741 1
239.2174 +77 406 5740 73
239.2175 +198 653 5739 24
239.2176 +256 764 5738 46
239.2177 +936 784 5737 98
239.2178 +210 862 5736 66
239.2179 +822 631 5735 91
239.2180 +505 72 5734 60
239.2181 +753 396 5733 63
239.2182 +433 627 5732 2
239.2183 +29 278 5731 41
239.2184 +753 495 5730 57
239.2185 +889 781 5729 87
239.2186 +980 481 5728 94
239.2187 +921 320 5727 31
239.2188 +231 741 5726 72
239.2189 +558 312 5725 38
239.2190 +675 970 5724 31
239.2191 +769 607 5723 75
239.2192 +349 614 5722 31
239.2193 +782 842 5721 40
239.2194 +713 693 5720 27
239.2195 +300 936 5719 86
239.2196 +160 623 5718 90
239.2197 +578 592 5717 5
239.2198 +429 338 5716 69
239.2199 +341 70 5715 67
239.2200 +363 565 5714 88
239.2201 +992 432 5713 90
239.2202 +771 914 5712 41
239.2203 +149 128 5711 56
239.2204 +757 411 5710 6
239.2205 +313 955 5709 41
239.2206 +30 850 5708 13
239.2207 +253 367 5707 58
239.2208 +268 18 5706 14
239.2209 +505 788 5705 8
239.2210 +132 976 5704 97
239.2211 +517 487 5703 37
239.2212 +786 852 5702 22
239.2213 +716 498 5701 62
239.2214 +456 655 5700 39
239.2215 +104 274 5699 44
239.2216 +483 557 5698 28
239.2217 +348 433 5697 77
239.2218 +229 60 5696 98
239.2219 +811 109 5695 76
239.2220 +489 608 5694 37
239.2221 +635 149 5693 61
239.2222 +354 598 5692 73
239.2223 +842 229 5691 6
239.2224 +380 948 5690 26
239.2225 +717 161 5689 35
239.2226 +123 505 5688 62
239.2227 +372 791 5687 13
239.2228 +950 222 5686 11
239.2229 +501 389 5685 41
239.2230 +459 758 5684 32
239.2231 +550 883 5683 85
239.2232 +368 661 5682 28
239.2233 +281 809 5681 51
239.2234 +787 908 5680 46
239.2235 +655 730 5679 66
239.2236 +713 486 5678 59
239.2237 +569 15 5677 75
239.2238 +833 701 5676 42
239.2239 +630 95 5675 44
239.2240 +875 467 5674 4
239.2241 +221 573 5673 90
239.2242 +851 769 5672 18
239.2243 +901 49 5671 8
239.2244 +177 798 5670 49
239.2245 +244 69 5669 13
239.2246 +471 842 5668 94
239.2247 +314 329 5667 14
239.2248 +606 972 5666 73
239.2249 +627 406 5665 20
239.2250 +894 133 5664 75
239.2251 +803 727 5663 65
239.2252 +720 93 5662 37
239.2253 +250 593 5661 94
239.2254 +729 361 5660 72
239.2255 +227 190 5659 93
239.2256 +512 797 5658 77
239.2257 +357 409 5657 15
239.2258 +565 532 5656 70
239.2259 +272 448 5655 97
239.2260 +405 101 5654 73
239.2261 +634 283 5653 9
239.2262 +499 420 5652 8
239.2263 +231 225 5651 46
239.2264 +171 791 5650 52
239.2265 +392 160 5649 50
239.2266 +387 615 5648 71
239.2267 +876 448 5647 15
239.2268 +84 729 5646 79
239.2269 +346 244 5645 29
239.2270 +817 642 5644 86
239.2271 +862 7 5643 77
239.2272 +195 613 5642 13
239.2273 +433 947 5641 26
239.2274 +631 19 5640 5
239.2275 +544 787 5639 77
239.2276 +166 558 5638 0
239.2277 +719 364 5637 51
239.2278 +484 498 5636 79
239.2279 +602 425 5635 73
239.2280 +634 95 5634 52
239.2281 +394 637 5633 95
239.2282 +665 866 5632 66
239.2283 +928 208 5631 76
239.2284 +232 280 5630 80
239.2285 +228 773 5629 8
239.2286 +194 494 5628 37
239.2287 +866 718 5627 44
239.2288 +72 55 5626 23
239.2289 +330 208 5625 88
239.2290 +458 573 5624 96
239.2291 +770 287 5623 23
239.2292 +658 905 5622 72
239.2293 +927 958 5621 73
239.2294 +506 716 5620 69
239.2295 +279 709 5619 0
239.2296 +776 929 5618 3
239.2297 +662 213 5617 32
239.2298 +846 351 5616 79
239.2299 +634 914 5615 74
239.2300 +285 727 5614 87
239.2301 +382 510 5613 68
239.2302 +946 992 5612 11
239.2303 +242 41 5611 73
239.2304 +6 691 5610 42
239.2305 +779 969 5609 22
239.2306 +715 706 5608 50
239.2307 +861 534 5607 11
239.2308 +437 52 5606 81
239.2309 +186 869 5605 21
239.2310 +217 183 5604 34
239.2311 +518 576 5603 90
239.2312 +950 380 5602 43
239.2313 +349 311 5601 70
239.2314 +722 192 5600 23
239.2315 +263 724 5599 22
239.2316 +172 389 5598 6
239.2317 +481 297 5597 85
239.2318 +182 604 5596 42
239.2319 +686 863 5595 25
239.2320 +607 445 5594 96
239.2321 +196 468 5593 69
239.2322 +69 731 5592 56
239.2323 +118 467 5591 60
239.2324 +468 9 5590 62
239.2325 +334 163 5589 45
239.2326 +92 209 5588 9
239.2327 +693 429 5587 69
239.2328 +740 174 5586 29
239.2329 +417 280 5585 49
239.2330 +977 270 5584 7
239.2331 +736 131 5583 41
239.2332 +263 967 5582 12
239.2333 +458 972 5581 95
239.2334 +845 169 5580 65
239.2335 +953 367 5579 13
239.2336 +780 401 5578 24
239.2337 +254 390 5577 39
239.2338 +893 803 5576 95
239.2339 +10 417 5575 32
239.2340 +139 667 5574 44
239.2341 +163 284 5573 24
239.2342 +994 176 5572 47
239.2343 +803 300 5571 80
239.2344 +802 516 5570 61
239.2345 +966 891 5569 89
239.2346 +10 842 5568 17
239.2347 +586 446 5567 52
239.2348 +386 629 5566 36
239.2349 +749 882 5565 88
239.2350 +383 200 5564 87
239.2351 +107 767 5563 97
239.2352 +875 668 5562 16
239.2353 +784 191 5561 19
239.2354 +624 720 5560 0
239.2355 +48 720 5559 83
239.2356 +395 646 5558 95
239.2357 +817 165 5557 42
239.2358 +747 477 5556 20
239.2359 +682 12 5555 63
239.2360 +432 895 5554 36
239.2361 +99 806 5553 27
239.2362 +476 977 5552 23
239.2363 +471 190 5551 9
239.2364 +0 165 5550 15
239.2365 +73 880 5549 57
239.2366 +481 531 5548 65
239.2367 +687 223 5547 57
239.2368 +465 563 5546 7
239.2369 +116 271 5545 6
239.2370 +89 89 5544 24
239.2371 +828 44 5543 33
239.2372 +787 140 5542 62
239.2373 +24 932 5541 0
239.2374 +284 583 5540 47
239.2375 +349 922 5539 92
239.2376 +307 75 5538 59
239.2377 +660 507 5537 79
239.2378 +291 5 5536 22
239.2379 +181 815 5535 34
239.2380 +45 917 5534 2
239.2381 +903 708 5533 26
239.2382 +208 619 5532 4
239.2383 +348 533 5531 76
239.2384 +661 544 5530 74
239.2385 +847 334 5529 93
239.2386 +567 798 5528 4
239.2387 +502 571 5527 64
239.2388 +189 872 5526 36
239.2389 +897 323 5525 11
239.2390 +208 765 5524 13
239.2391 +89 220 5523 14
239.2392 +86 277 5522 69
239.2393 +988 22 5521 85
239.2394 +209 805 5520 68
239.2395 +536 892 5519 81
239.2396 +226 395 5518 28
239.2397 +699 277 5517 6
239.2398 +549 258 5516 31
239.2399 +557 974 5515 29
239.2400 +544 993 5514 68
239.2401 +942 446 5513 11
239.2402 +254 835 5512 0
239.2403 +217 173 5511 9
239.2404 +912 873 5510 77
239.2405 +497 533 5509 67
239.2406 +117 216 5508 31
239.2407 +19 751 5507 52
239.2408 +283 21 5506 14
239.2409 +981 603 5505 99
239.2410 +546 569 5504 1
239.2411 +611 116 5503 60
239.2412 +662 905 5502 68
239.2413 +300 319 5501 3
239.2414 +339 104 5500 30
239.2415 +317 363 5499 41
239.2416 +465 783 5498 37
239.2417 +729 377 5497 9
239.2418 +417 157 5496 73
239.2419 +33 978 5495 30
239.2420 +452 411 5494 43
239.2421 +211 913 5493 93
239.2422 +585 650 5492 94
239.2423 +214 732 5491 36
239.2424 +741 889 5490 96
239.2425 +580 35 5489 2
239.2426 +405 281 5488 85
239.2427 +219 362 5487 73
239.2428 +179 434 5486 31
239.2429 +566 867 5485 38
239.2430 +497 499 5484 58
239.2431 +263 986 5483 24
239.2432 +918 586 5482 62
239.2433 +842 402 5481 37
239.2434 +854 938 5480 47
239.2435 +754 170 5479 16
239.2436 +919 116 5478 17
239.2437 +928 423 5477 18
239.2438 +566 928 5476 4
239.2439 +367 803 5475 61
239.2440 +512 338 5474 6
239.2441 +400 616 5473 23
239.2442 +184 254 5472 34
239.2443 +464 898 5471 7
239.2444 +767 311 5470 98
239.2445 +53 986 5469 9
239.2446 +693 988 5468 83
239.2447 +494 145 5467 99
239.2448 +125 427 5466 36
239.2449 +464 543 5465 19
239.2450 +722 834 5464 85
239.2451 +362 889 5463 11
239.2452 +355 268 5462 21
239.2453 +586 88 5461 71
239.2454 +324 887 5460 69
239.2455 +998 264 5459 71
239.2456 +843 844 5458 35
239.2457 +717 629 5457 19
239.2458 +884 162 5456 36
239.2459 +708 343 5455 66
239.2460 +945 744 5454 74
239.2461 +621 894 5453 35
239.2462 +179 496 5452 0
239.2463 +200 23 5451 76
239.2464 +623 982 5450 26
239.2465 +419 354 5449 32
239.2466 +215 161 5448 15
239.2467 +466 828 5447 12
239.2468 +819 708 5446 83
239.2469 +598 919 5445 17
239.2470 +849 381 5444 76
239.2471 +397 353 5443 32
239.2472 +473 237 5442 44
239.2473 +41 506 5441 97
239.2474 +628 936 5440 57
239.2475 +192 171 5439 20
239.2476 +332 29 5438 20
239.2477 +119 291 5437 74
239.2478 +789 658 5436 64
239.2479 +537 411 5435 22
239.2480 +28 439 5434 74
239.2481 +115 882 5433 45
239.2482 +731 462 5432 92
239.2483 +569 401 5431 43
239.2484 +765 374 5430 41
239.2485 +141 998 5429 43
239.2486 +737 456 5428 86
239.2487 +633 100 5427 21
239.2488 +246 427 5426 33
239.2489 +971 471 5425 25
239.2490 +557 296 5424 50
239.2491 +419 527 5423 91
239.2492 +61 492 5422 38
239.2493 +27 19 5421 16
239.2494 +375 977 5420 80
239.2495 +542 574 5419 62
239.2496 +355 648 5418 40
239.2497 +673 882 5417 10
239.2498 +956 77 5416 38
239.2499 +174 743 5415 27
239.2500 +769 595 5414 41
239.2501 +35 528 5413 13
239.2502 +472 222 5412 35
239.2503 +41 357 5411 3
239.2504 +402 181 5410 65
239.2505 +926 219 5409 83
239.2506 +765 299 5408 18
239.2507 +804 717 5407 68
239.2508 +333 112 5406 71
239.2509 +148 860 5405 78
239.2510 +66 275 5404 40
239.2511 +306 780 5403 73
239.2512 +865 323 5402 56
239.2513 +176 381 5401 43
239.2514 +961 819 5400 63
239.2515 +919 646 5399 47
239.2516 +582 504 5398 16
239.2517 +604 965 5397 96
239.2518 +251 934 5396 47
239.2519 +585 376 5395 18
239.2520 +494 671 5394 8
239.2521 +456 170 5393 76
239.2522 +941 131 5392 44
239.2523 +562 791 5391 68
239.2524 +172 163 5390 21
239.2525 +142 315 5389 4
239.2526 +538 199 5388 33
239.2527 +30 490 5387 97
239.2528 +558 285 5386 35
239.2529 +704 103 5385 66
239.2530 +501 320 5384 9
239.2531 +38 320 5383 3
239.2532 +339 751 5382 51
239.2533 +628 474 5381 37
239.2534 +848 172 5380 38
239.2535 +115 704 5379 3
239.2536 +709 360 5378 60
239.2537 +204 624 5377 50
239.2538 +181 686 5376 47
239.2539 +783 575 5375 85
239.2540 +0 52 5374 20
239.2541 +569 523 5373 46
239.2542 +276 135 5372 69
239.2543 +302 989 5371 71
239.2544 +468 359 5370 78
239.2545 +343 427 5369 73
239.2546 +736 96 5368 40
239.2547 +937 35 5367 50
239.2548 +110 619 5366 2
239.2549 +523 649 5365 39
239.2550 +529 741 5364 78
239.2551 +387 762 5363 43
239.2552 +146 988 5362 29
239.2553 +630 930 5361 97
239.2554 +932 47 5360 83
239.2555 +330 326 5359 12
239.2556 +61 901 5358 60
239.2557 +415 481 5357 79
239.2558 +969 624 5356 82
239.2559 +907 614 5355 58
239.2560 +978 352 5354 99
239.2561 +774 138 5353 14
239.2562 +57 318 5352 24
239.2563 +882 140 5351 51
239.2564 +721 708 5350 69
239.2565 +425 516 5349 60
239.2566 +419 809 5348 26
239.2567 +857 971 5347 64
239.2568 +10 239 5346 44
239.2569 +262 592 5345 6
239.2570 +214 853 5344 92
239.2571 +819 899 5343 20
239.2572 +178 725 5342 71
239.2573 +431 818 5341 17
239.2574 +192 96 5340 16
239.2575 +707 331 5339 29
239.2576 +838 624 5338 0
239.2577 +731 199 5337 56
239.2578 +647 384 5336 84
239.2579 +739 132 5335 74
239.2580 +953 725 5334 4
239.2581 +174 486 5333 39
239.2582 +907 542 5332 64
239.2583 +721 13 5331 74
239.2584 +765 865 5330 23
239.2585 +707 289 5329 48
239.2586 +425 443 5328 86
239.2587 +814 715 5327 10
239.2588 +252 99 5326 8
239.2589 +406 699 5325 90
239.2590 +239 653 5324 78
239.2591 +943 752 5323 77
239.2592 +529 894 5322 26
239.2593 +147 507 5321 18
239.2594 +575 754 5320 95
239.2595 +846 615 5319 5
239.2596 +728 762 5318 28
239.2597 +615 22 5317 61
239.2598 +399 176 5316 56
239.2599 +45 121 5315 84
239.2600 +900 8 5314 16
239.2601 +857 511 5313 29
239.2602 +387 81 5312 41
239.2603 +752 230 5311 38
239.2604 +138 897 5310 57
239.2605 +852 776 5309 72
239.2606 +740 670 5308 11
239.2607 +845 48 5307 11
239.2608 +55 717 5306 21
239.2609 +113 677 5305 35
239.2610 +496 871 5304 14
239.2611 +429 882 5303 4
239.2612 +850 31 5302 47
239.2613 +332 810 5301 63
239.2614 +120 842 5300 61
239.2615 +105 612 5299 28
239.2616 +622 3 5298 11
239.2617 +330 897 5297 89
239.2618 +39 861 5296 78
239.2619 +806 209 5295 94
239.2620 +989 101 5294 61
239.2621 +851 572 5293 6
239.2622 +220 835 5292 57
239.2623 +968 21 5291 51
239.2624 +229 327 5290 21
239.2625 +608 174 5289 1
239.2626 +106 216 5288 48
239.2627 +36 105 5287 29
239.2628 +651 847 5286 29
239.2629 +108 326 5285 23
239.2630 +528 549 5284 81
239.2631 +737 487 5283 13
239.2632 +813 60 5282 63
239.2633 +694 305 5281 25
239.2634 +153 197 5280 73
239.2635 +957 532 5279 62
239.2636 +111 190 5278 50
239.2637 +257 1 5277 7
239.2638 +521 57 5276 38
239.2639 +777 416 5275 54
239.2640 +61 679 5274 57
239.2641 +426 506 5273 79
239.2642 +754 379 5272 92
239.2643 +108 512 5271 11
239.2644 +664 117 5270 54
239.2645 +341 119 5269 19
239.2646 +188 431 5268 84
239.2647 +944 685 5267 85
239.2648 +640 840 5266 73
239.2649 +736 964 5265 74
239.2650 +173 788 5264 71
239.2651 +126 866 5263 63
239.2652 +866 804 5262 67
239.2653 +394 578 5261 64
239.2654 +998 344 5260 44
239.2655 +687 349 5259 32
239.2656 +745 992 5258 15
239.2657 +845 116 5257 24
239.2658 +876 992 5256 30
239.2659 +175 28 5255 90
239.2660 +922 81 5254 56
239.2661 +61 962 5253 4
239.2662 +225 25 5252 26
239.2663 +233 201 5251 47
239.2664 +995 120 5250 39
239.2665 +357 170 5249 31
239.2666 +875 908 5248 94
239.2667 +124 940 5247 90
239.2668 +964 399 5246 96
239.2669 +946 340 5245 70
239.2670 +119 517 5244 25
239.2671 +936 786 5243 86
239.2672 +823 788 5242 83
239.2673 +80 75 5241 99
239.2674 +950 86 5240 23
239.2675 +261 368 5239 63
239.2676 +968 41 5238 48
239.2677 +540 932 5237 75
239.2678 +59 266 5236 15
239.2679 +822 448 5235 1
239.2680 +731 392 5234 82
239.2681 +997 24 5233 18
239.2682 +712 843 5232 11
239.2683 +988 753 5231 74
239.2684 +717 601 5230 13
239.2685 +326 155 5229 68
239.2686 +109 730 5228 29
239.2687 +665 592 5227 42
239.2688 +818 142 5226 48
239.2689 +55 189 5225 23
239.2690 +368 644 5224 9
239.2691 +180 70 5223 73
239.2692 +90 369 5222 28
239.2693 +151 612 5221 72
239.2694 +445 440 5220 27
239.2695 +425 396 5219 39
239.2696 +137 865 5218 21
239.2697 +449 946 5217 44
239.2698 +952 244 5216 84
239.2699 +544 145 5215 76
239.2700 +574 357 5214 68
239.2701 +700 448 5213 18
239.2702 +756 561 5212 8
239.2703 +172 452 5211 93
239.2704 +43 880 5210 70
239.2705 +531 173 5209 1
239.2706 +918 773 5208 28
239.2707 +702 597 5207 68
239.2708 +98 83 5206 49
239.2709 +788 76 5205 40
239.2710 +909 499 5204 97
239.2711 +887 97 5203 87
239.2712 +108 151 5202 94
239.2713 +572 232 5201 58
239.2714 +707 686 5200 12
239.2715 +399 731 5199 51
239.2716 +176 599 5198 61
239.2717 +513 190 5197 21
239.2718 +6 90 5196 60
239.2719 +577 436 5195 31
239.2720 +401 96 5194 87
239.2721 +946 929 5193 2
239.2722 +919 360 5192 77
239.2723 +545 455 5191 53
239.2724 +954 617 5190 86
239.2725 +132 898 5189 30
239.2726 +409 397 5188 22
239.2727 +99 611 5187 66
239.2728 +653 294 5186 50
239.2729 +340 431 5185 42
239.2730 +167 856 5184 17
239.2731 +569 242 5183 45
239.2732 +905 243 5182 2
239.2733 +837 669 5181 37
239.2734 +718 557 5180 59
239.2735 +501 85 5179 82
239.2736 +785 559 5178 72
239.2737 +317 155 5177 30
239.2738 +862 77 5176 44
239.2739 +574 253 5175 31
239.2740 +614 721 5174 17
239.2741 +999 427 5173 59
239.2742 +573 653 5172 66
239.2743 +111 783 5171 6
239.2744 +472 768 5170 11
239.2745 +525 100 5169 21
239.2746 +404 412 5168 71
239.2747 +78 863 5167 46
239.2748 +824 133 5166 45
239.2749 +531 140 5165 28
239.2750 +294 575 5164 96
239.2751 +774 933 5163 61
239.2752 +870 597 5162 42
239.2753 +14 947 5161 46
239.2754 +667 903 5160 63
239.2755 +687 499 5159 94
239.2756 +549 249 5158 12
239.2757 +730 12 5157 32
239.2758 +992 166 5156 25
239.2759 +564 328 5155 29
239.2760 +641 345 5154 23
239.2761 +336 188 5153 52
239.2762 +649 963 5152 90
239.2763 +44 822 5151 85
239.2764 +403 692 5150 34
239.2765 +250 825 5149 98
239.2766 +237 795 5148 13
239.2767 +845 71 5147 81
239.2768 +838 961 5146 73
239.2769 +982 54 5145 42
239.2770 +156 717 5144 92
239.2771 +225 616 5143 30
239.2772 +141 48 5142 68
239.2773 +130 508 5141 60
239.2774 +866 366 5140 64
239.2775 +30 842 5139 15
239.2776 +723 318 5138 1
239.2777 +109 82 5137 39
239.2778 +907 309 5136 0
239.2779 +336 505 5135 85
239.2780 +101 617 5134 82
239.2781 +568 618 5133 93
239.2782 +539 82 5132 8
239.2783 +141 964 5131 1
239.2784 +523 487 5130 26
239.2785 +524 140 5129 83
239.2786 +236 620 5128 30
239.2787 +772 384 5127 61
239.2788 +803 150 5126 20
239.2789 +887 30 5125 57
239.2790 +998 893 5124 23
239.2791 +536 848 5123 53
239.2792 +118 72 5122 2
239.2793 +476 748 5121 39
239.2794 +347 426 5120 61
239.2795 +519 530 5119 99
239.2796 +236 692 5118 28
239.2797 +234 411 5117 46
239.2798 +120 630 5116 96
239.2799 +136 336 5115 91
239.2800 +45 701 5114 88
239.2801 +776 505 5113 46
239.2802 +323 630 5112 41
239.2803 +321 779 5111 64
239.2804 +896 618 5110 12
239.2805 +837 711 5109 82
239.2806 +281 824 5108 28
239.2807 +780 494 5107 0
239.2808 +294 53 5106 11
239.2809 +634 26 5105 98
239.2810 +196 426 5104 9
239.2811 +875 44 5103 26
239.2812 +850 776 5102 45
239.2813 +160 512 5101 0
239.2814 +907 301 5100 42
239.2815 +887 544 5099 5
239.2816 +329 281 5098 55
239.2817 +441 888 5097 50
239.2818 +26 129 5096 48
239.2819 +600 893 5095 65
239.2820 +382 821 5094 43
239.2821 +267 817 5093 32
239.2822 +264 450 5092 2
239.2823 +211 576 5091 68
239.2824 +757 367 5090 25
239.2825 +262 502 5089 1
239.2826 +393 55 5088 55
239.2827 +758 14 5087 88
239.2828 +236 826 5086 41
239.2829 +72 220 5085 42
239.2830 +3 118 5084 21
239.2831 +366 295 5083 11
239.2832 +874 335 5082 0
239.2833 +208 435 5081 5
239.2834 +864 233 5080 45
239.2835 +446 461 5079 49
239.2836 +41 670 5078 86
239.2837 +187 472 5077 63
239.2838 +606 989 5076 52
239.2839 +102 208 5075 16
239.2840 +822 102 5074 6
239.2841 +959 112 5073 63
239.2842 +900 949 5072 49
239.2843 +201 599 5071 66
239.2844 +772 959 5070 34
239.2845 +791 624 5069 41
239.2846 +197 235 5068 40
239.2847 +483 111 5067 85
239.2848 +780 359 5066 58
239.2849 +106 95 5065 50
239.2850 +990 431 5064 27
239.2851 +162 144 5063 86
239.2852 +350 826 5062 5
239.2853 +639 321 5061 69
239.2854 +335 926 5060 42
239.2855 +388 12 5059 98
239.2856 +124 551 5058 59
239.2857 +752 272 5057 71
239.2858 +264 77 5056 70
239.2859 +663 223 5055 67
239.2860 +287 417 5054 11
239.2861 +317 803 5053 82
239.2862 +505 360 5052 81
239.2863 +395 269 5051 71
239.2864 +913 448 5050 30
239.2865 +460 387 5049 94
239.2866 +279 879 5048 26
239.2867 +194 11 5047 37
239.2868 +854 29 5046 48
239.2869 +806 557 5045 60
239.2870 +613 288 5044 37
239.2871 +442 16 5043 96
239.2872 +91 100 5042 81
239.2873 +821 407 5041 11
239.2874 +60 357 5040 48
239.2875 +508 681 5039 45
239.2876 +867 892 5038 18
239.2877 +982 884 5037 8
239.2878 +471 886 5036 34
239.2879 +269 225 5035 4
239.2880 +272 406 5034 19
239.2881 +915 157 5033 17
239.2882 +692 701 5032 35
239.2883 +50 628 5031 26
239.2884 +675 28 5030 76
239.2885 +789 272 5029 55
239.2886 +8 95 5028 64
239.2887 +997 745 5027 88
239.2888 +661 292 5026 51
239.2889 +819 855 5025 20
239.2890 +248 21 5024 99
239.2891 +455 819 5023 35
239.2892 +73 81 5022 22
239.2893 +600 508 5021 64
239.2894 +756 209 5020 37
239.2895 +176 911 5019 88
239.2896 +350 755 5018 78
239.2897 +453 374 5017 1
239.2898 +437 308 5016 33
239.2899 +833 205 5015 84
239.2900 +202 640 5014 57
239.2901 +737 133 5013 79
239.2902 +572 580 5012 38
239.2903 +299 268 5011 47
239.2904 +297 487 5010 84
239.2905 +155 105 5009 57
239.2906 +380 770 5008 82
239.2907 +65 674 5007 89
239.2908 +103 493 5006 1
239.2909 +565 272 5005 60
239.2910 +506 777 5004 63
239.2911 +552 410 5003 46
239.2912 +312 909 5002 16
239.2913 +780 628 5001 27
239.2914 +382 264 5000 0
239.2915 +335 752 4999 14
239.2916 +95 929 4998 77
239.2917 +181 881 4997 31
239.2918 +220 412 4996 96
239.2919 +494 972 4995 53
239.2920 +366 167 4994 5
239.2921 +500 299 4993 95
239.2922 +281 891 4992 23
239.2923 +363 271 4991 53
239.2924 +512 859 4990 39
239.2925 +823 366 4989 4
239.2926 +48 459 4988 23
239.2927 +468 353 4987 91
239.2928 +440 424 4986 96
239.2929 +804 479 4985 72
239.2930 +867 104 4984 12
239.2931 +407 714 4983 86
239.2932 +620 708 4982 21
239.2933 +411 133 4981 91
239.2934 +492 351 4980 85
239.2935 +907 807 4979 68
239.2936 +106 325 4978 77
239.2937 +929 953 4977 57
239.2938 +944 234 4976 2
239.2939 +375 598 4975 63
239.2940 +389 261 4974 93
239.2941 +6 646 4973 46
239.2942 +575 302 4972 78
239.2943 +781 66 4971 20
239.2944 +543 162 4970 91
239.2945 +482 914 4969 58
239.2946 +372 195 4968 80
239.2947 +718 550 4967 17
239.2948 +635 393 4966 98
239.2949 +336 698 4965 56
239.2950 +615 476 4964 98
239.2951 +343 673 4963 38
239.2952 +236 577 4962 43
239.2953 +903 290 4961 79
239.2954 +248 332 4960 23
239.2955 +718 785 4959 6
239.2956 +644 622 4958 11
239.2957 +157 192 4957 65
239.2958 +695 415 4956 8
239.2959 +221 582 4955 29
239.2960 +803 602 4954 72
239.2961 +95 951 4953 27
239.2962 +286 637 4952 10
239.2963 +958 556 4951 33
239.2964 +547 175 4950 65
239.2965 +162 951 4949 52
239.2966 +429 456 4948 7
239.2967 +777 570 4947 48
239.2968 +833 783 4946 46
239.2969 +979 577 4945 47
239.2970 +651 449 4944 41
239.2971 +314 164 4943 70
239.2972 +81 775 4942 80
239.2973 +380 676 4941 32
239.2974 +224 125 4940 41
239.2975 +495 455 4939 38
239.2976 +885 586 4938 73
239.2977 +787 25 4937 65
239.2978 +206 988 4936 94
239.2979 +127 55 4935 85
239.2980 +285 710 4934 32
239.2981 +388 898 4933 33
239.2982 +98 479 4932 23
239.2983 +550 918 4931 70
239.2984 +669 26 4930 15
239.2985 +869 651 4929 72
239.2986 +560 80 4928 60
239.2987 +37 708 4927 9
239.2988 +932 90 4926 58
239.2989 +345 524 4925 7
239.2990 +811 991 4924 84
239.2991 +419 103 4923 89
239.2992 +561 532 4922 29
239.2993 +892 543 4921 54
239.2994 +374 427 4920 88
239.2995 +571 119 4919 80
239.2996 +372 511 4918 30
239.2997 +617 517 4917 52
239.2998 +566 502 4916 10
239.2999 +532 235 4915 58
239.3000 +888 945 4914 53
239.3001 +570 606 4913 39
239.3002 +988 742 4912 85
239.3003 +116 666 4911 66
239.3004 +307 80 4910 51
239.3005 +608 491 4909 80
239.3006 +993 784 4908 19
239.3007 +14 418 4907 75
239.3008 +266 517 4906 5
239.3009 +290 53 4905 3
239.3010 +339 141 4904 64
239.3011 +863 534 4903 31
239.3012 +75 188 4902 58
239.3013 +586 151 4901 87
239.3014 +588 714 4900 80
239.3015 +706 604 4899 69
239.3016 +366 443 4898 61
239.3017 +901 704 4897 97
239.3018 +463 16 4896 74
239.3019 +912 390 4895 97
239.3020 +606 325 4894 95
239.3021 +346 736 4893 47
239.3022 +36 709 4892 78
239.3023 +437 63 4891 48
239.3024 +109 109 4890 99
239.3025 +160 85 4889 88
239.3026 +739 635 4888 34
239.3027 +687 230 4887 46
239.3028 +626 771 4886 43
239.3029 +64 26 4885 55
239.3030 +589 474 4884 30
239.3031 +27 687 4883 26
239.3032 +646 298 4882 31
239.3033 +953 492 4881 59
239.3034 +24 114 4880 32
239.3035 +449 541 4879 94
239.3036 +404 875 4878 42
239.3037 +459 27 4877 5
239.3038 +745 885 4876 6
239.3039 +551 246 4875 56
239.3040 +787 45 4874 47
239.3041 +388 949 4873 56
239.3042 +806 711 4872 38
239.3043 +377 269 4871 69
239.3044 +573 379 4870 92
239.3045 +666 527 4869 57
239.3046 +848 367 4868 4
239.3047 +141 992 4867 94
239.3048 +639 498 4866 71
239.3049 +200 87 4865 19
239.3050 +95 913 4864 76
239.3051 +237 179 4863 39
239.3052 +441 689 4862 58
239.3053 +889 763 4861 42
239.3054 +852 354 4860 80
239.3055 +159 529 4859 90
239.3056 +375 99 4858 81
239.3057 +494 231 4857 70
239.3058 +411 518 4856 50
239.3059 +173 430 4855 43
239.3060 +734 365 4854 10
239.3061 +490 817 4853 85
239.3062 +925 151 4852 79
239.3063 +409 625 4851 55
239.3064 +824 896 4850 3
239.3065 +429 89 4849 69
239.3066 +867 111 4848 78
239.3067 +712 203 4847 88
239.3068 +88 63 4846 8
239.3069 +65 334 4845 23
239.3070 +548 246 4844 43
239.3071 +665 61 4843 24
239.3072 +525 243 4842 56
239.3073 +729 514 4841 51
239.3074 +807 345 4840 58
239.3075 +977 908 4839 39
239.3076 +907 902 4838 56
239.3077 +140 798 4837 15
239.3078 +728 844 4836 62
239.3079 +87 798 4835 2
239.3080 +185 195 4834 51
239.3081 +818 678 4833 88
239.3082 +729 49 4832 13
239.3083 +168 930 4831 79
239.3084 +437 190 4830 92
239.3085 +5 833 4829 82
239.3086 +103 406 4828 6
239.3087 +953 530 4827 76
239.3088 +46 601 4826 41
239.3089 +603 506 4825 64
239.3090 +517 634 4824 90
239.3091 +628 743 4823 36
239.3092 +118 343 4822 8
239.3093 +740 874 4821 56
239.3094 +357 92 4820 73
239.3095 +426 759 4819 43
239.3096 +876 302 4818 90
239.3097 +929 355 4817 15
239.3098 +94 770 4816 90
239.3099 +871 738 4815 44
239.3100 +891 535 4814 8
239.3101 +400 278 4813 88
239.3102 +468 527 4812 51
239.3103 +781 829 4811 37
239.3104 +332 299 4810 38
239.3105 +457 529 4809 93
239.3106 +947 751 4808 55
239.3107 +584 242 4807 94
239.3108 +31 464 4806 83
239.3109 +203 357 4805 22
239.3110 +256 196 4804 98
239.3111 +750 377 4803 49
239.3112 +698 133 4802 93
239.3113 +529 993 4801 68
239.3114 +769 452 4800 44
239.3115 +778 380 4799 87
239.3116 +509 603 4798 50
239.3117 +777 112 4797 36
239.3118 +107 611 4796 55
239.3119 +160 243 4795 82
239.3120 +818 488 4794 94
239.3121 +244 560 4793 50
239.3122 +139 244 4792 5
239.3123 +541 237 4791 16
239.3124 +71 573 4790 75
239.3125 +777 366 4789 99
239.3126 +490 145 4788 26
239.3127 +501 810 4787 73
239.3128 +367 724 4786 67
239.3129 +754 881 4785 94
239.3130 +928 440 4784 34
239.3131 +315 454 4783 57
239.3132 +7 882 4782 10
239.3133 +663 410 4781 59
239.3134 +207 767 4780 46
239.3135 +220 722 4779 29
239.3136 +334 538 4778 28
239.3137 +86 60 4777 98
239.3138 +842 724 4776 13
239.3139 +441 604 4775 61
239.3140 +985 767 4774 82
239.3141 +572 468 4773 61
239.3142 +471 507 4772 30
239.3143 +642 128 4771 34
239.3144 +45 175 4770 45
239.3145 +184 7 4769 98
239.3146 +477 296 4768 88
239.3147 +335 856 4767 24
239.3148 +119 519 4766 24
239.3149 +836 787 4765 40
239.3150 +298 212 4764 45
239.3151 +961 305 4763 41
239.3152 +378 964 4762 10
239.3153 +952 888 4761 82
239.3154 +167 468 4760 59
239.3155 +710 101 4759 86
239.3156 +440 637 4758 70
239.3157 +336 4 4757 14
239.3158 +731 841 4756 21
239.3159 +575 946 4755 28
239.3160 +906 41 4754 53
239.3161 +341 313 4753 33
239.3162 +75 270 4752 58
239.3163 +419 232 4751 42
239.3164 +367 735 4750 78
239.3165 +464 155 4749 45
239.3166 +632 564 4748 27
239.3167 +162 925 4747 10
239.3168 +895 933 4746 60
239.3169 +905 745 4745 15
239.3170 +728 200 4744 66
239.3171 +42 754 4743 56
239.3172 +38 157 4742 26
239.3173 +497 640 4741 65
239.3174 +580 327 4740 5
239.3175 +591 187 4739 90
239.3176 +638 166 4738 83
239.3177 +992 498 4737 46
239.3178 +187 448 4736 26
239.3179 +545 487 4735 99
239.3180 +445 103 4734 17
239.3181 +597 300 4733 68
239.3182 +516 608 4732 0
239.3183 +313 605 4731 54
239.3184 +140 148 4730 91
239.3185 +20 71 4729 98
239.3186 +667 362 4728 95
239.3187 +50 201 4727 64
239.3188 +960 277 4726 80
239.3189 +384 813 4725 64
239.3190 +802 491 4724 9
239.3191 +691 681 4723 84
239.3192 +3 462 4722 8
239.3193 +456 624 4721 20
239.3194 +76 927 4720 17
239.3195 +709 36 4719 12
239.3196 +160 306 4718 35
239.3197 +924 840 4717 61
239.3198 +464 162 4716 8
239.3199 +321 543 4715 57
239.3200 +809 250 4714 58
239.3201 +219 767 4713 11
239.3202 +838 878 4712 68
239.3203 +697 30 4711 54
239.3204 +890 52 4710 38
239.3205 +729 767 4709 36
239.3206 +466 735 4708 54
239.3207 +677 527 4707 23
239.3208 +619 513 4706 45
239.3209 +292 994 4705 14
239.3210 +483 471 4704 51
239.3211 +888 422 4703 58
239.3212 +848 141 4702 38
239.3213 +977 166 4701 14
239.3214 +285 13 4700 80
239.3215 +31 817 4699 16
239.3216 +208 312 4698 26
239.3217 +13 776 4697 78
239.3218 +519 316 4696 5
239.3219 +523 629 4695 32
239.3220 +48 922 4694 80
239.3221 +280 208 4693 59
239.3222 +975 240 4692 4
239.3223 +152 334 4691 87
239.3224 +196 645 4690 69
239.3225 +504 897 4689 25
239.3226 +535 474 4688 82
239.3227 +460 731 4687 19
239.3228 +686 729 4686 49
239.3229 +706 519 4685 99
239.3230 +714 213 4684 47
239.3231 +968 554 4683 76
239.3232 +905 169 4682 30
239.3233 +689 179 4681 82
239.3234 +747 438 4680 95
239.3235 +423 429 4679 69
239.3236 +743 629 4678 96
239.3237 +1 701 4677 7
239.3238 +210 496 4676 77
239.3239 +305 522 4675 97
239.3240 +659 706 4674 99
239.3241 +384 462 4673 74
239.3242 +990 481 4672 6
239.3243 +740 868 4671 21
239.3244 +8 263 4670 94
239.3245 +800 723 4669 32
239.3246 +927 892 4668 67
239.3247 +204 302 4667 74
239.3248 +974 793 4666 79
239.3249 +815 987 4665 90
239.3250 +244 246 4664 64
239.3251 +981 682 4663 27
239.3252 +613 846 4662 39
239.3253 +604 274 4661 24
239.3254 +540 617 4660 73
239.3255 +830 644 4659 20
239.3256 +590 937 4658 87
239.3257 +509 951 4657 72
239.3258 +805 885 4656 22
239.3259 +740 259 4655 15
239.3260 +563 371 4654 57
239.3261 +836 880 4653 26
239.3262 +572 144 4652 36
239.3263 +656 517 4651 0
239.3264 +973 523 4650 6
239.3265 +706 335 4649 71
239.3266 +986 148 4648 24
239.3267 +66 494 4647 8
239.3268 +626 70 4646 70
239.3269 +887 588 4645 6
239.3270 +491 307 4644 17
239.3271 +735 895 4643 72
239.3272 +627 358 4642 26
239.3273 +993 945 4641 91
239.3274 +188 353 4640 68
239.3275 +186 469 4639 26
239.3276 +654 159 4638 72
239.3277 +424 377 4637 91
239.3278 +481 637 4636 44
239.3279 +280 889 4635 73
239.3280 +412 448 4634 39
239.3281 +536 464 4633 75
239.3282 +413 347 4632 10
239.3283 +591 232 4631 63
239.3284 +883 417 4630 80
239.3285 +310 545 4629 0
239.3286 +782 800 4628 53
239.3287 +739 479 4627 23
239.3288 +748 701 4626 94
239.3289 +440 341 4625 20
239.3290 +984 640 4624 86
239.3291 +117 648 4623 87
239.3292 +114 473 4622 12
239.3293 +815 828 4621 82
239.3294 +871 803 4620 70
239.3295 +744 470 4619 57
239.3296 +320 300 4618 52
239.3297 +778 288 4617 4
239.3298 +359 742 4616 99
239.3299 +701 332 4615 30
239.3300 +992 992 4614 45
239.3301 +174 752 4613 86
239.3302 +645 301 4612 0
239.3303 +24 114 4611 29
239.3304 +333 134 4610 94
239.3305 +169 45 4609 12
239.3306 +12 485 4608 42
239.3307 +545 51 4607 54
239.3308 +410 683 4606 41
239.3309 +339 851 4605 65
239.3310 +239 590 4604 70
239.3311 +451 863 4603 81
239.3312 +187 704 4602 52
239.3313 +979 355 4601 62
239.3314 +89 816 4600 69
239.3315 +559 702 4599 16
239.3316 +434 881 4598 15
239.3317 +368 123 4597 46
239.3318 +832 760 4596 13
239.3319 +261 948 4595 7
239.3320 +726 891 4594 10
239.3321 +159 288 4593 78
239.3322 +349 907 4592 26
239.3323 +538 930 4591 20
239.3324 +114 526 4590 89
239.3325 +821 7 4589 52
239.3326 +757 689 4588 12
239.3327 +363 331 4587 6
239.3328 +812 64 4586 53
239.3329 +56 970 4585 57
239.3330 +603 312 4584 53
239.3331 +380 523 4583 56
239.3332 +977 56 4582 81
239.3333 +403 317 4581 81
239.3334 +518 360 4580 42
239.3335 +318 404 4579 29
239.3336 +358 59 4578 6
239.3337 +266 529 4577 39
239.3338 +94 964 4576 55
239.3339 +658 36 4575 75
239.3340 +788 967 4574 45
239.3341 +467 757 4573 22
239.3342 +739 999 4572 40
239.3343 +956 386 4571 57
239.3344 +956 131 4570 88
239.3345 +344 229 4569 20
239.3346 +529 669 4568 95
239.3347 +564 843 4567 9
239.3348 +928 795 4566 17
239.3349 +69 301 4565 43
239.3350 +210 231 4564 86
239.3351 +757 819 4563 32
239.3352 +612 829 4562 72
239.3353 +255 688 4561 78
239.3354 +902 685 4560 0
239.3355 +559 240 4559 61
239.3356 +826 867 4558 81
239.3357 +47 920 4557 96
239.3358 +494 735 4556 63
239.3359 +70 566 4555 85
239.3360 +412 548 4554 85
239.3361 +989 593 4553 45
239.3362 +140 945 4552 14
239.3363 +3 781 4551 35
239.3364 +444 389 4550 35
239.3365 +372 796 4549 34
239.3366 +947 850 4548 73
239.3367 +184 328 4547 77
239.3368 +168 778 4546 55
239.3369 +18 999 4545 42
239.3370 +955 407 4544 65
239.3371 +647 307 4543 42
239.3372 +163 787 4542 84
239.3373 +392 5 4541 13
239.3374 +593 9 4540 55
239.3375 +946 609 4539 7
239.3376 +521 954 4538 42
239.3377 +550 226 4537 76
239.3378 +778 128 4536 1
239.3379 +592 766 4535 14
239.3380 +99 235 4534 6
239.3381 +520 573 4533 30
239.3382 +781 711 4532 48
239.3383 +995 579 4531 77
239.3384 +400 485 4530 79
239.3385 +655 647 4529 64
239.3386 +728 661 4528 42
239.3387 +97 746 4527 97
239.3388 +362 866 4526 77
239.3389 +530 86 4525 18
239.3390 +662 756 4524 49
239.3391 +861 823 4523 57
239.3392 +132 713 4522 73
239.3393 +93 971 4521 78
239.3394 +838 152 4520 59
239.3395 +986 222 4519 74
239.3396 +914 452 4518 92
239.3397 +880 200 4517 63
239.3398 +780 584 4516 73
239.3399 +329 694 4515 83
239.3400 +933 913 4514 86
239.3401 +110 840 4513 80
239.3402 +741 952 4512 72
239.3403 +819 190 4511 3
239.3404 +929 850 4510 25
239.3405 +770 817 4509 85
239.3406 +251 296 4508 7
239.3407 +616 896 4507 3
239.3408 +889 902 4506 9
239.3409 +780 963 4505 45
239.3410 +73 67 4504 39
239.3411 +888 71 4503 82
239.3412 +761 690 4502 36
239.3413 +340 782 4501 92
239.3414 +32 403 4500 88
239.3415 +521 780 4499 15
239.3416 +399 37 4498 51
239.3417 +994 934 4497 63
239.3418 +938 648 4496 72
239.3419 +896 54 4495 10
239.3420 +995 573 4494 70
239.3421 +380 454 4493 18
239.3422 +908 446 4492 12
239.3423 +378 32 4491 42
239.3424 +623 730 4490 30
239.3425 +743 640 4489 51
239.3426 +102 883 4488 12
239.3427 +285 908 4487 40
239.3428 +594 617 4486 5
239.3429 +480 401 4485 4
239.3430 +119 522 4484 90
239.3431 +8 58 4483 61
239.3432 +413 705 4482 47
239.3433 +301 113 4481 52
239.3434 +90 796 4480 75
239.3435 +756 388 4479 87
239.3436 +974 717 4478 64
239.3437 +291 349 4477 81
239.3438 +215 12 4476 69
239.3439 +878 142 4475 11
239.3440 +464 285 4474 36
239.3441 +353 141 4473 11
239.3442 +591 943 4472 59
239.3443 +317 773 4471 11
239.3444 +407 875 4470 21
239.3445 +671 238 4469 33
239.3446 +368 824 4468 78
239.3447 +336 125 4467 68
239.3448 +870 576 4466 7
239.3449 +856 753 4465 33
239.3450 +143 249 4464 41
239.3451 +198 516 4463 11
239.3452 +169 482 4462 76
239.3453 +898 901 4461 27
239.3454 +636 877 4460 90
239.3455 +414 551 4459 73
239.3456 +698 99 4458 30
239.3457 +549 606 4457 3
239.3458 +822 738 4456 46
239.3459 +503 922 4455 1
239.3460 +733 303 4454 71
239.3461 +33 349 4453 94
239.3462 +581 486 4452 2
239.3463 +24 365 4451 27
239.3464 +326 172 4450 26
239.3465 +451 433 4449 22
239.3466 +492 271 4448 71
239.3467 +868 565 4447 14
239.3468 +816 452 4446 72
239.3469 +619 300 4445 31
239.3470 +953 768 4444 77
239.3471 +863 916 4443 69
239.3472 +121 757 4442 45
239.3473 +192 10 4441 55
239.3474 +739 39 4440 69
239.3475 +161 506 4439 87
239.3476 +706 566 4438 95
239.3477 +112 422 4437 62
239.3478 +152 407 4436 5
239.3479 +532 548 4435 19
239.3480 +851 70 4434 66
239.3481 +159 246 4433 9
239.3482 +746 896 4432 74
239.3483 +970 858 4431 92
239.3484 +533 823 4430 45
239.3485 +939 915 4429 57
239.3486 +144 334 4428 45
239.3487 +14 573 4427 59
239.3488 +858 854 4426 96
239.3489 +478 531 4425 62
239.3490 +823 575 4424 68
239.3491 +350 348 4423 69
239.3492 +37 813 4422 41
239.3493 +35 475 4421 77
239.3494 +907 875 4420 43
239.3495 +581 122 4419 59
239.3496 +760 862 4418 79
239.3497 +718 632 4417 12
239.3498 +323 340 4416 15
239.3499 +955 939 4415 38
239.3500 +227 989 4414 65
239.3501 +534 279 4413 47
239.3502 +337 636 4412 31
239.3503 +600 338 4411 0
239.3504 +752 844 4410 12
239.3505 +260 798 4409 32
239.3506 +229 666 4408 82
239.3507 +292 973 4407 4
239.3508 +401 776 4406 39
239.3509 +950 725 4405 36
239.3510 +710 181 4404 72
239.3511 +642 159 4403 69
239.3512 +298 311 4402 19
239.3513 +494 875 4401 73
239.3514 +46 801 4400 84
239.3515 +131 505 4399 49
239.3516 +693 778 4398 3
239.3517 +196 647 4397 93
239.3518 +50 26 4396 89
239.3519 +543 640 4395 45
239.3520 +22 35 4394 24
239.3521 +848 495 4393 6
239.3522 +436 459 4392 34
239.3523 +73 889 4391 80
239.3524 +295 356 4390 44
239.3525 +727 460 4389 91
239.3526 +130 94 4388 43
239.3527 +621 45 4387 49
239.3528 +385 440 4386 14
239.3529 +605 210 4385 50
239.3530 +540 172 4384 52
239.3531 +35 722 4383 17
239.3532 +569 540 4382 41
239.3533 +533 355 4381 36
239.3534 +895 533 4380 77
239.3535 +366 475 4379 56
239.3536 +48 942 4378 59
239.3537 +605 350 4377 50
239.3538 +229 638 4376 23
239.3539 +38 985 4375 78
239.3540 +449 347 4374 6
239.3541 +182 761 4373 50
239.3542 +184 50 4372 46
239.3543 +822 583 4371 3
239.3544 +57 209 4370 63
239.3545 +533 971 4369 52
239.3546 +592 87 4368 31
239.3547 +711 273 4367 44
239.3548 +653 455 4366 37
239.3549 +637 715 4365 19
239.3550 +586 560 4364 58
239.3551 +710 38 4363 26
239.3552 +466 429 4362 99
239.3553 +374 397 4361 36
239.3554 +237 109 4360 76
239.3555 +884 210 4359 52
239.3556 +814 875 4358 94
239.3557 +818 66 4357 88
239.3558 +739 184 4356 5
239.3559 +154 603 4355 1
239.3560 +522 320 4354 5
239.3561 +608 269 4353 87
239.3562 +31 635 4352 24
239.3563 +288 597 4351 9
239.3564 +898 240 4350 13
239.3565 +334 583 4349 35
239.3566 +809 59 4348 6
239.3567 +882 822 4347 99
239.3568 +581 43 4346 7
239.3569 +282 963 4345 58
239.3570 +51 175 4344 63
239.3571 +634 631 4343 91
239.3572 +37 152 4342 57
239.3573 +357 954 4341 74
239.3574 +656 783 4340 38
239.3575 +524 284 4339 56
239.3576 +236 72 4338 52
239.3577 +779 918 4337 92
239.3578 +79 494 4336 30
239.3579 +788 952 4335 29
239.3580 +543 718 4334 23
239.3581 +479 337 4333 41
239.3582 +197 833 4332 59
239.3583 +171 353 4331 68
239.3584 +499 825 4330 70
239.3585 +211 38 4329 13
239.3586 +154 598 4328 28
239.3587 +423 626 4327 45
239.3588 +542 2 4326 70
239.3589 +233 67 4325 29
239.3590 +380 814 4324 24
239.3591 +504 819 4323 6
239.3592 +479 916 4322 28
239.3593 +528 978 4321 2
239.3594 +786 569 4320 67
239.3595 +440 845 4319 28
239.3596 +971 829 4318 5
239.3597 +623 757 4317 73
239.3598 +934 409 4316 88
239.3599 +252 46 4315 30
239.3600 +995 180 4314 85
239.3601 +902 782 4313 87
239.3602 +937 255 4312 2
239.3603 +409 355 4311 95
239.3604 +724 383 4310 74
239.3605 +15 229 4309 34
239.3606 +72 327 4308 46
239.3607 +348 848 4307 34
239.3608 +362 573 4306 68
239.3609 +865 455 4305 68
239.3610 +397 977 4304 25
239.3611 +527 850 4303 9
239.3612 +900 73 4302 96
239.3613 +971 209 4301 52
239.3614 +153 396 4300 68
239.3615 +902 876 4299 70
239.3616 +478 120 4298 94
239.3617 +275 659 4297 72
239.3618 +118 6 4296 98
239.3619 +478 424 4295 49
239.3620 +126 164 4294 46
239.3621 +777 127 4293 87
239.3622 +864 437 4292 62
239.3623 +813 842 4291 92
239.3624 +519 976 4290 81
239.3625 +755 765 4289 25
239.3626 +461 218 4288 42
239.3627 +652 738 4287 20
239.3628 +582 488 4286 15
239.3629 +259 28 4285 64
239.3630 +37 597 4284 35
239.3631 +690 243 4283 34
239.3632 +594 697 4282 91
239.3633 +865 111 4281 5
239.3634 +210 566 4280 29
239.3635 +547 826 4279 76
239.3636 +480 221 4278 29
239.3637 +250 45 4277 80
239.3638 +459 517 4276 7
239.3639 +431 288 4275 32
239.3640 +353 2 4274 22
239.3641 +546 436 4273 34
239.3642 +585 861 4272 9
239.3643 +545 757 4271 72
239.3644 +739 530 4270 65
239.3645 +605 469 4269 66
239.3646 +176 484 4268 6
239.3647 +527 739 4267 23
239.3648 +229 747 4266 79
239.3649 +285 100 4265 2
239.3650 +565 874 4264 7
239.3651 +575 252 4263 80
239.3652 +104 365 4262 96
239.3653 +226 75 4261 3
239.3654 +60 990 4260 80
239.3655 +985 596 4259 13
239.3656 +744 837 4258 42
239.3657 +991 439 4257 64
239.3658 +647 762 4256 29
239.3659 +225 949 4255 94
239.3660 +622 271 4254 71
239.3661 +886 846 4253 99
239.3662 +290 920 4252 47
239.3663 +84 233 4251 87
239.3664 +393 672 4250 16
239.3665 +759 704 4249 7
239.3666 +397 781 4248 24
239.3667 +677 349 4247 75
239.3668 +812 354 4246 34
239.3669 +678 224 4245 42
239.3670 +424 728 4244 60
239.3671 +925 520 4243 73
239.3672 +687 592 4242 59
239.3673 +560 712 4241 20
239.3674 +967 90 4240 69
239.3675 +923 834 4239 63
239.3676 +431 487 4238 36
239.3677 +994 409 4237 71
239.3678 +130 921 4236 86
239.3679 +495 819 4235 13
239.3680 +208 868 4234 25
239.3681 +927 138 4233 49
239.3682 +880 391 4232 23
239.3683 +621 514 4231 12
239.3684 +255 56 4230 59
239.3685 +347 272 4229 4
239.3686 +77 642 4228 49
239.3687 +488 854 4227 43
239.3688 +101 731 4226 86
239.3689 +951 879 4225 63
239.3690 +729 754 4224 28
239.3691 +747 260 4223 28
239.3692 +876 112 4222 4
239.3693 +458 533 4221 25
239.3694 +783 548 4220 36
239.3695 +630 552 4219 90
239.3696 +788 55 4218 26
239.3697 +122 572 4217 58
239.3698 +852 228 4216 38
239.3699 +124 348 4215 15
239.3700 +494 4 4214 22
239.3701 +148 235 4213 98
239.3702 +578 786 4212 87
239.3703 +984 892 4211 41
239.3704 +996 458 4210 67
239.3705 +497 638 4209 15
239.3706 +482 680 4208 84
239.3707 +344 202 4207 66
239.3708 +879 236 4206 27
239.3709 +344 928 4205 72
239.3710 +769 239 4204 63
239.3711 +448 111 4203 34
239.3712 +894 452 4202 56
239.3713 +434 743 4201 59
239.3714 +820 520 4200 98
239.3715 +957 311 4199 49
239.3716 +478 176 4198 1
239.3717 +966 395 4197 13
239.3718 +307 543 4196 46
239.3719 +689 97 4195 53
239.3720 +127 283 4194 57
239.3721 +659 777 4193 32
239.3722 +708 975 4192 55
239.3723 +222 604 4191 45
239.3724 +208 489 4190 61
239.3725 +135 484 4189 86
239.3726 +780 877 4188 47
239.3727 +852 672 4187 51
239.3728 +446 929 4186 65
239.3729 +813 960 4185 61
239.3730 +506 253 4184 56
239.3731 +801 766 4183 46
239.3732 +370 94 4182 95
239.3733 +115 845 4181 48
239.3734 +5 750 4180 1
239.3735 +607 383 4179 7
239.3736 +204 967 4178 35
239.3737 +742 852 4177 92
239.3738 +969 41 4176 40
239.3739 +706 54 4175 63
239.3740 +487 95 4174 30
239.3741 +671 516 4173 70
239.3742 +248 465 4172 43
239.3743 +95 471 4171 25
239.3744 +366 940 4170 11
239.3745 +416 717 4169 39
239.3746 +114 426 4168 40
239.3747 +810 522 4167 46
239.3748 +986 773 4166 77
239.3749 +959 325 4165 26
239.3750 +578 602 4164 21
239.3751 +50 273 4163 81
239.3752 +993 175 4162 42
239.3753 +531 144 4161 15
239.3754 +222 712 4160 72
239.3755 +291 994 4159 95
239.3756 +904 941 4158 30
239.3757 +749 687 4157 30
239.3758 +447 511 4156 82
239.3759 +722 42 4155 2
239.3760 +328 403 4154 38
239.3761 +98 392 4153 52
239.3762 +30 269 4152 5
239.3763 +432 425 4151 46
239.3764 +717 777 4150 30
239.3765 +53 648 4149 93
239.3766 +253 998 4148 38
239.3767 +176 479 4147 15
239.3768 +468 796 4146 30
239.3769 +639 646 4145 72
239.3770 +11 852 4144 39
239.3771 +122 472 4143 23
239.3772 +844 593 4142 6
239.3773 +647 154 4141 59
239.3774 +129 376 4140 71
239.3775 +650 544 4139 66
239.3776 +518 232 4138 79
239.3777 +683 853 4137 7
239.3778 +150 576 4136 70
239.3779 +794 330 4135 82
239.3780 +380 163 4134 62
239.3781 +878 162 4133 88
239.3782 +439 469 4132 27
239.3783 +777 883 4131 19
239.3784 +832 49 4130 51
239.3785 +311 864 4129 47
239.3786 +378 722 4128 13
239.3787 +277 369 4127 83
239.3788 +245 878 4126 53
239.3789 +167 201 4125 35
239.3790 +0 739 4124 41
239.3791 +693 610 4123 50
239.3792 +585 81 4122 43
239.3793 +833 678 4121 66
239.3794 +185 38 4120 94
239.3795 +141 347 4119 52
239.3796 +353 296 4118 93
239.3797 +490 302 4117 10
239.3798 +677 176 4116 3
239.3799 +461 942 4115 7
239.3800 +129 912 4114 16
239.3801 +528 62 4113 30
239.3802 +403 777 4112 10
239.3803 +639 715 4111 75
239.3804 +691 424 4110 64
239.3805 +50 587 4109 4
239.3806 +994 831 4108 78
239.3807 +125 69 4107 86
239.3808 +234 953 4106 81
239.3809 +30 911 4105 21
239.3810 +849 858 4104 33
239.3811 +284 200 4103 60
239.3812 +62 355 4102 12
239.3813 +291 103 4101 76
239.3814 +837 604 4100 94
239.3815 +756 255 4099 64
239.3816 +761 925 4098 5
239.3817 +115 48 4097 86
239.3818 +42 598 4096 89
239.3819 +52 882 4095 20
239.3820 +658 731 4094 18
239.3821 +844 475 4093 56
239.3822 +251 361 4092 22
239.3823 +499 815 4091 77
239.3824 +349 307 4090 45
239.3825 +329 584 4089 8
239.3826 +877 187 4088 99
239.3827 +450 977 4087 64
239.3828 +715 687 4086 7
239.3829 +151 23 4085 98
239.3830 +255 615 4084 39
239.3831 +114 343 4083 81
239.3832 +545 451 4082 59
239.3833 +507 316 4081 75
239.3834 +723 373 4080 14
239.3835 +396 86 4079 2
239.3836 +209 348 4078 45
239.3837 +289 571 4077 42
239.3838 +664 84 4076 73
239.3839 +408 594 4075 56
239.3840 +271 580 4074 89
239.3841 +891 220 4073 14
239.3842 +134 841 4072 56
239.3843 +943 602 4071 3
239.3844 +286 129 4070 78
239.3845 +737 568 4069 32
239.3846 +777 24 4068 18
239.3847 +487 692 4067 92
239.3848 +489 169 4066 62
239.3849 +13 668 4065 25
239.3850 +360 755 4064 13
239.3851 +379 571 4063 38
239.3852 +238 530 4062 75
239.3853 +473 254 4061 19
239.3854 +561 456 4060 65
239.3855 +543 139 4059 54
239.3856 +331 267 4058 96
239.3857 +522 294 4057 28
239.3858 +501 369 4056 99
239.3859 +912 119 4055 47
239.3860 +183 756 4054 65
239.3861 +41 623 4053 98
239.3862 +275 566 4052 14
239.3863 +797 534 4051 76
239.3864 +317 107 4050 91
239.3865 +872 589 4049 1
239.3866 +972 670 4048 21
239.3867 +925 292 4047 80
239.3868 +249 521 4046 2
239.3869 +363 822 4045 58
239.3870 +132 671 4044 72
239.3871 +57 841 4043 14
239.3872 +32 375 4042 76
239.3873 +426 852 4041 47
239.3874 +517 894 4040 48
239.3875 +919 805 4039 44
239.3876 +377 403 4038 90
239.3877 +771 787 4037 4
239.3878 +698 432 4036 67
239.3879 +150 859 4035 88
239.3880 +830 587 4034 23
239.3881 +465 375 4033 7
239.3882 +522 288 4032 2
239.3883 +958 997 4031 60
239.3884 +89 35 4030 90
239.3885 +402 544 4029 59
239.3886 +615 853 4028 54
239.3887 +354 370 4027 60
239.3888 +573 790 4026 7
239.3889 +271 655 4025 54
239.3890 +211 154 4024 31
239.3891 +87 50 4023 36
239.3892 +290 419 4022 94
239.3893 +961 696 4021 56
239.3894 +491 310 4020 86
239.3895 +690 56 4019 68
239.3896 +482 935 4018 78
239.3897 +580 533 4017 26
239.3898 +134 524 4016 78
239.3899 +500 228 4015 30
239.3900 +104 954 4014 5
239.3901 +630 421 4013 12
239.3902 +723 378 4012 79
239.3903 +385 695 4011 32
239.3904 +253 182 4010 46
239.3905 +121 899 4009 80
239.3906 +401 526 4008 20
239.3907 +9 478 4007 90
239.3908 +295 479 4006 44
239.3909 +273 242 4005 63
239.3910 +533 935 4004 39
239.3911 +42 327 4003 47
239.3912 +683 467 4002 90
239.3913 +513 859 4001 33
239.3914 +282 669 4000 13
239.3915 +372 592 3999 13
239.3916 +47 305 3998 72
239.3917 +999 457 3997 39
239.3918 +237 811 3996 71
239.3919 +307 238 3995 2
239.3920 +608 922 3994 74
239.3921 +859 566 3993 49
239.3922 +608 568 3992 35
239.3923 +189 206 3991 17
239.3924 +77 999 3990 23
239.3925 +287 411 3989 91
239.3926 +848 328 3988 32
239.3927 +645 678 3987 4
239.3928 +572 691 3986 76
239.3929 +315 282 3985 93
239.3930 +356 250 3984 69
239.3931 +998 131 3983 74
239.3932 +361 188 3982 25
239.3933 +206 940 3981 41
239.3934 +588 320 3980 11
239.3935 +82 584 3979 78
239.3936 +650 277 3978 43
239.3937 +986 286 3977 20
239.3938 +409 831 3976 7
239.3939 +31 230 3975 25
239.3940 +118 950 3974 95
239.3941 +942 496 3973 35
239.3942 +248 833 3972 63
239.3943 +620 305 3971 15
239.3944 +735 322 3970 61
239.3945 +307 351 3969 50
239.3946 +990 236 3968 43
239.3947 +454 129 3967 66
239.3948 +600 815 3966 57
239.3949 +280 297 3965 37
239.3950 +454 601 3964 91
239.3951 +663 721 3963 17
239.3952 +528 480 3962 69
239.3953 +982 537 3961 62
239.3954 +971 111 3960 88
239.3955 +115 74 3959 42
239.3956 +106 767 3958 31
239.3957 +314 86 3957 53
239.3958 +517 200 3956 85
239.3959 +696 464 3955 32
239.3960 +879 736 3954 82
239.3961 +240 483 3953 79
239.3962 +943 65 3952 13
239.3963 +425 743 3951 54
239.3964 +36 456 3950 1
239.3965 +307 110 3949 85
239.3966 +681 781 3948 0
239.3967 +886 681 3947 79
239.3968 +736 533 3946 79
239.3969 +728 495 3945 82
239.3970 +253 34 3944 81
239.3971 +418 656 3943 63
239.3972 +321 588 3942 29
239.3973 +286 535 3941 51
239.3974 +345 154 3940 38
239.3975 +329 847 3939 72
239.3976 +99 216 3938 62
239.3977 +148 996 3937 79
239.3978 +38 975 3936 14
239.3979 +460 4 3935 0
239.3980 +377 178 3934 47
239.3981 +68 341 3933 83
239.3982 +52 779 3932 9
239.3983 +381 129 3931 3
239.3984 +306 658 3930 94
239.3985 +631 104 3929 1
239.3986 +220 830 3928 23
239.3987 +20 645 3927 95
239.3988 +970 141 3926 11
239.3989 +826 533 3925 57
239.3990 +837 640 3924 8
239.3991 +561 738 3923 30
239.3992 +650 62 3922 1
239.3993 +470 93 3921 67
239.3994 +554 924 3920 7
239.3995 +273 785 3919 67
239.3996 +185 280 3918 41
239.3997 +503 839 3917 19
239.3998 +608 533 3916 5
239.3999 +893 494 3915 14
239.4000 +901 773 3914 98
239.4001 +676 292 3913 27
239.4002 +968 346 3912 91
239.4003 +168 594 3911 18
239.4004 +139 400 3910 91
239.4005 +505 263 3909 28
239.4006 +441 211 3908 8
239.4007 +305 148 3907 68
239.4008 +39 905 3906 89
239.4009 +720 155 3905 71
239.4010 +481 713 3904 99
239.4011 +946 364 3903 22
239.4012 +751 730 3902 70
239.4013 +194 264 3901 80
239.4014 +136 634 3900 2
239.4015 +52 193 3899 63
239.4016 +62 405 3898 6
239.4017 +243 787 3897 13
239.4018 +750 179 3896 26
239.4019 +441 724 3895 31
239.4020 +349 766 3894 23
239.4021 +633 518 3893 53
239.4022 +466 906 3892 19
239.4023 +630 771 3891 55
239.4024 +440 395 3890 5
239.4025 +788 569 3889 8
239.4026 +618 929 3888 98
239.4027 +608 868 3887 81
239.4028 +454 947 3886 49
239.4029 +958 79 3885 30
239.4030 +247 703 3884 9
239.4031 +611 340 3883 71
239.4032 +135 637 3882 16
239.4033 +376 499 3881 83
239.4034 +825 973 3880 19
239.4035 +640 95 3879 65
239.4036 +60 169 3878 16
239.4037 +920 326 3877 0
239.4038 +867 184 3876 15
239.4039 +376 216 3875 49
239.4040 +362 376 3874 71
239.4041 +703 548 3873 63
239.4042 +137 331 3872 47
239.4043 +526 645 3871 75
239.4044 +877 538 3870 55
239.4045 +925 482 3869 18
239.4046 +842 159 3868 58
239.4047 +142 856 3867 13
239.4048 +968 657 3866 5
239.4049 +840 786 3865 49
239.4050 +827 74 3864 1
239.4051 +217 160 3863 65
239.4052 +686 717 3862 56
239.4053 +107 207 3861 61
239.4054 +55 366 3860 64
239.4055 +322 604 3859 95
239.4056 +303 440 3858 8
239.4057 +199 86 3857 70
239.4058 +870 561 3856 17
239.4059 +712 477 3855 12
239.4060 +913 354 3854 1
239.4061 +443 92 3853 61
239.4062 +509 955 3852 53
239.4063 +841 962 3851 57
239.4064 +762 696 3850 5
239.4065 +163 869 3849 73
239.4066 +353 381 3848 1
239.4067 +525 527 3847 10
239.4068 +83 45 3846 32
239.4069 +122 115 3845 15
239.4070 +262 402 3844 79
239.4071 +137 79 3843 47
239.4072 +992 951 3842 93
239.4073 +265 527 3841 66
239.4074 +827 318 3840 7
239.4075 +487 713 3839 59
239.4076 +854 914 3838 80
239.4077 +481 775 3837 82
239.4078 +930 169 3836 44
239.4079 +713 360 3835 96
239.4080 +322 327 3834 86
239.4081 +127 536 3833 12
239.4082 +424 266 3832 14
239.4083 +208 588 3831 72
239.4084 +605 479 3830 43
239.4085 +798 789 3829 33
239.4086 +138 981 3828 63
239.4087 +606 385 3827 37
239.4088 +809 481 3826 55
239.4089 +32 100 3825 21
239.4090 +791 735 3824 39
239.4091 +269 980 3823 19
239.4092 +677 417 3822 70
239.4093 +108 288 3821 21
239.4094 +690 98 3820 60
239.4095 +807 707 3819 80
239.4096 +595 259 3818 65
239.4097 +903 822 3817 53
239.4098 +381 334 3816 79
239.4099 +364 826 3815 77
239.4100 +755 195 3814 24
239.4101 +562 492 3813 52
239.4102 +128 486 3812 59
239.4103 +190 613 3811 56
239.4104 +391 796 3810 41
239.4105 +448 146 3809 88
239.4106 +437 127 3808 21
239.4107 +487 735 3807 69
239.4108 +508 20 3806 52
239.4109 +631 535 3805 1
239.4110 +703 719 3804 60
239.4111 +5 930 3803 19
239.4112 +873 22 3802 43
239.4113 +816 150 3801 93
239.4114 +650 535 3800 79
239.4115 +19 670 3799 94
239.4116 +391 519 3798 1
239.4117 +715 169 3797 94
239.4118 +484 504 3796 97
239.4119 +816 408 3795 87
239.4120 +789 416 3794 92
239.4121 +907 758 3793 69
239.4122 +872 496 3792 13
239.4123 +614 139 3791 5
239.4124 +865 855 3790 16
239.4125 +151 932 3789 63
239.4126 +350 61 3788 62
239.4127 +664 969 3787 67
239.4128 +96 102 3786 23
239.4129 +992 949 3785 66
239.4130 +658 229 3784 2
239.4131 +262 566 3783 88
239.4132 +356 74 3782 3
239.4133 +283 890 3781 25
239.4134 +923 534 3780 74
239.4135 +870 3 3779 71
239.4136 +92 952 3778 80
239.4137 +866 444 3777 68
239.4138 +153 563 3776 56
239.4139 +719 640 3775 10
239.4140 +663 145 3774 33
239.4141 +491 846 3773 39
239.4142 +183 778 3772 90
239.4143 +356 507 3771 7
239.4144 +531 35 3770 35
239.4145 +51 913 3769 5
239.4146 +507 115 3768 77
239.4147 +881 116 3767 22
239.4148 +922 464 3766 71
239.4149 +494 769 3765 43
239.4150 +299 938 3764 5
239.4151 +68 490 3763 17
239.4152 +270 832 3762 30
239.4153 +471 713 3761 82
239.4154 +122 306 3760 82
239.4155 +797 275 3759 48
239.4156 +999 552 3758 54
239.4157 +651 512 3757 62
239.4158 +695 279 3756 95
239.4159 +830 378 3755 42
239.4160 +447 883 3754 19
239.4161 +658 864 3753 23
239.4162 +118 479 3752 79
239.4163 +407 2 3751 79
239.4164 +30 344 3750 34
239.4165 +722 937 3749 32
239.4166 +40 916 3748 79
239.4167 +232 668 3747 34
239.4168 +900 530 3746 95
239.4169 +494 232 3745 86
239.4170 +18 963 3744 38
239.4171 +385 434 3743 78
239.4172 +477 998 3742 53
239.4173 +658 449 3741 71
239.4174 +407 23 3740 37
239.4175 +20 527 3739 30
239.4176 +248 450 3738 68
239.4177 +137 391 3737 80
239.4178 +297 91 3736 33
239.4179 +268 481 3735 40
239.4180 +529 593 3734 47
239.4181 +435 249 3733 63
239.4182 +548 828 3732 90
239.4183 +425 334 3731 81
239.4184 +496 68 3730 25
239.4185 +76 626 3729 38
239.4186 +59 873 3728 77
239.4187 +300 475 3727 11
239.4188 +609 925 3726 83
239.4189 +888 930 3725 2
239.4190 +343 841 3724 73
239.4191 +421 725 3723 9
239.4192 +494 88 3722 88
239.4193 +265 568 3721 12
239.4194 +441 863 3720 92
239.4195 +752 614 3719 42
239.4196 +397 662 3718 1
239.4197 +550 270 3717 75
239.4198 +994 811 3716 69
239.4199 +88 289 3715 72
239.4200 +116 645 3714 54
239.4201 +637 207 3713 92
239.4202 +520 764 3712 92
239.4203 +704 193 3711 22
239.4204 +249 508 3710 82
239.4205 +952 403 3709 68
239.4206 +391 258 3708 35
239.4207 +459 67 3707 84
239.4208 +521 970 3706 55
239.4209 +644 175 3705 90
239.4210 +437 622 3704 97
239.4211 +443 995 3703 47
239.4212 +570 698 3702 11
239.4213 +685 404 3701 81
239.4214 +105 135 3700 45
239.4215 +144 333 3699 29
239.4216 +191 507 3698 56
239.4217 +96 291 3697 93
239.4218 +794 649 3696 93
239.4219 +553 933 3695 87
239.4220 +626 493 3694 20
239.4221 +297 362 3693 99
239.4222 +294 301 3692 87
239.4223 +268 359 3691 88
239.4224 +801 158 3690 57
239.4225 +826 736 3689 96
239.4226 +215 628 3688 95
239.4227 +642 994 3687 9
239.4228 +715 60 3686 30
239.4229 +440 670 3685 24
239.4230 +131 212 3684 92
239.4231 +60 121 3683 32
239.4232 +941 988 3682 0
239.4233 +201 305 3681 2
239.4234 +421 618 3680 46
239.4235 +107 7 3679 97
239.4236 +634 859 3678 61
239.4237 +933 791 3677 57
239.4238 +390 60 3676 92
239.4239 +458 315 3675 27
239.4240 +90 596 3674 30
239.4241 +133 327 3673 7
239.4242 +683 976 3672 11
239.4243 +686 558 3671 74
239.4244 +611 491 3670 77
239.4245 +147 364 3669 31
239.4246 +67 37 3668 47
239.4247 +731 646 3667 70
239.4248 +745 651 3666 54
239.4249 +718 966 3665 93
239.4250 +269 238 3664 36
239.4251 +350 951 3663 95
239.4252 +418 379 3662 45
239.4253 +66 960 3661 99
239.4254 +127 465 3660 7
239.4255 +326 840 3659 46
239.4256 +391 772 3658 8
239.4257 +995 157 3657 33
239.4258 +684 610 3656 98
239.4259 +728 564 3655 2
239.4260 +287 409 3654 44
239.4261 +572 507 3653 91
239.4262 +418 453 3652 93
239.4263 +494 922 3651 35
239.4264 +625 610 3650 93
239.4265 +67 383 3649 80
239.4266 +614 744 3648 93
239.4267 +546 349 3647 39
239.4268 +45 959 3646 31
239.4269 +155 577 3645 95
239.4270 +901 529 3644 44
239.4271 +54 987 3643 71
239.4272 +531 580 3642 15
239.4273 +311 411 3641 92
239.4274 +227 138 3640 86
239.4275 +639 866 3639 55
239.4276 +394 537 3638 45
239.4277 +390 85 3637 6
239.4278 +382 355 3636 50
239.4279 +47 513 3635 89
239.4280 +542 726 3634 25
239.4281 +406 561 3633 84
239.4282 +168 229 3632 52
239.4283 +273 54 3631 21
239.4284 +271 312 3630 8
239.4285 +328 104 3629 58
239.4286 +451 385 3628 24
239.4287 +730 566 3627 0
239.4288 +841 610 3626 0
239.4289 +787 636 3625 33
239.4290 +165 406 3624 50
239.4291 +331 323 3623 13
239.4292 +175 303 3622 23
239.4293 +742 135 3621 89
239.4294 +207 496 3620 0
239.4295 +719 342 3619 94
239.4296 +818 241 3618 87
239.4297 +956 995 3617 72
239.4298 +973 673 3616 88
239.4299 +230 828 3615 5
239.4300 +82 370 3614 62
239.4301 +20 897 3613 83
239.4302 +167 342 3612 15
239.4303 +639 894 3611 43
239.4304 +154 58 3610 53
239.4305 +100 65 3609 48
239.4306 +245 155 3608 90
239.4307 +321 832 3607 86
239.4308 +845 834 3606 98
239.4309 +457 431 3605 74
239.4310 +473 789 3604 14
239.4311 +554 676 3603 6
239.4312 +448 723 3602 85
239.4313 +835 898 3601 52
239.4314 +992 45 3600 48
239.4315 +910 587 3599 5
239.4316 +322 39 3598 85
239.4317 +998 878 3597 92
239.4318 +403 239 3596 47
239.4319 +642 595 3595 38
239.4320 +112 85 3594 98
239.4321 +953 209 3593 91
239.4322 +824 324 3592 10
239.4323 +853 42 3591 61
239.4324 +458 431 3590 84
239.4325 +548 198 3589 8
239.4326 +160 930 3588 58
239.4327 +639 447 3587 32
239.4328 +643 89 3586 59
239.4329 +509 403 3585 76
239.4330 +876 65 3584 53
239.4331 +884 812 3583 15
239.4332 +281 493 3582 12
239.4333 +611 769 3581 97
239.4334 +233 760 3580 39
239.4335 +267 494 3579 90
239.4336 +483 262 3578 38
239.4337 +358 729 3577 52
239.4338 +686 834 3576 99
239.4339 +337 229 3575 13
239.4340 +253 372 3574 63
239.4341 +318 28 3573 99
239.4342 +723 158 3572 60
239.4343 +9 576 3571 67
239.4344 +265 485 3570 37
239.4345 +232 522 3569 96
239.4346 +533 866 3568 78
239.4347 +895 525 3567 12
239.4348 +604 861 3566 67
239.4349 +857 500 3565 34
239.4350 +343 641 3564 8
239.4351 +870 387 3563 93
239.4352 +582 933 3562 59
239.4353 +91 292 3561 71
239.4354 +962 412 3560 74
239.4355 +655 181 3559 3
239.4356 +341 658 3558 69
239.4357 +663 453 3557 63
239.4358 +360 323 3556 29
239.4359 +858 265 3555 74
239.4360 +253 148 3554 51
239.4361 +454 340 3553 47
239.4362 +641 880 3552 28
239.4363 +879 970 3551 49
239.4364 +231 710 3550 12
239.4365 +522 334 3549 30
239.4366 +205 61 3548 31
239.4367 +129 347 3547 67
239.4368 +58 543 3546 30
239.4369 +117 232 3545 50
239.4370 +807 40 3544 60
239.4371 +460 185 3543 79
239.4372 +909 796 3542 81
239.4373 +259 362 3541 76
239.4374 +376 821 3540 64
239.4375 +273 992 3539 70
239.4376 +713 636 3538 31
239.4377 +803 374 3537 7
239.4378 +311 801 3536 7
239.4379 +192 897 3535 94
239.4380 +854 805 3534 30
239.4381 +389 985 3533 34
239.4382 +433 51 3532 55
239.4383 +541 114 3531 65
239.4384 +828 937 3530 88
239.4385 +356 393 3529 10
239.4386 +262 240 3528 55
239.4387 +572 4 3527 91
239.4388 +904 130 3526 49
239.4389 +91 631 3525 11
239.4390 +820 963 3524 33
239.4391 +933 795 3523 46
239.4392 +937 900 3522 95
239.4393 +176 766 3521 89
239.4394 +544 780 3520 71
239.4395 +153 543 3519 47
239.4396 +235 648 3518 9
239.4397 +873 418 3517 69
239.4398 +499 373 3516 66
239.4399 +667 781 3515 81
239.4400 +167 872 3514 27
239.4401 +895 508 3513 88
239.4402 +133 64 3512 99
239.4403 +986 178 3511 76
239.4404 +237 241 3510 63
239.4405 +894 378 3509 39
239.4406 +230 403 3508 91
239.4407 +45 21 3507 36
239.4408 +592 855 3506 37
239.4409 +908 541 3505 83
239.4410 +364 384 3504 50
239.4411 +444 890 3503 27
239.4412 +886 235 3502 76
239.4413 +936 128 3501 14
239.4414 +862 240 3500 74
239.4415 +975 474 3499 34
239.4416 +381 555 3498 66
239.4417 +165 987 3497 18
239.4418 +313 543 3496 45
239.4419 +157 330 3495 68
239.4420 +494 228 3494 54
239.4421 +654 510 3493 91
239.4422 +107 614 3492 55
239.4423 +887 399 3491 94
239.4424 +766 405 3490 7
239.4425 +918 679 3489 88
239.4426 +568 478 3488 59
239.4427 +444 732 3487 21
239.4428 +212 769 3486 85
239.4429 +102 139 3485 15
239.4430 +718 624 3484 66
239.4431 +895 361 3483 83
239.4432 +215 608 3482 54
239.4433 +993 875 3481 21
239.4434 +726 187 3480 12
239.4435 +200 292 3479 84
239.4436 +745 378 3478 35
239.4437 +963 364 3477 12
239.4438 +629 695 3476 23
239.4439 +515 493 3475 10
239.4440 +262 823 3474 38
239.4441 +752 292 3473 82
239.4442 +733 327 3472 68
239.4443 +687 99 3471 22
239.4444 +895 272 3470 26
239.4445 +914 498 3469 52
239.4446 +14 226 3468 45
239.4447 +668 892 3467 78
239.4448 +201 122 3466 33
239.4449 +670 726 3465 11
239.4450 +530 560 3464 25
239.4451 +965 142 3463 50
239.4452 +227 458 3462 1
239.4453 +827 954 3461 4
239.4454 +773 742 3460 79
239.4455 +271 70 3459 98
239.4456 +334 672 3458 90
239.4457 +769 448 3457 34
239.4458 +395 221 3456 46
239.4459 +165 860 3455 53
239.4460 +418 743 3454 13
239.4461 +683 490 3453 56
239.4462 +504 973 3452 73
239.4463 +211 253 3451 40
239.4464 +672 811 3450 5
239.4465 +397 80 3449 50
239.4466 +224 554 3448 93
239.4467 +226 878 3447 56
239.4468 +360 934 3446 37
239.4469 +116 392 3445 23
239.4470 +253 573 3444 74
239.4471 +517 828 3443 73
239.4472 +719 337 3442 17
239.4473 +442 346 3441 29
239.4474 +730 551 3440 53
239.4475 +526 564 3439 27
239.4476 +676 373 3438 17
239.4477 +943 190 3437 99
239.4478 +542 143 3436 86
239.4479 +819 483 3435 24
239.4480 +745 11 3434 86
239.4481 +490 556 3433 73
239.4482 +990 885 3432 79
239.4483 +795 753 3431 27
239.4484 +987 265 3430 71
239.4485 +190 101 3429 20
239.4486 +183 175 3428 84
239.4487 +46 131 3427 73
239.4488 +660 621 3426 40
239.4489 +472 380 3425 72
239.4490 +454 127 3424 7
239.4491 +671 938 3423 25
239.4492 +132 520 3422 50
239.4493 +488 564 3421 19
239.4494 +163 507 3420 80
239.4495 +925 354 3419 79
239.4496 +43 117 3418 0
239.4497 +510 330 3417 13
239.4498 +240 679 3416 38
239.4499 +253 648 3415 18
239.4500 +189 819 3414 1
239.4501 +417 753 3413 78
239.4502 +956 305 3412 53
239.4503 +57 386 3411 64
239.4504 +153 11 3410 32
239.4505 +236 789 3409 23
239.4506 +787 869 3408 88
239.4507 +651 750 3407 53
239.4508 +30 198 3406 26
239.4509 +829 170 3405 98
239.4510 +65 234 3404 6
239.4511 +448 244 3403 77
239.4512 +919 894 3402 46
239.4513 +374 320 3401 89
239.4514 +222 86 3400 90
239.4515 +919 355 3399 91
239.4516 +119 348 3398 44
239.4517 +552 264 3397 13
239.4518 +28 281 3396 62
239.4519 +936 924 3395 20
239.4520 +989 291 3394 76
239.4521 +349 310 3393 61
239.4522 +574 562 3392 52
239.4523 +233 994 3391 54
239.4524 +730 988 3390 15
239.4525 +7 466 3389 30
239.4526 +83 314 3388 80
239.4527 +983 514 3387 56
239.4528 +357 420 3386 52
239.4529 +632 436 3385 9
239.4530 +980 146 3384 94
239.4531 +748 88 3383 63
239.4532 +567 984 3382 77
239.4533 +6 392 3381 34
239.4534 +521 849 3380 50
239.4535 +151 501 3379 72
239.4536 +799 233 3378 92
239.4537 +94 42 3377 10
239.4538 +983 431 3376 62
239.4539 +290 145 3375 72
239.4540 +58 307 3374 65
239.4541 +104 864 3373 23
239.4542 +592 434 3372 18
239.4543 +542 837 3371 56
239.4544 +347 780 3370 48
239.4545 +268 798 3369 36
239.4546 +190 823 3368 35
239.4547 +610 474 3367 70
239.4548 +286 901 3366 11
239.4549 +837 72 3365 69
239.4550 +443 418 3364 23
239.4551 +429 52 3363 95
239.4552 +596 618 3362 51
239.4553 +57 76 3361 4
239.4554 +981 114 3360 19
239.4555 +975 17 3359 7
239.4556 +349 647 3358 7
239.4557 +572 593 3357 58
239.4558 +828 418 3356 32
239.4559 +654 460 3355 44
239.4560 +366 278 3354 39
239.4561 +433 441 3353 1
239.4562 +542 462 3352 83
239.4563 +962 855 3351 53
239.4564 +97 114 3350 7
239.4565 +370 2 3349 0
239.4566 +53 497 3348 62
239.4567 +174 255 3347 77
239.4568 +958 875 3346 74
239.4569 +182 54 3345 17
239.4570 +836 380 3344 28
239.4571 +979 181 3343 93
239.4572 +606 292 3342 89
239.4573 +741 464 3341 58
239.4574 +111 68 3340 86
239.4575 +505 380 3339 72
239.4576 +241 848 3338 31
239.4577 +380 33 3337 87
239.4578 +820 569 3336 21
239.4579 +673 886 3335 77
239.4580 +199 355 3334 34
239.4581 +888 41 3333 85
239.4582 +828 311 3332 37
239.4583 +395 715 3331 86
239.4584 +687 138 3330 62
239.4585 +532 410 3329 60
239.4586 +815 437 3328 26
239.4587 +464 662 3327 86
239.4588 +682 441 3326 55
239.4589 +531 429 3325 14
239.4590 +313 488 3324 47
239.4591 +730 483 3323 31
239.4592 +595 507 3322 6
239.4593 +577 236 3321 43
239.4594 +727 22 3320 70
239.4595 +973 342 3319 15
239.4596 +775 403 3318 71
239.4597 +221 301 3317 35
239.4598 +11 412 3316 78
239.4599 +941 672 3315 15
239.4600 +5 164 3314 21
239.4601 +975 249 3313 58
239.4602 +271 627 3312 13
239.4603 +213 725 3311 1
239.4604 +680 552 3310 84
239.4605 +938 438 3309 75
239.4606 +102 366 3308 19
239.4607 +888 569 3307 55
239.4608 +739 630 3306 20
239.4609 +508 933 3305 7
239.4610 +914 634 3304 93
239.4611 +621 448 3303 2
239.4612 +902 115 3302 70
239.4613 +172 169 3301 5
239.4614 +113 94 3300 53
239.4615 +72 557 3299 74
239.4616 +796 643 3298 83
239.4617 +939 344 3297 21
239.4618 +696 139 3296 14
239.4619 +298 134 3295 23
239.4620 +186 906 3294 59
239.4621 +332 325 3293 29
239.4622 +946 646 3292 71
239.4623 +74 524 3291 72
239.4624 +537 791 3290 5
239.4625 +913 904 3289 4
239.4626 +299 623 3288 27
239.4627 +204 64 3287 85
239.4628 +5 917 3286 24
239.4629 +228 637 3285 39
239.4630 +580 301 3284 11
239.4631 +679 573 3283 85
239.4632 +121 988 3282 38
239.4633 +732 670 3281 87
239.4634 +887 17 3280 53
239.4635 +281 765 3279 62
239.4636 +558 419 3278 61
239.4637 +147 613 3277 9
239.4638 +279 844 3276 19
239.4639 +336 285 3275 77
239.4640 +727 259 3274 64
239.4641 +584 467 3273 90
239.4642 +318 514 3272 55
239.4643 +653 334 3271 38
239.4644 +251 912 3270 84
239.4645 +346 9 3269 60
239.4646 +805 519 3268 72
239.4647 +769 896 3267 41
239.4648 +559 421 3266 86
239.4649 +26 129 3265 94
239.4650 +792 746 3264 60
239.4651 +953 343 3263 14
239.4652 +179 169 3262 26
239.4653 +422 543 3261 66
239.4654 +903 239 3260 40
239.4655 +489 882 3259 90
239.4656 +623 312 3258 54
239.4657 +474 542 3257 3
239.4658 +291 925 3256 21
239.4659 +383 334 3255 53
239.4660 +403 465 3254 23
239.4661 +173 876 3253 83
239.4662 +626 601 3252 77
239.4663 +303 263 3251 75
239.4664 +356 496 3250 51
239.4665 +570 364 3249 41
239.4666 +769 505 3248 86
239.4667 +617 825 3247 14
239.4668 +590 677 3246 18
239.4669 +869 299 3245 90
239.4670 +588 394 3244 98
239.4671 +275 65 3243 22
239.4672 +338 16 3242 54
239.4673 +767 238 3241 32
239.4674 +131 104 3240 94
239.4675 +859 547 3239 78
239.4676 +679 716 3238 80
239.4677 +147 965 3237 15
239.4678 +378 275 3236 2
239.4679 +904 927 3235 72
239.4680 +329 750 3234 28
239.4681 +48 682 3233 31
239.4682 +777 224 3232 93
239.4683 +133 376 3231 57
239.4684 +557 160 3230 63
239.4685 +831 985 3229 27
239.4686 +750 649 3228 17
239.4687 +690 124 3227 53
239.4688 +347 306 3226 76
239.4689 +177 439 3225 47
239.4690 +67 968 3224 57
239.4691 +458 376 3223 28
239.4692 +847 365 3222 27
239.4693 +216 935 3221 64
239.4694 +175 363 3220 57
239.4695 +335 92 3219 72
239.4696 +525 648 3218 8
239.4697 +818 762 3217 6
239.4698 +866 295 3216 34
239.4699 +471 899 3215 17
239.4700 +591 293 3214 10
239.4701 +11 10 3213 60
239.4702 +429 626 3212 61
239.4703 +572 67 3211 63
239.4704 +271 850 3210 4
239.4705 +443 645 3209 83
239.4706 +886 19 3208 81
239.4707 +466 717 3207 70
239.4708 +395 172 3206 95
239.4709 +605 60 3205 39
239.4710 +283 500 3204 87
239.4711 +383 998 3203 58
239.4712 +559 978 3202 58
239.4713 +216 590 3201 85
239.4714 +204 201 3200 30
239.4715 +626 29 3199 82
239.4716 +301 103 3198 55
239.4717 +545 755 3197 41
239.4718 +111 556 3196 7
239.4719 +559 515 3195 78
239.4720 +502 299 3194 32
239.4721 +19 997 3193 90
239.4722 +388 725 3192 82
239.4723 +389 555 3191 34
239.4724 +172 474 3190 1
239.4725 +925 269 3189 57
239.4726 +348 138 3188 32
239.4727 +198 348 3187 75
239.4728 +41 280 3186 43
239.4729 +215 467 3185 55
239.4730 +301 422 3184 5
239.4731 +272 75 3183 48
239.4732 +170 481 3182 63
239.4733 +81 330 3181 99
239.4734 +204 433 3180 21
239.4735 +131 254 3179 24
239.4736 +789 568 3178 57
239.4737 +67 322 3177 15
239.4738 +813 882 3176 15
239.4739 +45 494 3175 82
239.4740 +346 573 3174 91
239.4741 +594 852 3173 2
239.4742 +150 632 3172 10
239.4743 +897 781 3171 8
239.4744 +178 970 3170 87
239.4745 +685 670 3169 7
239.4746 +246 426 3168 34
239.4747 +439 993 3167 72
239.4748 +388 330 3166 25
239.4749 +920 913 3165 76
239.4750 +721 883 3164 69
239.4751 +219 928 3163 75
239.4752 +850 12 3162 44
239.4753 +810 212 3161 25
239.4754 +300 803 3160 71
239.4755 +243 731 3159 49
239.4756 +432 620 3158 43
239.4757 +663 467 3157 80
239.4758 +417 485 3156 5
239.4759 +29 70 3155 46
239.4760 +955 945 3154 19
239.4761 +915 309 3153 50
239.4762 +799 190 3152 36
239.4763 +409 533 3151 4
239.4764 +72 226 3150 51
239.4765 +110 53 3149 5
239.4766 +153 632 3148 81
239.4767 +981 755 3147 76
239.4768 +415 584 3146 24
239.4769 +124 268 3145 38
239.4770 +636 697 3144 7
239.4771 +118 132 3143 3
239.4772 +656 328 3142 11
239.4773 +307 529 3141 39
239.4774 +172 453 3140 33
239.4775 +420 245 3139 96
239.4776 +877 42 3138 95
239.4777 +171 522 3137 17
239.4778 +315 858 3136 56
239.4779 +571 312 3135 29
239.4780 +564 35 3134 48
239.4781 +803 922 3133 51
239.4782 +798 726 3132 46
239.4783 +76 53 3131 34
239.4784 +208 374 3130 13
239.4785 +203 5 3129 75
239.4786 +519 783 3128 54
239.4787 +663 607 3127 70
239.4788 +546 273 3126 85
239.4789 +277 804 3125 74
239.4790 +112 969 3124 0
239.4791 +196 55 3123 76
239.4792 +673 113 3122 0
239.4793 +678 213 3121 72
239.4794 +369 383 3120 86
239.4795 +221 208 3119 0
239.4796 +176 837 3118 68
239.4797 +334 850 3117 85
239.4798 +469 112 3116 11
239.4799 +834 736 3115 26
239.4800 +914 246 3114 16
239.4801 +942 755 3113 91
239.4802 +899 282 3112 52
239.4803 +829 854 3111 99
239.4804 +175 862 3110 30
239.4805 +371 321 3109 14
239.4806 +986 828 3108 4
239.4807 +738 737 3107 84
239.4808 +375 848 3106 86
239.4809 +489 104 3105 63
239.4810 +490 248 3104 92
239.4811 +473 393 3103 97
239.4812 +427 528 3102 4
239.4813 +992 685 3101 7
239.4814 +541 161 3100 65
239.4815 +492 102 3099 80
239.4816 +90 202 3098 38
239.4817 +889 976 3097 24
239.4818 +744 230 3096 36
239.4819 +856 714 3095 88
239.4820 +855 948 3094 99
239.4821 +864 929 3093 1
239.4822 +842 971 3092 4
239.4823 +524 416 3091 43
239.4824 +58 849 3090 45
239.4825 +899 420 3089 4
239.4826 +226 135 3088 40
239.4827 +746 886 3087 20
239.4828 +516 476 3086 14
239.4829 +765 887 3085 88
239.4830 +18 981 3084 0
239.4831 +958 971 3083 99
239.4832 +555 610 3082 2
239.4833 +566 984 3081 31
239.4834 +429 401 3080 46
239.4835 +284 646 3079 15
239.4836 +249 200 3078 67
239.4837 +410 56 3077 47
239.4838 +588 257 3076 22
239.4839 +906 886 3075 75
239.4840 +9 10 3074 74
239.4841 +360 968 3073 6
239.4842 +626 704 3072 40
239.4843 +582 851 3071 98
239.4844 +755 307 3070 13
239.4845 +445 484 3069 14
239.4846 +144 193 3068 3
239.4847 +798 250 3067 83
239.4848 +370 478 3066 82
239.4849 +876 3 3065 68
239.4850 +41 686 3064 89
239.4851 +264 658 3063 64
239.4852 +852 413 3062 73
239.4853 +543 851 3061 4
239.4854 +822 992 3060 82
239.4855 +291 110 3059 30
239.4856 +943 195 3058 30
239.4857 +771 17 3057 34
239.4858 +474 138 3056 42
239.4859 +317 786 3055 49
239.4860 +28 248 3054 83
239.4861 +244 913 3053 77
239.4862 +561 690 3052 41
239.4863 +859 216 3051 30
239.4864 +881 517 3050 72
239.4865 +915 8 3049 53
239.4866 +177 954 3048 34
239.4867 +879 917 3047 17
239.4868 +352 934 3046 29
239.4869 +537 659 3045 15
239.4870 +334 57 3044 28
239.4871 +222 366 3043 78
239.4872 +474 102 3042 68
239.4873 +698 588 3041 70
239.4874 +508 189 3040 97
239.4875 +53 183 3039 96
239.4876 +37 176 3038 73
239.4877 +982 874 3037 29
239.4878 +275 139 3036 52
239.4879 +602 869 3035 81
239.4880 +691 504 3034 20
239.4881 +263 100 3033 11
239.4882 +514 980 3032 74
239.4883 +398 725 3031 77
239.4884 +5 10 3030 19
239.4885 +7 228 3029 45
239.4886 +301 439 3028 1
239.4887 +734 771 3027 5
239.4888 +270 711 3026 70
239.4889 +364 611 3025 67
239.4890 +403 91 3024 91
239.4891 +120 363 3023 42
239.4892 +254 972 3022 74
239.4893 +714 585 3021 11
239.4894 +781 734 3020 39
239.4895 +788 439 3019 99
239.4896 +668 960 3018 70
239.4897 +59 348 3017 56
239.4898 +100 33 3016 46
239.4899 +519 762 3015 90
239.4900 +728 483 3014 96
239.4901 +390 678 3013 28
239.4902 +387 633 3012 86
239.4903 +850 722 3011 54
239.4904 +295 395 3010 93
239.4905 +478 291 3009 99
239.4906 +611 138 3008 12
239.4907 +315 103 3007 60
239.4908 +271 557 3006 95
239.4909 +278 945 3005 58
239.4910 +805 677 3004 79
239.4911 +44 418 3003 33
239.4912 +910 325 3002 0
239.4913 +327 607 3001 53
239.4914 +103 940 3000 55
239.4915 +153 872 2999 81
239.4916 +34 512 2998 86
239.4917 +546 648 2997 29
239.4918 +611 379 2996 4
239.4919 +268 788 2995 99
239.4920 +258 453 2994 47
239.4921 +92 334 2993 76
239.4922 +717 466 2992 13
239.4923 +667 981 2991 58
239.4924 +67 737 2990 22
239.4925 +359 950 2989 95
239.4926 +863 570 2988 11
239.4927 +269 252 2987 48
239.4928 +590 51 2986 93
239.4929 +335 519 2985 34
239.4930 +118 712 2984 0
239.4931 +868 626 2983 16
239.4932 +484 550 2982 37
239.4933 +244 360 2981 5
239.4934 +786 272 2980 59
239.4935 +380 832 2979 70
239.4936 +317 630 2978 49
239.4937 +200 553 2977 59
239.4938 +532 591 2976 67
239.4939 +807 333 2975 25
239.4940 +85 843 2974 21
239.4941 +76 790 2973 25
239.4942 +189 324 2972 38
239.4943 +88 451 2971 23
239.4944 +440 891 2970 45
239.4945 +201 212 2969 40
239.4946 +76 902 2968 6
239.4947 +962 915 2967 11
239.4948 +257 423 2966 66
239.4949 +489 38 2965 72
239.4950 +52 966 2964 72
239.4951 +466 866 2963 0
239.4952 +873 144 2962 88
239.4953 +560 781 2961 10
239.4954 +679 52 2960 64
239.4955 +310 342 2959 23
239.4956 +986 946 2958 12
239.4957 +491 448 2957 11
239.4958 +385 943 2956 70
239.4959 +72 3 2955 76
239.4960 +99 713 2954 43
239.4961 +722 120 2953 58
239.4962 +362 786 2952 59
239.4963 +729 452 2951 31
239.4964 +709 409 2950 88
239.4965 +396 112 2949 36
239.4966 +497 11 2948 32
239.4967 +505 408 2947 49
239.4968 +940 937 2946 10
239.4969 +289 331 2945 31
239.4970 +592 850 2944 97
239.4971 +334 993 2943 37
239.4972 +333 279 2942 35
239.4973 +43 432 2941 63
239.4974 +297 511 2940 1
239.4975 +101 45 2939 31
239.4976 +602 827 2938 89
239.4977 +471 390 2937 99
239.4978 +605 792 2936 56
239.4979 +480 340 2935 65
239.4980 +857 594 2934 69
239.4981 +713 17 2933 25
239.4982 +847 726 2932 0
239.4983 +920 613 2931 29
239.4984 +466 706 2930 74
239.4985 +218 413 2929 19
239.4986 +436 907 2928 49
239.4987 +598 427 2927 13
239.4988 +451 914 2926 86
239.4989 +746 954 2925 12
239.4990 +576 437 2924 62
239.4991 +291 257 2923 14
239.4992 +112 710 2922 86
239.4993 +906 544 2921 92
239.4994 +292 549 2920 45
239.4995 +506 697 2919 24
239.4996 +479 368 2918 78
239.4997 +513 264 2917 83
239.4998 +959 740 2916 14
239.4999 +516 501 2915 70
239.5000 +180 479 2914 16
239.5001 +547 278 2913 28
239.5002 +166 938 2912 17
239.5003 +994 472 2911 20
239.5004 +852 207 2910 61
239.5005 +329 465 2909 78
239.5006 +103 943 2908 2
239.5007 +524 691 2907 96
239.5008 +238 441 2906 55
239.5009 +22 535 2905 44
239.5010 +201 884 2904 33
239.5011 +339 106 2903 63
239.5012 +465 972 2902 38
239.5013 +265 591 2901 17
239.5014 +741 828 2900 14
239.5015 +522 758 2899 52
239.5016 +251 60 2898 22
239.5017 +250 413 2897 57
239.5018 +906 109 2896 28
239.5019 +651 107 2895 21
239.5020 +777 703 2894 82
239.5021 +134 251 2893 86
239.5022 +380 209 2892 87
239.5023 +763 29 2891 19
239.5024 +69 618 2890 52
239.5025 +698 297 2889 21
239.5026 +647 646 2888 27
239.5027 +303 294 2887 0
239.5028 +2 68 2886 34
239.5029 +404 396 2885 25
239.5030 +451 958 2884 87
239.5031 +42 987 2883 64
239.5032 +179 674 2882 75
239.5033 +411 675 2881 61
239.5034 +321 304 2880 69
239.5035 +650 948 2879 37
239.5036 +352 269 2878 5
239.5037 +225 656 2877 34
239.5038 +672 89 2876 30
239.5039 +437 380 2875 59
239.5040 +970 231 2874 95
239.5041 +313 888 2873 40
239.5042 +999 136 2872 86
239.5043 +370 922 2871 76
239.5044 +355 323 2870 9
239.5045 +679 319 2869 67
239.5046 +613 707 2868 29
239.5047 +566 43 2867 12
239.5048 +709 701 2866 55
239.5049 +148 646 2865 23
239.5050 +342 543 2864 46
239.5051 +751 546 2863 65
239.5052 +214 93 2862 31
239.5053 +598 678 2861 62
239.5054 +4 419 2860 1
239.5055 +612 372 2859 67
239.5056 +663 171 2858 6
239.5057 +341 573 2857 4
239.5058 +55 318 2856 85
239.5059 +102 767 2855 56
239.5060 +996 809 2854 80
239.5061 +453 343 2853 59
239.5062 +415 686 2852 53
239.5063 +258 612 2851 61
239.5064 +47 338 2850 59
239.5065 +200 610 2849 39
239.5066 +598 19 2848 94
239.5067 +254 188 2847 32
239.5068 +550 296 2846 28
239.5069 +958 754 2845 95
239.5070 +466 214 2844 10
239.5071 +657 53 2843 54
239.5072 +73 921 2842 3
239.5073 +274 22 2841 15
239.5074 +728 201 2840 21
239.5075 +590 444 2839 84
239.5076 +831 626 2838 60
239.5077 +891 35 2837 34
239.5078 +541 333 2836 70
239.5079 +540 846 2835 59
239.5080 +160 563 2834 49
239.5081 +132 505 2833 80
239.5082 +899 881 2832 58
239.5083 +820 945 2831 79
239.5084 +757 363 2830 54
239.5085 +817 245 2829 13
239.5086 +590 258 2828 75
239.5087 +702 639 2827 93
239.5088 +486 111 2826 34
239.5089 +283 99 2825 0
239.5090 +57 683 2824 37
239.5091 +623 224 2823 2
239.5092 +936 785 2822 23
239.5093 +581 253 2821 7
239.5094 +118 407 2820 6
239.5095 +986 378 2819 93
239.5096 +618 819 2818 22
239.5097 +528 589 2817 88
239.5098 +12 348 2816 21
239.5099 +416 621 2815 20
239.5100 +458 351 2814 22
239.5101 +439 794 2813 43
239.5102 +532 154 2812 68
239.5103 +845 15 2811 35
239.5104 +29 123 2810 46
239.5105 +559 712 2809 13
239.5106 +229 339 2808 36
239.5107 +241 671 2807 9
239.5108 +726 13 2806 51
239.5109 +270 977 2805 59
239.5110 +557 791 2804 95
239.5111 +639 746 2803 1
239.5112 +139 332 2802 90
239.5113 +892 891 2801 68
239.5114 +410 331 2800 81
239.5115 +372 763 2799 47
239.5116 +668 278 2798 32
239.5117 +658 574 2797 98
239.5118 +35 920 2796 51
239.5119 +185 638 2795 45
239.5120 +44 938 2794 71
239.5121 +413 111 2793 91
239.5122 +441 220 2792 50
239.5123 +559 871 2791 24
239.5124 +568 345 2790 48
239.5125 +484 141 2789 3
239.5126 +703 340 2788 70
239.5127 +654 473 2787 0
239.5128 +281 59 2786 62
239.5129 +700 743 2785 85
239.5130 +826 793 2784 14
239.5131 +891 418 2783 63
239.5132 +349 253 2782 97
239.5133 +525 764 2781 88
239.5134 +204 443 2780 99
239.5135 +800 333 2779 8
239.5136 +867 694 2778 78
239.5137 +414 387 2777 4
239.5138 +315 772 2776 37
239.5139 +949 708 2775 58
239.5140 +375 510 2774 87
239.5141 +164 658 2773 93
239.5142 +489 89 2772 54
239.5143 +320 892 2771 82
239.5144 +110 906 2770 32
239.5145 +639 302 2769 40
239.5146 +307 731 2768 93
239.5147 +615 677 2767 45
239.5148 +63 792 2766 9
239.5149 +198 706 2765 36
239.5150 +852 939 2764 57
239.5151 +568 393 2763 21
239.5152 +197 718 2762 67
239.5153 +985 502 2761 16
239.5154 +603 917 2760 21
239.5155 +571 470 2759 47
239.5156 +54 479 2758 33
239.5157 +885 354 2757 69
239.5158 +85 733 2756 55
239.5159 +767 791 2755 86
239.5160 +545 363 2754 34
239.5161 +674 535 2753 28
239.5162 +215 505 2752 37
239.5163 +585 959 2751 21
239.5164 +446 739 2750 38
239.5165 +990 138 2749 3
239.5166 +125 639 2748 51
239.5167 +620 140 2747 16
239.5168 +942 686 2746 79
239.5169 +427 518 2745 31
239.5170 +828 62 2744 22
239.5171 +29 912 2743 87
239.5172 +546 159 2742 45
239.5173 +219 830 2741 63
239.5174 +600 350 2740 13
239.5175 +498 514 2739 45
239.5176 +499 348 2738 86
239.5177 +453 369 2737 50
239.5178 +167 481 2736 67
239.5179 +456 96 2735 51
239.5180 +150 350 2734 59
239.5181 +753 412 2733 79
239.5182 +328 828 2732 48
239.5183 +480 492 2731 32
239.5184 +835 682 2730 61
239.5185 +165 590 2729 10
239.5186 +979 360 2728 99
239.5187 +887 826 2727 4
239.5188 +384 163 2726 28
239.5189 +746 915 2725 71
239.5190 +937 801 2724 30
239.5191 +584 314 2723 39
239.5192 +336 156 2722 42
239.5193 +809 708 2721 84
239.5194 +91 516 2720 64
239.5195 +230 102 2719 67
239.5196 +534 954 2718 18
239.5197 +662 758 2717 9
239.5198 +247 574 2716 50
239.5199 +114 405 2715 63
239.5200 +486 908 2714 80
239.5201 +158 972 2713 35
239.5202 +447 575 2712 24
239.5203 +191 204 2711 52
239.5204 +414 973 2710 71
239.5205 +147 483 2709 86
239.5206 +195 95 2708 69
239.5207 +184 588 2707 87
239.5208 +169 864 2706 41
239.5209 +496 830 2705 13
239.5210 +935 454 2704 62
239.5211 +397 105 2703 32
239.5212 +370 721 2702 71
239.5213 +230 809 2701 25
239.5214 +490 856 2700 77
239.5215 +388 165 2699 26
239.5216 +507 824 2698 95
239.5217 +723 457 2697 1
239.5218 +34 281 2696 1
239.5219 +375 504 2695 67
239.5220 +348 300 2694 56
239.5221 +384 617 2693 53
239.5222 +912 454 2692 2
239.5223 +953 478 2691 14
239.5224 +690 510 2690 74
239.5225 +341 314 2689 10
239.5226 +366 940 2688 88
239.5227 +176 996 2687 78
239.5228 +776 342 2686 68
239.5229 +203 111 2685 65
239.5230 +683 22 2684 2
239.5231 +162 512 2683 96
239.5232 +975 886 2682 47
239.5233 +968 399 2681 95
239.5234 +196 639 2680 26
239.5235 +373 220 2679 34
239.5236 +943 98 2678 97
239.5237 +654 93 2677 19
239.5238 +230 31 2676 39
239.5239 +89 631 2675 57
239.5240 +510 63 2674 51
239.5241 +625 491 2673 52
239.5242 +487 513 2672 18
239.5243 +760 696 2671 0
239.5244 +419 912 2670 77
239.5245 +122 375 2669 82
239.5246 +4 783 2668 42
239.5247 +62 791 2667 28
239.5248 +400 826 2666 42
239.5249 +567 53 2665 14
239.5250 +571 998 2664 57
239.5251 +978 334 2663 88
239.5252 +816 178 2662 13
239.5253 +783 235 2661 72
239.5254 +537 949 2660 34
239.5255 +591 392 2659 29
239.5256 +992 140 2658 11
239.5257 +964 864 2657 94
239.5258 +773 283 2656 66
239.5259 +54 561 2655 83
239.5260 +663 694 2654 99
239.5261 +156 745 2653 59
239.5262 +943 411 2652 16
239.5263 +285 386 2651 3
239.5264 +557 43 2650 24
239.5265 +251 179 2649 94
239.5266 +276 176 2648 59
239.5267 +581 279 2647 2
239.5268 +721 829 2646 19
239.5269 +866 836 2645 71
239.5270 +949 402 2644 39
239.5271 +334 431 2643 50
239.5272 +25 128 2642 21
239.5273 +342 786 2641 65
239.5274 +864 299 2640 72
239.5275 +3 348 2639 30
239.5276 +896 570 2638 97
239.5277 +449 836 2637 69
239.5278 +993 472 2636 85
239.5279 +434 327 2635 85
239.5280 +970 883 2634 91
239.5281 +302 294 2633 61
239.5282 +342 555 2632 30
239.5283 +487 928 2631 68
239.5284 +951 423 2630 47
239.5285 +777 329 2629 86
239.5286 +733 280 2628 10
239.5287 +364 835 2627 44
239.5288 +144 3 2626 45
239.5289 +444 937 2625 55
239.5290 +588 303 2624 46
239.5291 +739 305 2623 66
239.5292 +626 626 2622 96
239.5293 +505 204 2621 85
239.5294 +93 617 2620 53
239.5295 +48 754 2619 17
239.5296 +445 659 2618 4
239.5297 +831 990 2617 36
239.5298 +66 897 2616 22
239.5299 +634 95 2615 69
239.5300 +997 795 2614 85
239.5301 +678 707 2613 84
239.5302 +422 106 2612 11
239.5303 +586 318 2611 12
239.5304 +862 361 2610 41
239.5305 +95 129 2609 4
239.5306 +668 675 2608 60
239.5307 +93 148 2607 61
239.5308 +801 520 2606 76
239.5309 +300 844 2605 43
239.5310 +87 6 2604 63
239.5311 +601 735 2603 31
239.5312 +787 992 2602 25
239.5313 +956 709 2601 83
239.5314 +232 366 2600 72
239.5315 +454 441 2599 76
239.5316 +526 990 2598 42
239.5317 +628 848 2597 57
239.5318 +676 333 2596 29
239.5319 +837 795 2595 50
239.5320 +270 317 2594 21
239.5321 +743 62 2593 48
239.5322 +283 420 2592 81
239.5323 +342 111 2591 83
239.5324 +925 957 2590 72
239.5325 +451 339 2589 77
239.5326 +142 852 2588 92
239.5327 +514 282 2587 89
239.5328 +538 791 2586 95
239.5329 +477 287 2585 83
239.5330 +255 726 2584 56
239.5331 +642 672 2583 52
239.5332 +309 983 2582 45
239.5333 +153 105 2581 94
239.5334 +617 946 2580 41
239.5335 +487 850 2579 47
239.5336 +569 29 2578 30
239.5337 +490 945 2577 62
239.5338 +504 114 2576 97
239.5339 +561 271 2575 6
239.5340 +54 39 2574 22
239.5341 +688 67 2573 61
239.5342 +877 518 2572 33
239.5343 +159 524 2571 15
239.5344 +96 942 2570 53
239.5345 +820 165 2569 13
239.5346 +84 681 2568 91
239.5347 +831 651 2567 7
239.5348 +842 915 2566 98
239.5349 +231 839 2565 94
239.5350 +972 609 2564 50
239.5351 +548 279 2563 36
239.5352 +994 177 2562 81
239.5353 +581 619 2561 71
239.5354 +777 405 2560 6
239.5355 +483 213 2559 27
239.5356 +30 838 2558 73
239.5357 +736 91 2557 25
239.5358 +75 44 2556 98
239.5359 +229 435 2555 61
239.5360 +329 141 2554 25
239.5361 +101 554 2553 42
239.5362 +558 91 2552 55
239.5363 +213 656 2551 41
239.5364 +191 786 2550 80
239.5365 +375 540 2549 29
239.5366 +746 483 2548 45
239.5367 +47 263 2547 29
239.5368 +608 378 2546 66
239.5369 +294 351 2545 84
239.5370 +587 835 2544 90
239.5371 +462 869 2543 22
239.5372 +435 141 2542 54
239.5373 +870 609 2541 34
239.5374 +246 509 2540 2
239.5375 +56 841 2539 81
239.5376 +219 158 2538 62
239.5377 +885 634 2537 69
239.5378 +26 814 2536 43
239.5379 +515 945 2535 31
239.5380 +966 672 2534 70
239.5381 +728 685 2533 12
239.5382 +531 198 2532 2
239.5383 +100 322 2531 56
239.5384 +667 206 2530 62
239.5385 +682 186 2529 18
239.5386 +523 931 2528 83
239.5387 +820 258 2527 33
239.5388 +868 125 2526 85
239.5389 +273 607 2525 51
239.5390 +987 582 2524 54
239.5391 +486 96 2523 23
239.5392 +876 462 2522 19
239.5393 +115 941 2521 43
239.5394 +20 434 2520 43
239.5395 +254 352 2519 98
239.5396 +672 502 2518 15
239.5397 +133 475 2517 70
239.5398 +518 347 2516 95
239.5399 +24 961 2515 59
239.5400 +486 312 2514 28
239.5401 +634 40 2513 50
239.5402 +521 765 2512 61
239.5403 +506 999 2511 76
239.5404 +81 447 2510 9
239.5405 +850 826 2509 76
239.5406 +26 455 2508 58
239.5407 +127 751 2507 53
239.5408 +386 357 2506 61
239.5409 +649 308 2505 49
239.5410 +272 785 2504 53
239.5411 +274 889 2503 85
239.5412 +766 849 2502 11
239.5413 +552 666 2501 1
239.5414 +621 328 2500 42
239.5415 +370 184 2499 23
239.5416 +703 41 2498 82
239.5417 +394 925 2497 89
239.5418 +48 120 2496 74
239.5419 +522 956 2495 73
239.5420 +896 685 2494 37
239.5421 +39 738 2493 99
239.5422 +183 98 2492 50
239.5423 +338 589 2491 21
239.5424 +143 194 2490 93
239.5425 +143 407 2489 25
239.5426 +116 925 2488 66
239.5427 +804 157 2487 30
239.5428 +164 4 2486 34
239.5429 +270 359 2485 52
239.5430 +946 379 2484 62
239.5431 +640 488 2483 85
239.5432 +509 294 2482 85
239.5433 +395 282 2481 84
239.5434 +786 681 2480 19
239.5435 +482 583 2479 0
239.5436 +767 357 2478 2
239.5437 +152 963 2477 31
239.5438 +645 818 2476 64
239.5439 +979 900 2475 89
239.5440 +890 769 2474 32
239.5441 +194 0 2473 30
239.5442 +12 11 2472 13
239.5443 +601 650 2471 11
239.5444 +97 195 2470 60
239.5445 +225 973 2469 30
239.5446 +393 714 2468 71
239.5447 +145 672 2467 61
239.5448 +918 746 2466 50
239.5449 +130 570 2465 66
239.5450 +769 16 2464 8
239.5451 +989 176 2463 69
239.5452 +361 16 2462 18
239.5453 +454 505 2461 41
239.5454 +221 303 2460 50
239.5455 +259 590 2459 87
239.5456 +42 98 2458 83
239.5457 +926 108 2457 24
239.5458 +175 841 2456 22
239.5459 +553 576 2455 78
239.5460 +840 392 2454 36
239.5461 +159 515 2453 78
239.5462 +511 770 2452 62
239.5463 +202 907 2451 90
239.5464 +712 631 2450 23
239.5465 +492 40 2449 96
239.5466 +989 583 2448 21
239.5467 +267 21 2447 11
239.5468 +265 439 2446 75
239.5469 +184 425 2445 62
239.5470 +876 581 2444 71
239.5471 +744 152 2443 68
239.5472 +863 721 2442 64
239.5473 +276 672 2441 30
239.5474 +590 271 2440 48
239.5475 +457 745 2439 22
239.5476 +561 100 2438 50
239.5477 +581 365 2437 72
239.5478 +14 128 2436 0
239.5479 +844 908 2435 8
239.5480 +429 31 2434 30
239.5481 +430 33 2433 13
239.5482 +49 339 2432 88
239.5483 +401 819 2431 58
239.5484 +525 269 2430 68
239.5485 +644 717 2429 13
239.5486 +735 780 2428 89
239.5487 +237 720 2427 98
239.5488 +219 919 2426 56
239.5489 +876 774 2425 16
239.5490 +998 174 2424 41
239.5491 +693 251 2423 99
239.5492 +520 293 2422 38
239.5493 +550 901 2421 64
239.5494 +551 551 2420 87
239.5495 +936 238 2419 88
239.5496 +59 914 2418 90
239.5497 +801 412 2417 49
239.5498 +145 397 2416 1
239.5499 +599 754 2415 34
239.5500 +922 416 2414 87
239.5501 +957 617 2413 30
239.5502 +391 733 2412 17
239.5503 +350 772 2411 96
239.5504 +313 994 2410 99
239.5505 +323 972 2409 61
239.5506 +502 411 2408 87
239.5507 +15 480 2407 25
239.5508 +642 674 2406 65
239.5509 +338 465 2405 54
239.5510 +798 572 2404 67
239.5511 +884 131 2403 96
239.5512 +961 203 2402 56
239.5513 +777 971 2401 4
239.5514 +21 383 2400 3
239.5515 +560 737 2399 98
239.5516 +931 618 2398 82
239.5517 +805 602 2397 48
239.5518 +209 110 2396 37
239.5519 +892 868 2395 30
239.5520 +440 711 2394 53
239.5521 +928 399 2393 91
239.5522 +231 524 2392 92
239.5523 +588 4 2391 18
239.5524 +645 47 2390 75
239.5525 +118 168 2389 46
239.5526 +15 334 2388 62
239.5527 +492 114 2387 12
239.5528 +241 67 2386 59
239.5529 +156 765 2385 31
239.5530 +312 625 2384 45
239.5531 +875 990 2383 51
239.5532 +519 740 2382 69
239.5533 +956 427 2381 64
239.5534 +879 294 2380 94
239.5535 +833 831 2379 52
239.5536 +219 504 2378 10
239.5537 +47 529 2377 52
239.5538 +302 278 2376 25
239.5539 +139 865 2375 8
239.5540 +634 938 2374 84
239.5541 +250 816 2373 43
239.5542 +312 53 2372 35
239.5543 +132 699 2371 56
239.5544 +463 416 2370 7
239.5545 +327 423 2369 4
239.5546 +974 579 2368 61
239.5547 +250 271 2367 17
239.5548 +413 166 2366 74
239.5549 +926 239 2365 16
239.5550 +122 408 2364 50
239.5551 +763 81 2363 38
239.5552 +353 792 2362 93
239.5553 +282 485 2361 18
239.5554 +993 32 2360 66
239.5555 +843 431 2359 13
239.5556 +308 441 2358 35
239.5557 +105 427 2357 72
239.5558 +926 581 2356 83
239.5559 +831 658 2355 48
239.5560 +326 120 2354 80
239.5561 +289 446 2353 35
239.5562 +306 757 2352 41
239.5563 +453 511 2351 7
239.5564 +601 532 2350 28
239.5565 +989 784 2349 15
239.5566 +13 628 2348 53
239.5567 +846 887 2347 20
239.5568 +923 350 2346 17
239.5569 +538 681 2345 9
239.5570 +673 445 2344 50
239.5571 +688 948 2343 3
239.5572 +246 339 2342 98
239.5573 +978 780 2341 85
239.5574 +748 139 2340 85
239.5575 +155 614 2339 61
239.5576 +741 332 2338 97
239.5577 +536 24 2337 16
239.5578 +668 83 2336 92
239.5579 +235 589 2335 38
239.5580 +497 467 2334 86
239.5581 +609 54 2333 98
239.5582 +558 129 2332 44
239.5583 +641 1 2331 26
239.5584 +524 240 2330 22
239.5585 +282 635 2329 59
239.5586 +308 808 2328 41
239.5587 +940 244 2327 20
239.5588 +493 538 2326 86
239.5589 +122 520 2325 43
239.5590 +412 878 2324 73
239.5591 +925 544 2323 88
239.5592 +127 173 2322 5
239.5593 +760 38 2321 91
239.5594 +605 637 2320 11
239.5595 +826 178 2319 24
239.5596 +564 210 2318 97
239.5597 +705 336 2317 36
239.5598 +18 435 2316 44
239.5599 +641 693 2315 37
239.5600 +334 850 2314 71
239.5601 +370 837 2313 48
239.5602 +134 133 2312 79
239.5603 +401 800 2311 36
239.5604 +459 874 2310 15
239.5605 +967 268 2309 77
239.5606 +873 605 2308 26
239.5607 +901 921 2307 85
239.5608 +741 75 2306 68
239.5609 +843 661 2305 37
239.5610 +13 223 2304 30
239.5611 +704 688 2303 96
239.5612 +333 431 2302 23
239.5613 +925 211 2301 73
239.5614 +606 375 2300 94
239.5615 +662 518 2299 49
239.5616 +684 401 2298 9
239.5617 +846 172 2297 97
239.5618 +414 310 2296 16
239.5619 +437 70 2295 89
239.5620 +535 343 2294 83
239.5621 +257 727 2293 30
239.5622 +219 502 2292 37
239.5623 +836 791 2291 40
239.5624 +857 451 2290 31
239.5625 +116 396 2289 94
239.5626 +229 122 2288 97
239.5627 +861 812 2287 83
239.5628 +240 262 2286 43
239.5629 +726 67 2285 97
239.5630 +615 521 2284 90
239.5631 +224 937 2283 27
239.5632 +711 962 2282 3
239.5633 +340 89 2281 38
239.5634 +54 374 2280 97
239.5635 +274 965 2279 74
239.5636 +309 140 2278 88
239.5637 +549 405 2277 36
239.5638 +194 455 2276 62
239.5639 +546 74 2275 51
239.5640 +583 624 2274 11
239.5641 +975 239 2273 39
239.5642 +873 655 2272 51
239.5643 +714 403 2271 37
239.5644 +409 238 2270 28
239.5645 +824 854 2269 77
239.5646 +735 519 2268 96
239.5647 +949 745 2267 76
239.5648 +381 108 2266 35
239.5649 +449 402 2265 64
239.5650 +384 720 2264 96
239.5651 +584 877 2263 60
239.5652 +251 142 2262 10
239.5653 +165 84 2261 15
239.5654 +384 506 2260 30
239.5655 +334 814 2259 58
239.5656 +773 204 2258 8
239.5657 +637 404 2257 78
239.5658 +706 706 2256 56
239.5659 +681 685 2255 93
239.5660 +842 353 2254 6
239.5661 +734 507 2253 80
239.5662 +57 942 2252 33
239.5663 +578 854 2251 8
239.5664 +692 720 2250 78
239.5665 +609 494 2249 4
239.5666 +799 304 2248 56
239.5667 +697 217 2247 13
239.5668 +20 635 2246 93
239.5669 +331 867 2245 2
239.5670 +846 264 2244 83
239.5671 +564 467 2243 10
239.5672 +87 247 2242 67
239.5673 +134 303 2241 47
239.5674 +225 732 2240 88
239.5675 +190 487 2239 8
239.5676 +86 425 2238 80
239.5677 +581 205 2237 10
239.5678 +768 906 2236 67
239.5679 +602 185 2235 68
239.5680 +797 730 2234 48
239.5681 +219 430 2233 28
239.5682 +943 197 2232 47
239.5683 +571 593 2231 95
239.5684 +244 803 2230 90
239.5685 +62 272 2229 3
239.5686 +220 707 2228 10
239.5687 +299 424 2227 50
239.5688 +720 987 2226 81
239.5689 +454 203 2225 16
239.5690 +300 203 2224 80
239.5691 +233 804 2223 57
239.5692 +604 523 2222 27
239.5693 +790 44 2221 37
239.5694 +530 873 2220 32
239.5695 +564 932 2219 18
239.5696 +283 597 2218 84
239.5697 +436 692 2217 92
239.5698 +784 646 2216 57
239.5699 +0 360 2215 26
239.5700 +398 227 2214 15
239.5701 +280 301 2213 6
239.5702 +479 903 2212 62
239.5703 +171 46 2211 81
239.5704 +940 143 2210 25
239.5705 +334 340 2209 96
239.5706 +905 921 2208 28
239.5707 +46 341 2207 84
239.5708 +285 313 2206 65
239.5709 +133 111 2205 78
239.5710 +926 87 2204 60
239.5711 +397 438 2203 11
239.5712 +857 814 2202 80
239.5713 +902 554 2201 30
239.5714 +802 294 2200 23
239.5715 +419 684 2199 60
239.5716 +579 435 2198 42
239.5717 +28 193 2197 85
239.5718 +201 869 2196 76
239.5719 +24 181 2195 15
239.5720 +649 483 2194 20
239.5721 +623 316 2193 52
239.5722 +260 493 2192 54
239.5723 +259 77 2191 95
239.5724 +610 623 2190 10
239.5725 +248 177 2189 38
239.5726 +242 570 2188 83
239.5727 +324 97 2187 55
239.5728 +687 608 2186 82
239.5729 +698 945 2185 17
239.5730 +166 678 2184 37
239.5731 +823 988 2183 2
239.5732 +416 585 2182 36
239.5733 +453 854 2181 0
239.5734 +446 717 2180 64
239.5735 +606 543 2179 36
239.5736 +472 288 2178 0
239.5737 +489 724 2177 91
239.5738 +662 649 2176 63
239.5739 +267 802 2175 98
239.5740 +689 349 2174 53
239.5741 +402 663 2173 34
239.5742 +731 361 2172 40
239.5743 +137 351 2171 96
239.5744 +174 288 2170 0
239.5745 +254 355 2169 84
239.5746 +564 87 2168 13
239.5747 +74 281 2167 98
239.5748 +846 647 2166 82
239.5749 +453 457 2165 39
239.5750 +685 188 2164 57
239.5751 +302 936 2163 28
239.5752 +10 444 2162 67
239.5753 +62 956 2161 59
239.5754 +932 166 2160 96
239.5755 +267 706 2159 91
239.5756 +806 150 2158 68
239.5757 +634 156 2157 48
239.5758 +190 432 2156 22
239.5759 +268 817 2155 39
239.5760 +252 290 2154 76
239.5761 +491 615 2153 38
239.5762 +487 77 2152 29
239.5763 +789 630 2151 94
239.5764 +459 43 2150 13
239.5765 +556 229 2149 66
239.5766 +993 200 2148 46
239.5767 +724 261 2147 17
239.5768 +615 835 2146 44
239.5769 +526 625 2145 92
239.5770 +674 384 2144 1
239.5771 +537 91 2143 76
239.5772 +447 344 2142 0
239.5773 +586 817 2141 69
239.5774 +813 464 2140 32
239.5775 +29 203 2139 90
239.5776 +939 289 2138 56
239.5777 +425 728 2137 26
239.5778 +209 522 2136 10
239.5779 +240 904 2135 8
239.5780 +293 256 2134 85
239.5781 +746 756 2133 13
239.5782 +527 305 2132 9
239.5783 +352 368 2131 86
239.5784 +261 426 2130 77
239.5785 +914 341 2129 78
239.5786 +561 292 2128 9
239.5787 +205 160 2127 51
239.5788 +617 20 2126 21
239.5789 +648 236 2125 96
239.5790 +499 714 2124 94
239.5791 +450 47 2123 54
239.5792 +937 229 2122 21
239.5793 +941 87 2121 17
239.5794 +85 988 2120 9
239.5795 +48 693 2119 34
239.5796 +132 577 2118 35
239.5797 +139 297 2117 35
239.5798 +783 246 2116 58
239.5799 +522 21 2115 96
239.5800 +667 401 2114 14
239.5801 +817 328 2113 4
239.5802 +141 42 2112 51
239.5803 +99 84 2111 99
239.5804 +295 744 2110 85
239.5805 +116 993 2109 3
239.5806 +280 997 2108 91
239.5807 +50 767 2107 99
239.5808 +225 619 2106 35
239.5809 +620 820 2105 26
239.5810 +72 99 2104 85
239.5811 +285 536 2103 84
239.5812 +958 517 2102 67
239.5813 +340 139 2101 4
239.5814 +750 820 2100 80
239.5815 +996 120 2099 17
239.5816 +229 923 2098 83
239.5817 +148 636 2097 23
239.5818 +798 94 2096 82
239.5819 +721 406 2095 60
239.5820 +562 5 2094 54
239.5821 +19 173 2093 78
239.5822 +377 634 2092 32
239.5823 +319 238 2091 61
239.5824 +699 624 2090 58
239.5825 +196 343 2089 75
239.5826 +286 605 2088 76
239.5827 +542 405 2087 8
239.5828 +687 218 2086 34
239.5829 +401 58 2085 7
239.5830 +831 759 2084 15
239.5831 +538 460 2083 54
239.5832 +396 708 2082 64
239.5833 +613 28 2081 5
239.5834 +281 836 2080 61
239.5835 +737 987 2079 50
239.5836 +199 685 2078 90
239.5837 +186 731 2077 74
239.5838 +160 272 2076 85
239.5839 +298 919 2075 28
239.5840 +299 615 2074 56
239.5841 +751 901 2073 29
239.5842 +680 582 2072 14
239.5843 +192 439 2071 78
239.5844 +849 116 2070 33
239.5845 +301 593 2069 54
239.5846 +953 165 2068 53
239.5847 +459 889 2067 1
239.5848 +353 569 2066 2
239.5849 +303 715 2065 86
239.5850 +714 276 2064 99
239.5851 +318 150 2063 54
239.5852 +143 359 2062 7
239.5853 +323 450 2061 48
239.5854 +522 787 2060 34
239.5855 +428 6 2059 54
239.5856 +275 524 2058 34
239.5857 +319 986 2057 49
239.5858 +853 164 2056 10
239.5859 +438 863 2055 4
239.5860 +126 451 2054 58
239.5861 +790 476 2053 39
239.5862 +908 583 2052 17
239.5863 +662 145 2051 82
239.5864 +781 796 2050 80
239.5865 +481 198 2049 9
239.5866 +538 854 2048 15
239.5867 +822 387 2047 95
239.5868 +301 56 2046 46
239.5869 +411 460 2045 41
239.5870 +975 193 2044 31
239.5871 +893 221 2043 33
239.5872 +437 354 2042 88
239.5873 +349 19 2041 24
239.5874 +597 705 2040 88
239.5875 +343 942 2039 30
239.5876 +466 196 2038 94
239.5877 +330 489 2037 71
239.5878 +596 51 2036 52
239.5879 +266 101 2035 88
239.5880 +972 977 2034 43
239.5881 +866 453 2033 8
239.5882 +334 635 2032 45
239.5883 +314 365 2031 8
239.5884 +762 580 2030 75
239.5885 +746 356 2029 25
239.5886 +706 227 2028 87
239.5887 +438 195 2027 13
239.5888 +949 631 2026 73
239.5889 +124 453 2025 33
239.5890 +524 353 2024 29
239.5891 +817 626 2023 10
239.5892 +270 367 2022 53
239.5893 +784 336 2021 2
239.5894 +224 498 2020 55
239.5895 +129 376 2019 1
239.5896 +32 740 2018 4
239.5897 +563 402 2017 26
239.5898 +178 403 2016 48
239.5899 +99 35 2015 82
239.5900 +727 188 2014 59
239.5901 +259 573 2013 70
239.5902 +30 511 2012 54
239.5903 +838 469 2011 48
239.5904 +121 535 2010 55
239.5905 +635 975 2009 9
239.5906 +338 773 2008 9
239.5907 +998 777 2007 46
239.5908 +367 664 2006 38
239.5909 +847 225 2005 7
239.5910 +614 892 2004 37
239.5911 +62 160 2003 46
239.5912 +42 60 2002 22
239.5913 +934 926 2001 19
239.5914 +559 465 2000 71
239.5915 +202 997 1999 48
239.5916 +995 629 1998 29
239.5917 +113 82 1997 34
239.5918 +438 306 1996 63
239.5919 +333 707 1995 52
239.5920 +731 904 1994 23
239.5921 +99 238 1993 55
239.5922 +133 36 1992 1
239.5923 +461 476 1991 10
239.5924 +467 230 1990 37
239.5925 +368 188 1989 35
239.5926 +546 957 1988 20
239.5927 +776 709 1987 88
239.5928 +599 110 1986 67
239.5929 +802 287 1985 10
239.5930 +666 679 1984 60
239.5931 +201 533 1983 63
239.5932 +560 910 1982 96
239.5933 +245 733 1981 67
239.5934 +42 17 1980 99
239.5935 +231 150 1979 9
239.5936 +247 324 1978 82
239.5937 +599 207 1977 77
239.5938 +822 569 1976 17
239.5939 +607 503 1975 79
239.5940 +146 969 1974 13
239.5941 +622 666 1973 46
239.5942 +177 293 1972 64
239.5943 +715 678 1971 31
239.5944 +867 894 1970 20
239.5945 +825 277 1969 81
239.5946 +117 51 1968 98
239.5947 +637 593 1967 64
239.5948 +66 379 1966 77
239.5949 +533 661 1965 21
239.5950 +303 670 1964 46
239.5951 +372 823 1963 52
239.5952 +615 326 1962 44
239.5953 +783 111 1961 46
239.5954 +617 392 1960 84
239.5955 +225 827 1959 4
239.5956 +458 335 1958 70
239.5957 +213 870 1957 48
239.5958 +718 562 1956 57
239.5959 +990 753 1955 53
239.5960 +847 937 1954 23
239.5961 +497 79 1953 93
239.5962 +214 983 1952 75
239.5963 +718 613 1951 83
239.5964 +564 805 1950 16
239.5965 +492 335 1949 39
239.5966 +464 227 1948 76
239.5967 +308 909 1947 24
239.5968 +809 38 1946 49
239.5969 +816 302 1945 72
239.5970 +858 298 1944 14
239.5971 +95 173 1943 35
239.5972 +370 925 1942 28
239.5973 +807 665 1941 49
239.5974 +470 773 1940 15
239.5975 +108 625 1939 7
239.5976 +317 521 1938 2
239.5977 +871 750 1937 15
239.5978 +735 766 1936 49
239.5979 +3 585 1935 99
239.5980 +124 792 1934 95
239.5981 +248 68 1933 76
239.5982 +259 786 1932 72
239.5983 +891 342 1931 56
239.5984 +148 81 1930 33
239.5985 +104 44 1929 36
239.5986 +770 871 1928 79
239.5987 +984 657 1927 44
239.5988 +181 504 1926 13
239.5989 +792 35 1925 73
239.5990 +724 195 1924 87
239.5991 +281 38 1923 87
239.5992 +444 161 1922 98
239.5993 +260 225 1921 36
239.5994 +36 974 1920 74
239.5995 +172 571 1919 4
239.5996 +214 344 1918 33
239.5997 +153 310 1917 78
239.5998 +468 403 1916 80
239.5999 +840 853 1915 38
239.6000 +156 2 1914 6
239.6001 +876 887 1913 44
239.6002 +935 620 1912 83
239.6003 +250 624 1911 18
239.6004 +403 699 1910 22
239.6005 +227 709 1909 86
239.6006 +33 548 1908 95
239.6007 +907 982 1907 6
239.6008 +550 413 1906 68
239.6009 +850 321 1905 62
239.6010 +114 624 1904 68
239.6011 +267 605 1903 27
239.6012 +996 654 1902 94
239.6013 +924 959 1901 68
239.6014 +990 360 1900 84
239.6015 +161 905 1899 17
239.6016 +565 897 1898 19
239.6017 +568 376 1897 12
239.6018 +92 56 1896 35
239.6019 +697 943 1895 69
239.6020 +19 404 1894 73
239.6021 +950 338 1893 84
239.6022 +695 256 1892 27
239.6023 +598 837 1891 7
239.6024 +454 672 1890 93
239.6025 +7 980 1889 82
239.6026 +520 68 1888 59
239.6027 +320 769 1887 99
239.6028 +112 657 1886 47
239.6029 +539 962 1885 39
239.6030 +65 889 1884 67
239.6031 +82 577 1883 6
239.6032 +418 197 1882 25
239.6033 +164 138 1881 9
239.6034 +691 104 1880 14
239.6035 +912 233 1879 44
239.6036 +299 598 1878 48
239.6037 +111 520 1877 20
239.6038 +694 82 1876 20
239.6039 +73 716 1875 57
239.6040 +312 609 1874 47
239.6041 +379 814 1873 98
239.6042 +58 157 1872 66
239.6043 +34 952 1871 25
239.6044 +871 697 1870 47
239.6045 +635 959 1869 77
239.6046 +77 286 1868 61
239.6047 +438 993 1867 18
239.6048 +365 634 1866 41
239.6049 +106 99 1865 62
239.6050 +794 490 1864 76
239.6051 +656 319 1863 93
239.6052 +205 409 1862 32
239.6053 +254 780 1861 2
239.6054 +738 694 1860 16
239.6055 +673 165 1859 23
239.6056 +293 425 1858 55
239.6057 +358 770 1857 63
239.6058 +534 796 1856 7
239.6059 +608 859 1855 25
239.6060 +171 829 1854 31
239.6061 +909 610 1853 13
239.6062 +629 297 1852 45
239.6063 +86 861 1851 95
239.6064 +528 927 1850 51
239.6065 +740 677 1849 6
239.6066 +655 918 1848 38
239.6067 +973 566 1847 93
239.6068 +936 813 1846 82
239.6069 +30 946 1845 92
239.6070 +218 174 1844 43
239.6071 +313 686 1843 26
239.6072 +435 500 1842 28
239.6073 +933 434 1841 54
239.6074 +249 451 1840 55
239.6075 +759 684 1839 78
239.6076 +351 446 1838 8
239.6077 +753 110 1837 68
239.6078 +866 897 1836 3
239.6079 +772 488 1835 90
239.6080 +487 175 1834 81
239.6081 +186 982 1833 90
239.6082 +65 737 1832 87
239.6083 +983 984 1831 50
239.6084 +766 769 1830 68
239.6085 +238 704 1829 49
239.6086 +335 402 1828 40
239.6087 +212 644 1827 59
239.6088 +408 131 1826 88
239.6089 +313 93 1825 9
239.6090 +193 908 1824 28
239.6091 +244 26 1823 30
239.6092 +752 376 1822 12
239.6093 +215 817 1821 8
239.6094 +65 194 1820 21
239.6095 +302 82 1819 52
239.6096 +757 809 1818 90
239.6097 +513 711 1817 12
239.6098 +37 793 1816 80
239.6099 +185 808 1815 9
239.6100 +882 985 1814 12
239.6101 +649 179 1813 94
239.6102 +558 39 1812 49
239.6103 +623 864 1811 53
239.6104 +111 689 1810 14
239.6105 +272 624 1809 76
239.6106 +98 780 1808 54
239.6107 +917 318 1807 24
239.6108 +985 708 1806 47
239.6109 +822 974 1805 85
239.6110 +806 172 1804 30
239.6111 +139 455 1803 23
239.6112 +175 955 1802 9
239.6113 +174 387 1801 93
239.6114 +65 386 1800 51
239.6115 +844 218 1799 83
239.6116 +461 301 1798 17
239.6117 +610 767 1797 18
239.6118 +733 623 1796 93
239.6119 +802 549 1795 16
239.6120 +716 70 1794 1
239.6121 +499 141 1793 66
239.6122 +568 155 1792 96
239.6123 +1 423 1791 0
239.6124 +167 672 1790 10
239.6125 +916 665 1789 22
239.6126 +534 992 1788 38
239.6127 +144 248 1787 85
239.6128 +73 770 1786 87
239.6129 +479 145 1785 93
239.6130 +929 350 1784 8
239.6131 +985 701 1783 21
239.6132 +732 963 1782 93
239.6133 +751 891 1781 56
239.6134 +7 888 1780 83
239.6135 +672 837 1779 25
239.6136 +744 531 1778 38
239.6137 +477 975 1777 38
239.6138 +625 944 1776 7
239.6139 +794 845 1775 59
239.6140 +648 868 1774 54
239.6141 +738 286 1773 94
239.6142 +72 363 1772 25
239.6143 +2 733 1771 98
239.6144 +50 583 1770 74
239.6145 +306 867 1769 33
239.6146 +556 993 1768 92
239.6147 +30 318 1767 26
239.6148 +99 477 1766 85
239.6149 +976 43 1765 83
239.6150 +582 605 1764 14
239.6151 +922 691 1763 91
239.6152 +629 272 1762 66
239.6153 +150 236 1761 7
239.6154 +715 409 1760 95
239.6155 +874 406 1759 74
239.6156 +674 660 1758 74
239.6157 +841 415 1757 52
239.6158 +433 21 1756 93
239.6159 +438 684 1755 12
239.6160 +914 235 1754 39
239.6161 +419 244 1753 65
239.6162 +35 595 1752 29
239.6163 +826 118 1751 47
239.6164 +2 206 1750 43
239.6165 +746 995 1749 84
239.6166 +245 223 1748 20
239.6167 +393 595 1747 83
239.6168 +336 807 1746 40
239.6169 +449 728 1745 99
239.6170 +990 734 1744 52
239.6171 +649 366 1743 49
239.6172 +476 813 1742 38
239.6173 +912 44 1741 20
239.6174 +211 594 1740 82
239.6175 +771 640 1739 25
239.6176 +628 366 1738 50
239.6177 +787 425 1737 85
239.6178 +78 412 1736 5
239.6179 +994 470 1735 88
239.6180 +368 29 1734 45
239.6181 +552 111 1733 34
239.6182 +769 173 1732 17
239.6183 +449 385 1731 56
239.6184 +954 567 1730 70
239.6185 +273 755 1729 43
239.6186 +941 649 1728 14
239.6187 +12 793 1727 84
239.6188 +942 170 1726 70
239.6189 +441 428 1725 8
239.6190 +917 117 1724 62
239.6191 +937 167 1723 81
239.6192 +788 609 1722 78
239.6193 +818 863 1721 32
239.6194 +811 261 1720 49
239.6195 +105 296 1719 68
239.6196 +855 301 1718 33
239.6197 +623 132 1717 92
239.6198 +742 624 1716 7
239.6199 +310 457 1715 50
239.6200 +950 811 1714 52
239.6201 +558 32 1713 97
239.6202 +746 462 1712 14
239.6203 +601 825 1711 96
239.6204 +964 814 1710 0
239.6205 +994 348 1709 70
239.6206 +168 403 1708 25
239.6207 +508 858 1707 23
239.6208 +166 569 1706 88
239.6209 +646 976 1705 43
239.6210 +779 544 1704 35
239.6211 +569 829 1703 39
239.6212 +637 180 1702 81
239.6213 +10 962 1701 14
239.6214 +466 301 1700 63
239.6215 +944 455 1699 96
239.6216 +544 17 1698 82
239.6217 +289 351 1697 66
239.6218 +592 448 1696 34
239.6219 +432 72 1695 51
239.6220 +715 967 1694 86
239.6221 +649 579 1693 21
239.6222 +218 667 1692 93
239.6223 +660 507 1691 62
239.6224 +845 666 1690 54
239.6225 +438 143 1689 52
239.6226 +665 166 1688 40
239.6227 +903 317 1687 25
239.6228 +376 823 1686 69
239.6229 +104 651 1685 16
239.6230 +388 657 1684 71
239.6231 +912 279 1683 6
239.6232 +159 303 1682 43
239.6233 +840 82 1681 55
239.6234 +522 23 1680 81
239.6235 +977 121 1679 40
239.6236 +848 144 1678 77
239.6237 +493 558 1677 76
239.6238 +171 536 1676 52
239.6239 +994 443 1675 27
239.6240 +378 651 1674 71
239.6241 +975 635 1673 47
239.6242 +220 872 1672 75
239.6243 +59 742 1671 31
239.6244 +901 407 1670 31
239.6245 +976 634 1669 54
239.6246 +586 10 1668 12
239.6247 +22 234 1667 35
239.6248 +93 255 1666 32
239.6249 +792 555 1665 17
239.6250 +15 240 1664 61
239.6251 +762 723 1663 40
239.6252 +130 433 1662 75
239.6253 +335 0 1661 16
239.6254 +772 772 1660 15
239.6255 +623 415 1659 92
239.6256 +776 774 1658 39
239.6257 +979 32 1657 56
239.6258 +699 145 1656 92
239.6259 +315 561 1655 30
239.6260 +516 212 1654 77
239.6261 +290 648 1653 25
239.6262 +432 593 1652 63
239.6263 +227 2 1651 79
239.6264 +356 233 1650 56
239.6265 +641 534 1649 14
239.6266 +742 826 1648 84
239.6267 +887 634 1647 79
239.6268 +584 628 1646 28
239.6269 +348 524 1645 38
239.6270 +563 523 1644 79
239.6271 +55 620 1643 22
239.6272 +590 838 1642 85
239.6273 +769 231 1641 20
239.6274 +698 414 1640 87
239.6275 +707 300 1639 71
239.6276 +191 51 1638 89
239.6277 +6 516 1637 85
239.6278 +103 896 1636 30
239.6279 +1 585 1635 23
239.6280 +902 572 1634 78
239.6281 +782 368 1633 50
239.6282 +606 653 1632 46
239.6283 +816 333 1631 82
239.6284 +113 155 1630 7
239.6285 +249 815 1629 99
239.6286 +534 44 1628 51
239.6287 +620 551 1627 18
239.6288 +310 67 1626 90
239.6289 +12 451 1625 10
239.6290 +204 276 1624 9
239.6291 +714 42 1623 11
239.6292 +320 644 1622 17
239.6293 +177 750 1621 79
239.6294 +339 79 1620 70
239.6295 +771 475 1619 86
239.6296 +492 330 1618 71
239.6297 +484 282 1617 91
239.6298 +616 800 1616 30
239.6299 +174 3 1615 29
239.6300 +233 979 1614 80
239.6301 +398 943 1613 49
239.6302 +894 385 1612 39
239.6303 +670 87 1611 14
239.6304 +603 839 1610 83
239.6305 +145 148 1609 56
239.6306 +48 800 1608 27
239.6307 +481 605 1607 0
239.6308 +797 10 1606 86
239.6309 +24 491 1605 44
239.6310 +35 317 1604 94
239.6311 +558 95 1603 83
239.6312 +298 252 1602 50
239.6313 +247 304 1601 22
239.6314 +690 268 1600 6
239.6315 +348 290 1599 45
239.6316 +195 269 1598 9
239.6317 +594 140 1597 56
239.6318 +519 426 1596 68
239.6319 +174 499 1595 77
239.6320 +221 106 1594 98
239.6321 +843 330 1593 47
239.6322 +947 280 1592 25
239.6323 +35 157 1591 5
239.6324 +978 607 1590 55
239.6325 +21 361 1589 34
239.6326 +129 529 1588 15
239.6327 +713 883 1587 60
239.6328 +926 910 1586 7
239.6329 +393 784 1585 34
239.6330 +776 511 1584 95
239.6331 +50 217 1583 37
239.6332 +123 209 1582 89
239.6333 +549 493 1581 91
239.6334 +245 214 1580 5
239.6335 +832 189 1579 95
239.6336 +646 551 1578 89
239.6337 +972 526 1577 41
239.6338 +126 729 1576 78
239.6339 +273 392 1575 53
239.6340 +294 574 1574 61
239.6341 +7 482 1573 72
239.6342 +715 982 1572 92
239.6343 +278 855 1571 57
239.6344 +25 100 1570 30
239.6345 +637 65 1569 41
239.6346 +25 476 1568 18
239.6347 +796 628 1567 67
239.6348 +336 253 1566 84
239.6349 +818 916 1565 85
239.6350 +91 891 1564 97
239.6351 +499 798 1563 28
239.6352 +127 353 1562 29
239.6353 +754 270 1561 43
239.6354 +35 889 1560 25
239.6355 +589 227 1559 38
239.6356 +847 511 1558 61
239.6357 +375 828 1557 22
239.6358 +336 992 1556 45
239.6359 +24 874 1555 51
239.6360 +93 693 1554 72
239.6361 +444 994 1553 59
239.6362 +82 854 1552 37
239.6363 +380 184 1551 37
239.6364 +662 864 1550 71
239.6365 +715 775 1549 44
239.6366 +683 383 1548 74
239.6367 +835 768 1547 47
239.6368 +118 941 1546 3
239.6369 +181 792 1545 31
239.6370 +698 134 1544 93
239.6371 +139 220 1543 64
239.6372 +669 999 1542 36
239.6373 +319 653 1541 70
239.6374 +88 273 1540 71
239.6375 +392 703 1539 94
239.6376 +614 270 1538 3
239.6377 +827 432 1537 84
239.6378 +148 727 1536 71
239.6379 +658 380 1535 93
239.6380 +914 282 1534 48
239.6381 +221 286 1533 55
239.6382 +345 659 1532 46
239.6383 +379 983 1531 35
239.6384 +570 771 1530 23
239.6385 +432 915 1529 69
239.6386 +838 182 1528 77
239.6387 +705 132 1527 78
239.6388 +346 778 1526 67
239.6389 +97 455 1525 48
239.6390 +995 922 1524 74
239.6391 +627 89 1523 69
239.6392 +676 119 1522 87
239.6393 +211 119 1521 96
239.6394 +856 534 1520 80
239.6395 +732 919 1519 13
239.6396 +50 990 1518 59
239.6397 +353 107 1517 13
239.6398 +323 189 1516 35
239.6399 +533 745 1515 24
239.6400 +832 51 1514 10
239.6401 +970 817 1513 36
239.6402 +0 908 1512 95
239.6403 +584 157 1511 46
239.6404 +615 671 1510 35
239.6405 +928 542 1509 12
239.6406 +882 461 1508 68
239.6407 +918 774 1507 69
239.6408 +444 109 1506 3
239.6409 +693 147 1505 79
239.6410 +233 733 1504 70
239.6411 +908 417 1503 86
239.6412 +751 486 1502 96
239.6413 +485 109 1501 41
239.6414 +129 230 1500 96
239.6415 +81 442 1499 68
239.6416 +686 984 1498 4
239.6417 +665 666 1497 96
239.6418 +961 240 1496 47
239.6419 +414 89 1495 75
239.6420 +315 838 1494 45
239.6421 +931 892 1493 32
239.6422 +376 554 1492 15
239.6423 +879 445 1491 26
239.6424 +788 282 1490 35
239.6425 +457 640 1489 4
239.6426 +318 81 1488 39
239.6427 +425 490 1487 2
239.6428 +150 723 1486 70
239.6429 +251 291 1485 54
239.6430 +945 134 1484 9
239.6431 +338 167 1483 38
239.6432 +108 891 1482 55
239.6433 +163 909 1481 49
239.6434 +642 308 1480 9
239.6435 +558 653 1479 33
239.6436 +591 373 1478 13
239.6437 +767 316 1477 89
239.6438 +432 156 1476 27
239.6439 +156 449 1475 89
239.6440 +967 713 1474 30
239.6441 +276 829 1473 60
239.6442 +981 58 1472 22
239.6443 +601 405 1471 94
239.6444 +654 760 1470 52
239.6445 +279 191 1469 8
239.6446 +56 246 1468 96
239.6447 +160 617 1467 82
239.6448 +706 375 1466 33
239.6449 +735 593 1465 27
239.6450 +884 698 1464 18
239.6451 +770 377 1463 69
239.6452 +652 284 1462 29
239.6453 +644 424 1461 38
239.6454 +568 437 1460 94
239.6455 +945 115 1459 37
239.6456 +628 143 1458 22
239.6457 +241 489 1457 89
239.6458 +782 58 1456 45
239.6459 +894 86 1455 97
239.6460 +320 498 1454 85
239.6461 +93 396 1453 11
239.6462 +859 914 1452 11
239.6463 +986 433 1451 0
239.6464 +321 571 1450 7
239.6465 +972 151 1449 62
239.6466 +653 327 1448 31
239.6467 +430 441 1447 38
239.6468 +972 482 1446 45
239.6469 +588 120 1445 88
239.6470 +102 736 1444 57
239.6471 +481 996 1443 22
239.6472 +480 109 1442 23
239.6473 +862 931 1441 87
239.6474 +419 453 1440 66
239.6475 +824 306 1439 34
239.6476 +885 930 1438 31
239.6477 +959 927 1437 22
239.6478 +362 571 1436 45
239.6479 +384 313 1435 38
239.6480 +739 347 1434 48
239.6481 +886 993 1433 62
239.6482 +178 360 1432 0
239.6483 +478 207 1431 61
239.6484 +147 316 1430 44
239.6485 +375 29 1429 59
239.6486 +2 96 1428 93
239.6487 +356 764 1427 92
239.6488 +257 74 1426 59
239.6489 +966 897 1425 97
239.6490 +354 865 1424 64
239.6491 +632 619 1423 85
239.6492 +153 382 1422 70
239.6493 +891 175 1421 69
239.6494 +286 846 1420 33
239.6495 +933 657 1419 77
239.6496 +332 11 1418 37
239.6497 +689 329 1417 64
239.6498 +176 618 1416 9
239.6499 +32 333 1415 29
239.6500 +245 791 1414 61
239.6501 +237 144 1413 72
239.6502 +207 9 1412 47
239.6503 +328 368 1411 26
239.6504 +189 559 1410 60
239.6505 +645 397 1409 35
239.6506 +681 727 1408 60
239.6507 +711 547 1407 64
239.6508 +285 807 1406 51
239.6509 +542 679 1405 14
239.6510 +647 890 1404 78
239.6511 +135 242 1403 0
239.6512 +640 217 1402 2
239.6513 +809 656 1401 87
239.6514 +161 251 1400 13
239.6515 +669 752 1399 54
239.6516 +180 958 1398 96
239.6517 +740 129 1397 97
239.6518 +127 368 1396 42
239.6519 +789 357 1395 74
239.6520 +647 778 1394 89
239.6521 +25 978 1393 51
239.6522 +560 151 1392 49
239.6523 +404 739 1391 83
239.6524 +499 594 1390 64
239.6525 +793 580 1389 49
239.6526 +829 993 1388 48
239.6527 +761 544 1387 44
239.6528 +10 682 1386 61
239.6529 +579 848 1385 33
239.6530 +799 382 1384 14
239.6531 +827 17 1383 62
239.6532 +411 663 1382 46
239.6533 +145 184 1381 15
239.6534 +14 154 1380 90
239.6535 +587 3 1379 70
239.6536 +448 48 1378 96
239.6537 +862 828 1377 6
239.6538 +834 274 1376 75
239.6539 +466 195 1375 43
239.6540 +364 520 1374 78
239.6541 +354 156 1373 97
239.6542 +479 308 1372 41
239.6543 +29 251 1371 26
239.6544 +151 198 1370 13
239.6545 +954 742 1369 42
239.6546 +220 895 1368 13
239.6547 +554 317 1367 58
239.6548 +78 319 1366 2
239.6549 +674 650 1365 36
239.6550 +364 808 1364 10
239.6551 +848 555 1363 0
239.6552 +56 149 1362 87
239.6553 +53 135 1361 44
239.6554 +455 703 1360 87
239.6555 +846 287 1359 19
239.6556 +578 552 1358 73
239.6557 +997 558 1357 66
239.6558 +669 659 1356 47
239.6559 +842 266 1355 40
239.6560 +252 91 1354 31
239.6561 +405 134 1353 51
239.6562 +14 425 1352 79
239.6563 +431 572 1351 0
239.6564 +415 680 1350 59
239.6565 +735 462 1349 60
239.6566 +994 68 1348 26
239.6567 +898 190 1347 58
239.6568 +393 72 1346 32
239.6569 +174 92 1345 82
239.6570 +957 794 1344 58
239.6571 +708 724 1343 84
239.6572 +853 787 1342 39
239.6573 +891 405 1341 58
239.6574 +217 989 1340 1
239.6575 +393 340 1339 68
239.6576 +878 687 1338 74
239.6577 +118 252 1337 9
239.6578 +979 501 1336 50
239.6579 +297 237 1335 21
239.6580 +69 742 1334 21
239.6581 +936 456 1333 24
239.6582 +382 808 1332 85
239.6583 +416 566 1331 96
239.6584 +648 335 1330 67
239.6585 +653 940 1329 82
239.6586 +435 644 1328 51
239.6587 +750 591 1327 76
239.6588 +264 285 1326 13
239.6589 +495 2 1325 68
239.6590 +285 968 1324 22
239.6591 +647 393 1323 13
239.6592 +242 893 1322 55
239.6593 +230 287 1321 96
239.6594 +395 849 1320 76
239.6595 +296 308 1319 99
239.6596 +52 755 1318 21
239.6597 +305 621 1317 68
239.6598 +283 456 1316 48
239.6599 +34 453 1315 76
239.6600 +574 94 1314 20
239.6601 +500 578 1313 63
239.6602 +605 587 1312 40
239.6603 +438 198 1311 1
239.6604 +541 772 1310 83
239.6605 +553 777 1309 9
239.6606 +133 533 1308 24
239.6607 +164 198 1307 74
239.6608 +3 716 1306 2
239.6609 +358 560 1305 24
239.6610 +515 570 1304 45
239.6611 +991 233 1303 7
239.6612 +388 393 1302 89
239.6613 +426 176 1301 16
239.6614 +995 736 1300 89
239.6615 +243 856 1299 98
239.6616 +334 495 1298 42
239.6617 +482 724 1297 96
239.6618 +156 773 1296 16
239.6619 +989 789 1295 64
239.6620 +337 386 1294 84
239.6621 +840 178 1293 52
239.6622 +216 728 1292 60
239.6623 +440 270 1291 96
239.6624 +880 909 1290 43
239.6625 +360 566 1289 75
239.6626 +771 451 1288 90
239.6627 +950 807 1287 85
239.6628 +984 517 1286 32
239.6629 +403 801 1285 16
239.6630 +207 318 1284 65
239.6631 +450 922 1283 49
239.6632 +458 639 1282 62
239.6633 +360 531 1281 77
239.6634 +342 679 1280 56
239.6635 +115 842 1279 51
239.6636 +644 57 1278 58
239.6637 +290 526 1277 82
239.6638 +715 158 1276 96
239.6639 +483 515 1275 58
239.6640 +395 155 1274 19
239.6641 +282 873 1273 75
239.6642 +108 847 1272 99
239.6643 +851 216 1271 9
239.6644 +837 40 1270 1
239.6645 +784 931 1269 22
239.6646 +531 768 1268 47
239.6647 +367 853 1267 35
239.6648 +643 385 1266 57
239.6649 +359 385 1265 23
239.6650 +282 437 1264 8
239.6651 +26 765 1263 11
239.6652 +630 894 1262 17
239.6653 +176 79 1261 25
239.6654 +109 790 1260 1
239.6655 +162 757 1259 5
239.6656 +914 115 1258 25
239.6657 +468 780 1257 16
239.6658 +999 342 1256 72
239.6659 +947 143 1255 28
239.6660 +672 975 1254 7
239.6661 +871 939 1253 25
239.6662 +814 916 1252 39
239.6663 +289 243 1251 45
239.6664 +32 961 1250 6
239.6665 +642 798 1249 94
239.6666 +335 90 1248 24
239.6667 +437 439 1247 44
239.6668 +198 440 1246 46
239.6669 +168 205 1245 5
239.6670 +35 822 1244 27
239.6671 +22 860 1243 80
239.6672 +673 940 1242 5
239.6673 +281 387 1241 52
239.6674 +162 119 1240 25
239.6675 +708 698 1239 39
239.6676 +650 802 1238 30
239.6677 +998 977 1237 89
239.6678 +235 417 1236 23
239.6679 +383 776 1235 3
239.6680 +961 474 1234 13
239.6681 +919 744 1233 1
239.6682 +552 530 1232 34
239.6683 +268 268 1231 39
239.6684 +421 866 1230 11
239.6685 +896 83 1229 45
239.6686 +824 408 1228 5
239.6687 +560 659 1227 65
239.6688 +641 208 1226 76
239.6689 +301 897 1225 85
239.6690 +729 120 1224 42
239.6691 +213 663 1223 4
239.6692 +262 958 1222 36
239.6693 +402 272 1221 28
239.6694 +782 664 1220 84
239.6695 +674 396 1219 52
239.6696 +749 405 1218 7
239.6697 +451 889 1217 26
239.6698 +311 911 1216 91
239.6699 +776 430 1215 33
239.6700 +457 379 1214 57
239.6701 +704 675 1213 51
239.6702 +685 81 1212 95
239.6703 +608 438 1211 86
239.6704 +267 321 1210 61
239.6705 +991 453 1209 10
239.6706 +515 806 1208 92
239.6707 +978 345 1207 29
239.6708 +480 579 1206 14
239.6709 +51 768 1205 53
239.6710 +703 55 1204 31
239.6711 +594 564 1203 75
239.6712 +643 91 1202 1
239.6713 +116 240 1201 7
239.6714 +868 512 1200 34
239.6715 +646 182 1199 27
239.6716 +461 627 1198 47
239.6717 +765 158 1197 53
239.6718 +811 605 1196 49
239.6719 +712 214 1195 42
239.6720 +491 567 1194 34
239.6721 +472 733 1193 10
239.6722 +850 942 1192 95
239.6723 +728 735 1191 52
239.6724 +329 65 1190 24
239.6725 +554 799 1189 22
239.6726 +469 938 1188 18
239.6727 +552 39 1187 69
239.6728 +391 69 1186 95
239.6729 +647 80 1185 9
239.6730 +834 239 1184 22
239.6731 +790 157 1183 1
239.6732 +206 423 1182 62
239.6733 +669 278 1181 12
239.6734 +266 25 1180 39
239.6735 +860 37 1179 77
239.6736 +898 489 1178 8
239.6737 +970 741 1177 91
239.6738 +988 855 1176 16
239.6739 +840 878 1175 74
239.6740 +81 201 1174 81
239.6741 +733 396 1173 4
239.6742 +145 499 1172 58
239.6743 +253 723 1171 53
239.6744 +988 623 1170 40
239.6745 +548 689 1169 40
239.6746 +748 169 1168 96
239.6747 +886 755 1167 92
239.6748 +976 416 1166 98
239.6749 +676 931 1165 14
239.6750 +805 769 1164 75
239.6751 +897 458 1163 34
239.6752 +776 48 1162 58
239.6753 +99 133 1161 89
239.6754 +934 997 1160 26
239.6755 +520 443 1159 44
239.6756 +413 34 1158 79
239.6757 +339 946 1157 86
239.6758 +485 833 1156 90
239.6759 +161 389 1155 29
239.6760 +310 410 1154 87
239.6761 +410 758 1153 90
239.6762 +914 696 1152 12
239.6763 +135 627 1151 67
239.6764 +553 824 1150 16
239.6765 +409 640 1149 41
239.6766 +87 937 1148 10
239.6767 +113 952 1147 7
239.6768 +443 610 1146 85
239.6769 +979 428 1145 32
239.6770 +651 963 1144 85
239.6771 +62 787 1143 90
239.6772 +69 444 1142 49
239.6773 +803 511 1141 77
239.6774 +183 750 1140 58
239.6775 +702 307 1139 14
239.6776 +985 32 1138 32
239.6777 +342 220 1137 97
239.6778 +182 530 1136 67
239.6779 +464 472 1135 46
239.6780 +176 950 1134 32
239.6781 +342 404 1133 58
239.6782 +933 717 1132 99
239.6783 +760 196 1131 26
239.6784 +442 437 1130 62
239.6785 +275 822 1129 48
239.6786 +811 347 1128 71
239.6787 +689 304 1127 64
239.6788 +58 205 1126 16
239.6789 +521 136 1125 71
239.6790 +546 737 1124 28
239.6791 +687 596 1123 83
239.6792 +520 727 1122 40
239.6793 +758 645 1121 17
239.6794 +615 139 1120 31
239.6795 +474 763 1119 16
239.6796 +43 73 1118 46
239.6797 +98 483 1117 12
239.6798 +69 442 1116 63
239.6799 +399 429 1115 53
239.6800 +141 455 1114 97
239.6801 +868 423 1113 85
239.6802 +82 236 1112 16
239.6803 +506 855 1111 76
239.6804 +375 150 1110 14
239.6805 +690 702 1109 14
239.6806 +590 342 1108 43
239.6807 +40 491 1107 94
239.6808 +13 93 1106 2
239.6809 +974 562 1105 66
239.6810 +31 115 1104 25
239.6811 +186 692 1103 27
239.6812 +380 405 1102 78
239.6813 +705 618 1101 57
239.6814 +447 1 1100 13
239.6815 +360 711 1099 68
239.6816 +851 484 1098 9
239.6817 +397 916 1097 55
239.6818 +530 359 1096 2
239.6819 +446 411 1095 3
239.6820 +423 986 1094 94
239.6821 +287 485 1093 84
239.6822 +786 210 1092 80
239.6823 +617 445 1091 67
239.6824 +290 445 1090 25
239.6825 +226 585 1089 8
239.6826 +567 549 1088 50
239.6827 +557 523 1087 45
239.6828 +948 987 1086 86
239.6829 +424 97 1085 8
239.6830 +500 97 1084 2
239.6831 +274 38 1083 13
239.6832 +765 131 1082 50
239.6833 +999 416 1081 16
239.6834 +859 170 1080 32
239.6835 +36 578 1079 6
239.6836 +25 55 1078 65
239.6837 +536 586 1077 1
239.6838 +890 782 1076 60
239.6839 +999 60 1075 52
239.6840 +59 887 1074 92
239.6841 +906 634 1073 22
239.6842 +715 332 1072 50
239.6843 +245 841 1071 76
239.6844 +592 263 1070 13
239.6845 +522 404 1069 82
239.6846 +469 648 1068 1
239.6847 +803 401 1067 48
239.6848 +721 85 1066 64
239.6849 +173 599 1065 89
239.6850 +253 697 1064 93
239.6851 +302 717 1063 15
239.6852 +490 742 1062 19
239.6853 +577 626 1061 46
239.6854 +858 316 1060 65
239.6855 +756 812 1059 7
239.6856 +246 521 1058 5
239.6857 +315 843 1057 66
239.6858 +486 755 1056 8
239.6859 +901 950 1055 54
239.6860 +979 787 1054 91
239.6861 +975 961 1053 95
239.6862 +115 722 1052 81
239.6863 +309 816 1051 91
239.6864 +504 581 1050 71
239.6865 +290 18 1049 10
239.6866 +678 386 1048 51
239.6867 +87 584 1047 93
239.6868 +804 533 1046 82
239.6869 +163 628 1045 58
239.6870 +825 968 1044 92
239.6871 +239 139 1043 0
239.6872 +905 899 1042 86
239.6873 +234 193 1041 80
239.6874 +563 616 1040 80
239.6875 +632 591 1039 21
239.6876 +802 579 1038 61
239.6877 +50 101 1037 59
239.6878 +904 243 1036 28
239.6879 +659 663 1035 64
239.6880 +829 917 1034 33
239.6881 +240 143 1033 58
239.6882 +705 54 1032 33
239.6883 +576 0 1031 67
239.6884 +25 590 1030 67
239.6885 +11 602 1029 93
239.6886 +477 21 1028 82
239.6887 +857 307 1027 75
239.6888 +580 642 1026 14
239.6889 +745 302 1025 24
239.6890 +774 751 1024 83
239.6891 +89 252 1023 58
239.6892 +53 663 1022 53
239.6893 +410 999 1021 12
239.6894 +988 739 1020 55
239.6895 +580 101 1019 1
239.6896 +714 78 1018 53
239.6897 +664 604 1017 61
239.6898 +339 902 1016 27
239.6899 +550 414 1015 83
239.6900 +499 240 1014 97
239.6901 +589 54 1013 68
239.6902 +663 406 1012 3
239.6903 +260 577 1011 64
239.6904 +637 538 1010 42
239.6905 +23 479 1009 40
239.6906 +473 914 1008 86
239.6907 +702 342 1007 5
239.6908 +487 442 1006 32
239.6909 +173 863 1005 78
239.6910 +185 285 1004 5
239.6911 +648 649 1003 91
239.6912 +829 392 1002 92
239.6913 +39 221 1001 40
239.6914 +58 13 1000 62
239.6915 +565 542 999 61
239.6916 +571 815 998 54
239.6917 +899 725 997 77
239.6918 +578 535 996 21
239.6919 +578 738 995 31
239.6920 +636 141 994 98
239.6921 +257 984 993 53
239.6922 +170 522 992 81
239.6923 +207 781 991 78
239.6924 +471 7 990 98
239.6925 +726 64 989 49
239.6926 +89 778 988 99
239.6927 +190 556 987 67
239.6928 +797 900 986 32
239.6929 +596 326 985 0
239.6930 +156 450 984 94
239.6931 +461 718 983 37
239.6932 +741 29 982 8
239.6933 +773 809 981 96
239.6934 +942 486 980 73
239.6935 +286 499 979 74
239.6936 +221 321 978 63
239.6937 +656 351 977 89
239.6938 +573 320 976 39
239.6939 +876 59 975 20
239.6940 +731 562 974 44
239.6941 +688 292 973 69
239.6942 +220 123 972 72
239.6943 +322 226 971 96
239.6944 +986 991 970 83
239.6945 +178 107 969 65
239.6946 +970 737 968 6
239.6947 +30 506 967 56
239.6948 +261 192 966 8
239.6949 +496 760 965 69
239.6950 +270 745 964 14
239.6951 +168 974 963 4
239.6952 +896 752 962 46
239.6953 +235 136 961 89
239.6954 +883 174 960 33
239.6955 +369 590 959 80
239.6956 +231 501 958 20
239.6957 +313 480 957 93
239.6958 +432 387 956 76
239.6959 +15 551 955 76
239.6960 +770 101 954 22
239.6961 +221 574 953 10
239.6962 +615 571 952 27
239.6963 +962 561 951 66
239.6964 +584 527 950 35
239.6965 +89 600 949 51
239.6966 +20 268 948 13
239.6967 +93 169 947 91
239.6968 +835 4 946 88
239.6969 +450 539 945 41
239.6970 +526 122 944 24
239.6971 +3 831 943 54
239.6972 +9 609 942 60
239.6973 +34 309 941 65
239.6974 +926 837 940 37
239.6975 +331 375 939 49
239.6976 +98 221 938 6
239.6977 +164 35 937 92
239.6978 +465 464 936 25
239.6979 +416 173 935 38
239.6980 +291 695 934 92
239.6981 +221 943 933 52
239.6982 +299 951 932 99
239.6983 +472 276 931 97
239.6984 +461 882 930 10
239.6985 +154 426 929 59
239.6986 +185 142 928 23
239.6987 +571 668 927 93
239.6988 +291 873 926 69
239.6989 +477 461 925 4
239.6990 +751 401 924 12
239.6991 +991 528 923 6
239.6992 +675 19 922 92
239.6993 +393 867 921 82
239.6994 +455 512 920 1
239.6995 +284 361 919 30
239.6996 +474 298 918 96
239.6997 +794 235 917 61
239.6998 +412 650 916 28
239.6999 +59 923 915 81
239.7000 +873 55 914 72
239.7001 +508 148 913 75
239.7002 +152 94 912 31
239.7003 +354 816 911 28
239.7004 +151 703 910 93
239.7005 +63 338 909 17
239.7006 +63 355 908 81
239.7007 +584 333 907 67
239.7008 +727 467 906 38
239.7009 +867 86 905 35
239.7010 +907 966 904 18
239.7011 +53 443 903 36
239.7012 +277 34 902 35
239.7013 +113 343 901 79
239.7014 +364 766 900 20
239.7015 +983 361 899 8
239.7016 +22 130 898 99
239.7017 +865 296 897 47
239.7018 +380 29 896 85
239.7019 +119 165 895 85
239.7020 +523 821 894 96
239.7021 +409 8 893 85
239.7022 +690 557 892 77
239.7023 +576 595 891 16
239.7024 +405 115 890 74
239.7025 +230 88 889 38
239.7026 +834 520 888 96
239.7027 +266 622 887 15
239.7028 +864 997 886 48
239.7029 +344 898 885 26
239.7030 +812 106 884 59
239.7031 +451 78 883 11
239.7032 +962 611 882 71
239.7033 +479 415 881 11
239.7034 +27 367 880 17
239.7035 +567 420 879 17
239.7036 +898 804 878 39
239.7037 +624 670 877 56
239.7038 +99 224 876 40
239.7039 +791 664 875 51
239.7040 +28 482 874 53
239.7041 +466 395 873 36
239.7042 +195 603 872 48
239.7043 +48 943 871 48
239.7044 +946 995 870 45
239.7045 +616 779 869 45
239.7046 +133 828 868 66
239.7047 +446 164 867 27
239.7048 +559 883 866 52
239.7049 +182 988 865 30
239.7050 +86 169 864 76
239.7051 +791 872 863 56
239.7052 +660 5 862 27
239.7053 +948 30 861 14
239.7054 +215 992 860 10
239.7055 +950 790 859 33
239.7056 +664 394 858 48
239.7057 +281 749 857 68
239.7058 +894 217 856 88
239.7059 +818 544 855 37
239.7060 +296 201 854 9
239.7061 +866 290 853 29
239.7062 +975 123 852 13
239.7063 +37 45 851 71
239.7064 +202 771 850 73
239.7065 +395 847 849 26
239.7066 +645 795 848 28
239.7067 +532 800 847 38
239.7068 +672 508 846 38
239.7069 +343 282 845 7
239.7070 +910 800 844 52
239.7071 +167 163 843 42
239.7072 +78 418 842 89
239.7073 +273 979 841 93
239.7074 +924 467 840 83
239.7075 +52 978 839 80
239.7076 +995 903 838 75
239.7077 +291 995 837 11
239.7078 +226 311 836 85
239.7079 +482 553 835 32
239.7080 +636 92 834 43
239.7081 +744 538 833 74
239.7082 +439 953 832 8
239.7083 +511 102 831 80
239.7084 +489 28 830 34
239.7085 +74 56 829 87
239.7086 +907 636 828 5
239.7087 +684 253 827 70
239.7088 +758 530 826 6
239.7089 +460 896 825 74
239.7090 +554 690 824 84
239.7091 +584 654 823 89
239.7092 +851 284 822 30
239.7093 +73 454 821 92
239.7094 +972 477 820 2
239.7095 +419 814 819 41
239.7096 +383 352 818 16
239.7097 +723 638 817 22
239.7098 +633 320 816 92
239.7099 +205 898 815 29
239.7100 +35 953 814 90
239.7101 +369 586 813 96
239.7102 +829 378 812 73
239.7103 +976 904 811 77
239.7104 +662 607 810 10
239.7105 +462 248 809 55
239.7106 +714 943 808 3
239.7107 +318 297 807 65
239.7108 +421 627 806 8
239.7109 +945 391 805 42
239.7110 +366 936 804 17
239.7111 +208 236 803 66
239.7112 +473 955 802 54
239.7113 +297 675 801 85
239.7114 +358 548 800 31
239.7115 +305 516 799 20
239.7116 +645 377 798 74
239.7117 +669 569 797 39
239.7118 +236 661 796 89
239.7119 +455 257 795 47
239.7120 +699 504 794 57
239.7121 +280 125 793 15
239.7122 +280 687 792 73
239.7123 +126 538 791 17
239.7124 +32 113 790 93
239.7125 +138 452 789 5
239.7126 +808 351 788 65
239.7127 +907 500 787 97
239.7128 +404 419 786 43
239.7129 +753 897 785 78
239.7130 +378 420 784 75
239.7131 +437 423 783 41
239.7132 +149 559 782 0
239.7133 +425 236 781 15
239.7134 +660 885 780 9
239.7135 +101 394 779 89
239.7136 +851 683 778 33
239.7137 +80 542 777 90
239.7138 +522 653 776 50
239.7139 +477 24 775 65
239.7140 +996 336 774 37
239.7141 +864 418 773 94
239.7142 +322 847 772 28
239.7143 +350 59 771 72
239.7144 +491 200 770 76
239.7145 +710 563 769 55
239.7146 +141 429 768 24
239.7147 +889 397 767 77
239.7148 +628 852 766 55
239.7149 +688 276 765 4
239.7150 +917 433 764 48
239.7151 +571 652 763 13
239.7152 +787 564 762 54
239.7153 +859 958 761 97
239.7154 +636 205 760 85
239.7155 +133 309 759 78
239.7156 +32 477 758 56
239.7157 +545 213 757 25
239.7158 +576 513 756 26
239.7159 +843 563 755 93
239.7160 +780 348 754 77
239.7161 +88 590 753 34
239.7162 +605 569 752 78
239.7163 +752 112 751 92
239.7164 +895 79 750 22
239.7165 +832 210 749 50
239.7166 +264 317 748 10
239.7167 +699 991 747 48
239.7168 +949 321 746 96
239.7169 +215 169 745 73
239.7170 +758 424 744 6
239.7171 +21 561 743 69
239.7172 +457 855 742 48
239.7173 +33 706 741 85
239.7174 +868 718 740 85
239.7175 +893 401 739 6
239.7176 +326 614 738 56
239.7177 +669 517 737 56
239.7178 +152 236 736 75
239.7179 +744 669 735 73
239.7180 +862 370 734 45
239.7181 +706 209 733 73
239.7182 +149 629 732 56
239.7183 +987 995 731 42
239.7184 +316 793 730 16
239.7185 +787 496 729 97
239.7186 +97 2 728 56
239.7187 +280 815 727 65
239.7188 +566 15 726 51
239.7189 +299 277 725 40
239.7190 +161 719 724 88
239.7191 +580 173 723 15
239.7192 +633 140 722 55
239.7193 +202 259 721 16
239.7194 +296 189 720 67
239.7195 +494 408 719 52
239.7196 +186 910 718 68
239.7197 +799 138 717 81
239.7198 +737 110 716 71
239.7199 +558 526 715 26
239.7200 +546 725 714 13
239.7201 +33 598 713 58
239.7202 +880 395 712 94
239.7203 +69 490 711 43
239.7204 +780 140 710 90
239.7205 +498 840 709 80
239.7206 +771 872 708 30
239.7207 +28 102 707 38
239.7208 +584 446 706 6
239.7209 +800 129 705 17
239.7210 +126 557 704 1
239.7211 +202 634 703 51
239.7212 +905 515 702 15
239.7213 +350 526 701 81
239.7214 +300 102 700 28
239.7215 +967 495 699 28
239.7216 +770 920 698 72
239.7217 +655 325 697 74
239.7218 +316 882 696 44
239.7219 +572 166 695 78
239.7220 +922 499 694 67
239.7221 +119 360 693 92
239.7222 +989 341 692 29
239.7223 +423 521 691 55
239.7224 +607 6 690 4
239.7225 +575 556 689 33
239.7226 +594 983 688 19
239.7227 +442 298 687 11
239.7228 +716 660 686 33
239.7229 +667 109 685 74
239.7230 +138 750 684 65
239.7231 +18 626 683 80
239.7232 +819 742 682 13
239.7233 +515 504 681 56
239.7234 +449 717 680 81
239.7235 +572 135 679 3
239.7236 +684 82 678 98
239.7237 +637 775 677 15
239.7238 +551 594 676 72
239.7239 +358 94 675 4
239.7240 +124 846 674 52
239.7241 +883 673 673 11
239.7242 +237 564 672 19
239.7243 +787 749 671 30
239.7244 +581 783 670 6
239.7245 +52 51 669 87
239.7246 +306 827 668 88
239.7247 +180 426 667 4
239.7248 +500 677 666 8
239.7249 +247 519 665 19
239.7250 +173 409 664 23
239.7251 +108 920 663 24
239.7252 +814 895 662 64
239.7253 +965 238 661 45
239.7254 +731 188 660 20
239.7255 +224 989 659 52
239.7256 +401 840 658 74
239.7257 +748 961 657 12
239.7258 +158 893 656 68
239.7259 +110 958 655 25
239.7260 +488 993 654 7
239.7261 +25 595 653 6
239.7262 +656 195 652 29
239.7263 +49 244 651 84
239.7264 +199 677 650 23
239.7265 +148 782 649 50
239.7266 +879 620 648 82
239.7267 +67 445 647 65
239.7268 +935 426 646 59
239.7269 +964 179 645 4
239.7270 +398 9 644 62
239.7271 +400 770 643 46
239.7272 +951 445 642 36
239.7273 +566 614 641 60
239.7274 +894 726 640 84
239.7275 +162 684 639 5
239.7276 +174 170 638 26
239.7277 +18 61 637 81
239.7278 +247 543 636 13
239.7279 +169 425 635 97
239.7280 +238 158 634 56
239.7281 +325 94 633 99
239.7282 +830 761 632 44
239.7283 +888 757 631 38
239.7284 +41 798 630 67
239.7285 +514 783 629 73
239.7286 +108 456 628 98
239.7287 +518 679 627 15
239.7288 +117 161 626 77
239.7289 +267 405 625 7
239.7290 +63 567 624 93
239.7291 +333 549 623 91
239.7292 +3 64 622 49
239.7293 +959 712 621 94
239.7294 +15 939 620 84
239.7295 +326 743 619 52
239.7296 +776 833 618 40
239.7297 +518 384 617 59
239.7298 +756 693 616 40
239.7299 +837 147 615 84
239.7300 +18 17 614 20
239.7301 +484 417 613 72
239.7302 +351 554 612 33
239.7303 +772 93 611 4
239.7304 +196 320 610 94
239.7305 +910 120 609 68
239.7306 +449 815 608 55
239.7307 +690 188 607 25
239.7308 +546 551 606 76
239.7309 +129 645 605 91
239.7310 +599 474 604 81
239.7311 +863 399 603 53
239.7312 +460 286 602 13
239.7313 +773 100 601 57
239.7314 +199 255 600 57
239.7315 +304 138 599 28
239.7316 +627 292 598 46
239.7317 +637 495 597 75
239.7318 +906 843 596 14
239.7319 +170 100 595 41
239.7320 +75 285 594 52
239.7321 +112 400 593 73
239.7322 +185 553 592 40
239.7323 +845 2 591 68
239.7324 +116 291 590 57
239.7325 +845 823 589 89
239.7326 +796 703 588 67
239.7327 +652 613 587 99
239.7328 +742 727 586 73
239.7329 +815 886 585 73
239.7330 +884 794 584 9
239.7331 +846 332 583 96
239.7332 +551 716 582 92
239.7333 +711 114 581 33
239.7334 +467 678 580 72
239.7335 +120 217 579 27
239.7336 +89 687 578 4
239.7337 +886 259 577 14
239.7338 +841 995 576 90
239.7339 +92 640 575 92
239.7340 +462 132 574 93
239.7341 +615 35 573 3
239.7342 +602 587 572 29
239.7343 +436 611 571 83
239.7344 +460 457 570 24
239.7345 +529 222 569 34
239.7346 +428 904 568 3
239.7347 +263 234 567 20
239.7348 +355 981 566 4
239.7349 +507 997 565 74
239.7350 +97 892 564 63
239.7351 +447 742 563 84
239.7352 +976 455 562 1
239.7353 +153 595 561 16
239.7354 +234 896 560 97
239.7355 +318 316 559 93
239.7356 +670 827 558 10
239.7357 +252 158 557 16
239.7358 +984 296 556 90
239.7359 +104 118 555 84
239.7360 +150 784 554 41
239.7361 +287 832 553 65
239.7362 +859 848 552 47
239.7363 +699 190 551 82
239.7364 +579 44 550 91
239.7365 +489 829 549 91
239.7366 +668 936 548 64
239.7367 +862 256 547 41
239.7368 +178 60 546 26
239.7369 +333 437 545 88
239.7370 +952 759 544 95
239.7371 +984 180 543 86
239.7372 +657 647 542 42
239.7373 +146 903 541 16
239.7374 +214 3 540 11
239.7375 +892 268 539 9
239.7376 +680 230 538 82
239.7377 +196 149 537 80
239.7378 +622 387 536 68
239.7379 +678 926 535 84
239.7380 +579 91 534 38
239.7381 +532 435 533 96
239.7382 +744 267 532 32
239.7383 +900 40 531 51
239.7384 +735 29 530 93
239.7385 +37 269 529 32
239.7386 +80 14 528 21
239.7387 +762 122 527 48
239.7388 +460 839 526 57
239.7389 +835 462 525 94
239.7390 +656 413 524 9
239.7391 +167 641 523 4
239.7392 +226 815 522 78
239.7393 +11 580 521 84
239.7394 +759 609 520 16
239.7395 +254 109 519 69
239.7396 +892 728 518 95
239.7397 +283 909 517 31
239.7398 +376 630 516 30
239.7399 +48 845 515 62
239.7400 +772 52 514 17
239.7401 +825 258 513 48
239.7402 +235 944 512 94
239.7403 +970 678 511 21
239.7404 +500 467 510 25
239.7405 +380 741 509 50
239.7406 +819 638 508 36
239.7407 +279 15 507 60
239.7408 +785 676 506 90
239.7409 +792 446 505 32
239.7410 +793 690 504 27
239.7411 +313 547 503 94
239.7412 +265 725 502 59
239.7413 +211 963 501 26
239.7414 +726 746 500 47
239.7415 +102 143 499 11
239.7416 +622 752 498 56
239.7417 +339 702 497 54
239.7418 +229 578 496 49
239.7419 +756 51 495 99
239.7420 +142 329 494 99
239.7421 +821 356 493 48
239.7422 +762 326 492 4
239.7423 +216 793 491 5
239.7424 +603 351 490 48
239.7425 +390 558 489 62
239.7426 +50 20 488 47
239.7427 +123 46 487 28
239.7428 +527 501 486 10
239.7429 +722 993 485 47
239.7430 +973 519 484 61
239.7431 +30 432 483 32
239.7432 +532 993 482 5
239.7433 +442 568 481 54
239.7434 +792 861 480 61
239.7435 +537 144 479 21
239.7436 +974 195 478 34
239.7437 +544 174 477 92
239.7438 +508 635 476 59
239.7439 +474 860 475 80
239.7440 +86 292 474 74
239.7441 +438 261 473 94
239.7442 +424 512 472 49
239.7443 +706 933 471 8
239.7444 +717 399 470 65
239.7445 +948 873 469 25
239.7446 +20 413 468 56
239.7447 +539 329 467 42
239.7448 +774 792 466 3
239.7449 +568 55 465 3
239.7450 +30 806 464 38
239.7451 +748 445 463 64
239.7452 +579 408 462 1
239.7453 +533 439 461 71
239.7454 +526 395 460 98
239.7455 +459 691 459 76
239.7456 +84 133 458 92
239.7457 +537 393 457 48
239.7458 +736 2 456 76
239.7459 +249 646 455 20
239.7460 +360 739 454 53
239.7461 +36 633 453 28
239.7462 +969 296 452 16
239.7463 +43 728 451 4
239.7464 +703 220 450 0
239.7465 +558 840 449 6
239.7466 +740 446 448 37
239.7467 +390 716 447 54
239.7468 +355 558 446 80
239.7469 +907 668 445 48
239.7470 +106 256 444 88
239.7471 +337 112 443 32
239.7472 +568 122 442 6
239.7473 +507 40 441 92
239.7474 +379 938 440 34
239.7475 +393 692 439 14
239.7476 +730 827 438 81
239.7477 +157 747 437 34
239.7478 +890 312 436 3
239.7479 +411 599 435 44
239.7480 +144 564 434 80
239.7481 +989 256 433 76
239.7482 +82 142 432 76
239.7483 +101 584 431 6
239.7484 +246 194 430 12
239.7485 +864 327 429 98
239.7486 +80 468 428 66
239.7487 +434 314 427 57
239.7488 +713 587 426 26
239.7489 +35 647 425 47
239.7490 +307 31 424 26
239.7491 +114 0 423 15
239.7492 +557 708 422 90
239.7493 +390 932 421 98
239.7494 +867 141 420 85
239.7495 +859 322 419 38
239.7496 +154 90 418 78
239.7497 +726 305 417 64
239.7498 +939 788 416 72
239.7499 +615 211 415 67
239.7500 +31 112 414 72
239.7501 +291 247 413 19
239.7502 +775 925 412 55
239.7503 +790 126 411 16
239.7504 +819 473 410 52
239.7505 +232 597 409 0
239.7506 +784 138 408 70
239.7507 +517 924 407 42
239.7508 +576 43 406 78
239.7509 +99 950 405 32
239.7510 +864 533 404 58
239.7511 +322 636 403 74
239.7512 +798 389 402 51
239.7513 +653 644 401 98
239.7514 +875 514 400 97
239.7515 +458 302 399 58
239.7516 +214 278 398 44
239.7517 +880 640 397 26
239.7518 +92 463 396 94
239.7519 +417 739 395 47
239.7520 +897 844 394 23
239.7521 +246 224 393 54
239.7522 +745 530 392 52
239.7523 +129 13 391 14
239.7524 +212 385 390 77
239.7525 +24 138 389 41
239.7526 +637 182 388 24
239.7527 +176 325 387 33
239.7528 +723 464 386 78
239.7529 +895 241 385 67
239.7530 +619 693 384 52
239.7531 +694 17 383 65
239.7532 +517 378 382 50
239.7533 +627 367 381 61
239.7534 +247 360 380 91
239.7535 +956 174 379 18
239.7536 +856 909 378 38
239.7537 +860 545 377 46
239.7538 +222 112 376 45
239.7539 +547 155 375 82
239.7540 +675 870 374 27
239.7541 +639 148 373 92
239.7542 +11 886 372 17
239.7543 +6 698 371 88
239.7544 +186 729 370 38
239.7545 +264 801 369 29
239.7546 +363 925 368 9
239.7547 +432 8 367 99
239.7548 +957 624 366 63
239.7549 +285 552 365 67
239.7550 +721 350 364 87
239.7551 +261 748 363 3
239.7552 +188 287 362 62
239.7553 +968 508 361 0
239.7554 +928 89 360 82
239.7555 +875 191 359 92
239.7556 +916 103 358 90
239.7557 +384 358 357 93
239.7558 +71 962 356 47
239.7559 +202 803 355 67
239.7560 +601 835 354 56
239.7561 +461 408 353 45
239.7562 +778 622 352 7
239.7563 +419 183 351 21
239.7564 +897 899 350 3
239.7565 +88 20 349 5
239.7566 +745 970 348 95
239.7567 +395 455 347 53
239.7568 +159 802 346 31
239.7569 +967 109 345 86
239.7570 +426 103 344 60
239.7571 +786 386 343 14
239.7572 +438 853 342 68
239.7573 +284 180 341 35
239.7574 +879 986 340 52
239.7575 +50 94 339 80
239.7576 +514 426 338 34
239.7577 +653 219 337 34
239.7578 +693 444 336 23
239.7579 +5 268 335 19
239.7580 +717 460 334 54
239.7581 +532 457 333 64
239.7582 +673 323 332 34
239.7583 +193 837 331 15
239.7584 +892 711 330 40
239.7585 +667 465 329 82
239.7586 +207 994 328 53
239.7587 +775 112 327 86
239.7588 +175 44 326 95
239.7589 +808 650 325 68
239.7590 +2 900 324 28
239.7591 +133 293 323 18
239.7592 +485 192 322 85
239.7593 +126 749 321 48
239.7594 +246 576 320 30
239.7595 +471 292 319 22
239.7596 +881 674 318 46
239.7597 +68 901 317 43
239.7598 +394 272 316 59
239.7599 +749 398 315 36
239.7600 +607 104 314 80
239.7601 +100 325 313 86
239.7602 +443 378 312 64
239.7603 +172 178 311 35
239.7604 +284 76 310 88
239.7605 +617 763 309 77
239.7606 +773 28 308 59
239.7607 +629 832 307 81
239.7608 +873 232 306 67
239.7609 +294 561 305 64
239.7610 +778 936 304 14
239.7611 +947 221 303 50
239.7612 +199 287 302 65
239.7613 +102 479 301 27
239.7614 +312 105 300 88
239.7615 +735 184 299 66
239.7616 +195 777 298 84
239.7617 +599 139 297 14
239.7618 +671 29 296 75
239.7619 +624 502 295 57
239.7620 +714 635 294 51
239.7621 +934 849 293 83
239.7622 +807 387 292 74
239.7623 +374 381 291 9
239.7624 +921 221 290 78
239.7625 +406 822 289 57
239.7626 +638 700 288 53
239.7627 +109 387 287 59
239.7628 +527 177 286 92
239.7629 +867 62 285 4
239.7630 +785 684 284 91
239.7631 +461 84 283 78
239.7632 +5 649 282 12
239.7633 +160 308 281 43
239.7634 +399 211 280 45
239.7635 +122 38 279 51
239.7636 +312 943 278 76
239.7637 +210 668 277 52
239.7638 +114 880 276 58
239.7639 +377 136 275 65
239.7640 +600 129 274 8
239.7641 +434 654 273 32
239.7642 +341 692 272 45
239.7643 +96 981 271 84
239.7644 +173 937 270 76
239.7645 +95 746 269 27
239.7646 +274 239 268 80
239.7647 +787 946 267 10
239.7648 +743 922 266 9
239.7649 +6 578 265 73
239.7650 +475 757 264 77
239.7651 +961 867 263 16
239.7652 +711 611 262 9
239.7653 +43 84 261 24
239.7654 +190 483 260 92
239.7655 +507 467 259 7
239.7656 +292 708 258 82
239.7657 +23 5 257 48
239.7658 +343 359 256 4
239.7659 +821 958 255 73
239.7660 +889 611 254 53
239.7661 +256 73 253 51
239.7662 +526 848 252 25
239.7663 +600 321 251 66
239.7664 +16 845 250 85
239.7665 +759 258 249 68
239.7666 +703 332 248 21
239.7667 +645 443 247 26
239.7668 +400 307 246 67
239.7669 +347 205 245 52
239.7670 +538 16 244 93
239.7671 +225 264 243 63
239.7672 +526 582 242 72
239.7673 +476 815 241 92
239.7674 +587 168 240 58
239.7675 +925 469 239 25
239.7676 +889 945 238 5
239.7677 +136 589 237 5
239.7678 +101 157 236 24
239.7679 +189 591 235 5
239.7680 +752 297 234 80
239.7681 +681 904 233 31
239.7682 +766 803 232 69
239.7683 +646 341 231 5
239.7684 +699 327 230 88
239.7685 +523 200 229 66
239.7686 +356 997 228 3
239.7687 +431 813 227 75
239.7688 +566 190 226 3
239.7689 +293 244 225 91
239.7690 +393 496 224 43
239.7691 +100 614 223 7
239.7692 +461 648 222 91
239.7693 +13 160 221 11
239.7694 +126 227 220 94
239.7695 +202 626 219 17
239.7696 +184 282 218 16
239.7697 +623 718 217 92
239.7698 +946 122 216 86
239.7699 +747 475 215 27
239.7700 +882 366 214 89
239.7701 +965 155 213 29
239.7702 +487 795 212 63
239.7703 +933 173 211 44
239.7704 +601 770 210 88
239.7705 +343 9 209 92
239.7706 +563 242 208 1
239.7707 +596 58 207 56
239.7708 +646 592 206 67
239.7709 +109 373 205 19
239.7710 +210 606 204 86
239.7711 +360 653 203 91
239.7712 +622 191 202 47
239.7713 +402 560 201 55
239.7714 +761 963 200 33
239.7715 +766 904 199 25
239.7716 +183 458 198 78
239.7717 +466 884 197 96
239.7718 +219 477 196 94
239.7719 +767 333 195 53
239.7720 +952 948 194 89
239.7721 +462 438 193 85
239.7722 +630 923 192 73
239.7723 +597 222 191 21
239.7724 +58 74 190 64
239.7725 +446 477 189 99
239.7726 +573 812 188 58
239.7727 +406 17 187 71
239.7728 +143 413 186 24
239.7729 +384 637 185 45
239.7730 +510 48 184 81
239.7731 +515 112 183 48
239.7732 +700 518 182 83
239.7733 +148 579 181 3
239.7734 +596 645 180 53
239.7735 +664 412 179 61
239.7736 +795 865 178 87
239.7737 +604 470 177 16
239.7738 +775 794 176 26
239.7739 +589 637 175 75
239.7740 +935 324 174 87
239.7741 +594 657 173 99
239.7742 +939 799 172 81
239.7743 +933 494 171 55
239.7744 +233 926 170 55
239.7745 +547 738 169 93
239.7746 +394 706 168 86
239.7747 +675 904 167 19
239.7748 +157 503 166 82
239.7749 +313 885 165 18
239.7750 +667 879 164 65
239.7751 +857 181 163 34
239.7752 +305 261 162 65
239.7753 +567 1 161 0
239.7754 +187 618 160 70
239.7755 +32 63 159 68
239.7756 +801 677 158 15
239.7757 +400 362 157 71
239.7758 +618 642 156 51
239.7759 +6 532 155 84
239.7760 +697 311 154 64
239.7761 +919 685 153 80
239.7762 +260 649 152 55
239.7763 +382 305 151 73
239.7764 +555 14 150 38
239.7765 +385 532 149 15
239.7766 +315 434 148 23
239.7767 +719 200 147 40
239.7768 +109 674 146 78
239.7769 +221 198 145 61
239.7770 +625 836 144 30
239.7771 +36 257 143 77
239.7772 +344 814 142 65
239.7773 +290 357 141 87
239.7774 +481 225 140 82
239.7775 +98 923 139 16
239.7776 +233 829 138 7
239.7777 +525 618 137 59
239.7778 +476 169 136 60
239.7779 +361 304 135 88
239.7780 +578 529 134 59
239.7781 +442 119 133 58
239.7782 +457 780 132 69
239.7783 +131 51 131 5
239.7784 +301 657 130 80
239.7785 +93 99 129 38
239.7786 +210 473 128 86
239.7787 +449 986 127 70
239.7788 +865 721 126 4
239.7789 +774 293 125 11
239.7790 +410 5 124 78
239.7791 +338 897 123 13
239.7792 +729 638 122 98
239.7793 +394 244 121 32
239.7794 +557 426 120 82
239.7795 +625 517 119 20
239.7796 +487 157 118 88
239.7797 +265 658 117 76
239.7798 +427 934 116 58
239.7799 +288 331 115 9
239.7800 +107 647 114 36
239.7801 +258 151 113 7
239.7802 +394 658 112 60
239.7803 +818 496 111 33
239.7804 +908 622 110 83
239.7805 +360 324 109 93
239.7806 +498 121 108 13
239.7807 +724 178 107 22
239.7808 +603 492 106 83
239.7809 +684 727 105 13
239.7810 +495 291 104 18
239.7811 +492 463 103 84
239.7812 +162 273 102 86
239.7813 +873 498 101 57
239.7814 +297 904 100 90
239.7815 +203 793 99 54
239.7816 +943 916 98 86
239.7817 +685 383 97 77
239.7818 +764 699 96 12
239.7819 +436 958 95 91
239.7820 +827 331 94 18
239.7821 +189 984 93 0
239.7822 +775 288 92 32
239.7823 +593 666 91 28
239.7824 +111 361 90 57
239.7825 +877 686 89 9
239.7826 +532 87 88 26
239.7827 +684 653 87 25
239.7828 +740 202 86 92
239.7829 +627 730 85 32
239.7830 +347 184 84 60
239.7831 +695 673 83 63
239.7832 +621 40 82 41
239.7833 +304 712 81 18
239.7834 +675 482 80 48
239.7835 +598 833 79 23
239.7836 +434 3 78 34
239.7837 +450 336 77 84
239.7838 +471 592 76 94
239.7839 +546 719 75 11
239.7840 +510 971 74 28
239.7841 +633 223 73 65
239.7842 +328 231 72 7
239.7843 +229 700 71 31
239.7844 +649 248 70 62
239.7845 +830 888 69 7
239.7846 +666 497 68 16
239.7847 +743 903 67 98
239.7848 +873 831 66 97
239.7849 +747 833 65 92
239.7850 +747 628 64 3
239.7851 +992 576 63 87
239.7852 +530 757 62 30
239.7853 +452 687 61 9
239.7854 +359 552 60 57
239.7855 +391 913 59 81
239.7856 +593 180 58 16
239.7857 +72 4 57 92
239.7858 +997 54 56 87
239.7859 +204 889 55 12
239.7860 +51 157 54 99
239.7861 +819 573 53 75
239.7862 +69 204 52 46
239.7863 +134 520 51 7
239.7864 +639 759 50 9
239.7865 +732 656 49 96
239.7866 +176 240 48 79
239.7867 +950 52 47 52
239.7868 +164 745 46 7
239.7869 +732 125 45 79
239.7870 +584 244 44 15
239.7871 +368 294 43 23
239.7872 +684 383 42 74
239.7873 +760 984 41 93
239.7874 +103 126 40 49
239.7875 +416 169 39 90
239.7876 +187 276 38 55
239.7877 +307 447 37 22
239.7878 +619 281 36 78
239.7879 +881 641 35 43
239.7880 +950 920 34 14
239.7881 +910 482 33 21
239.7882 +398 814 32 68
239.7883 +858 439 31 92
239.7884 +956 588 30 65
239.7885 +893 350 29 68
239.7886 +829 330 28 22
239.7887 +165 440 27 88
239.7888 +639 354 26 68
239.7889 +720 284 25 73
239.7890 +437 931 24 93
239.7891 +667 531 23 3
239.7892 +375 760 22 51
239.7893 +850 266 21 53
239.7894 +238 970 20 90
239.7895 +20 457 19 6
239.7896 +890 348 18 6
239.7897 +86 192 17 66
239.7898 +69 949 16 52
239.7899 +352 807 15 91
239.7900 +400 891 14 28
239.7901 +771 526 13 76
239.7902 +493 972 12 29
239.7903 +296 637 11 52
239.7904 +512 839 10 61
239.7905 +108 998 9 21
239.7906 +156 400 8 12
239.7907 +242 137 7 80
239.7908 +141 606 6 1
239.7909 +916 635 5 71
239.7910 +364 513 4 95
239.7911 +553 477 3 62
239.7912 +335 768 2 27
239.7913 +798 911 1 19
239.7914 +840 394 0 78
239.7915 +@nodes
239.7916 +source 252
239.7917 +@end
240.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
240.2 +++ b/test/error_test.cc Mon May 23 04:48:14 2005 +0000
240.3 @@ -0,0 +1,65 @@
240.4 +/* -*- C++ -*-
240.5 + * test/error_test.cc - Part of LEMON, a generic C++ optimization library
240.6 + *
240.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
240.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
240.9 + *
240.10 + * Permission to use, modify and distribute this software is granted
240.11 + * provided that this copyright notice appears in all copies. For
240.12 + * precise terms see the accompanying LICENSE file.
240.13 + *
240.14 + * This software is provided "AS IS" with no warranty of any kind,
240.15 + * express or implied, and with no claim as to its suitability for any
240.16 + * purpose.
240.17 + *
240.18 + */
240.19 +
240.20 +#include <iostream>
240.21 +
240.22 +#include <lemon/error.h>
240.23 +#include "test_tools.h"
240.24 +using namespace lemon;
240.25 +using std::cout;
240.26 +using std::endl;
240.27 +
240.28 +void faulty_fn() {
240.29 + fault("This is a fault message");
240.30 +}
240.31 +
240.32 +void exception_fn() {
240.33 + throw Exception("This is a fn throwing excpt with some args: ")
240.34 + << 5 << ", " << 18;
240.35 +}
240.36 +
240.37 +void unfinished_fn() {
240.38 + FIXME("unfinished_fn() is unfinished!");
240.39 +}
240.40 +
240.41 +
240.42 +int main() {
240.43 + try {
240.44 + faulty_fn();
240.45 + check(false, "A faulty function did not fail.");
240.46 + }
240.47 + catch(const Exception &e) {
240.48 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
240.49 + }
240.50 +
240.51 + try {
240.52 + exception_fn();
240.53 + check(false, "The function did not throw Exception.");
240.54 + }
240.55 + catch(const Exception &e) {
240.56 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
240.57 + }
240.58 +
240.59 + try {
240.60 + unfinished_fn();
240.61 + check(false, "FIXME macro does not work.");
240.62 + }
240.63 + catch(const Exception &e) {
240.64 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
240.65 + }
240.66 +
240.67 + return 0;
240.68 +}
241.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
241.2 +++ b/test/graph_adaptor_test.cc Mon May 23 04:48:14 2005 +0000
241.3 @@ -0,0 +1,75 @@
241.4 +/* -*- C++ -*-
241.5 + * test/graph_adaptor_test.cc - Part of LEMON, a generic C++ optimization library
241.6 + *
241.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
241.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
241.9 + *
241.10 + * Permission to use, modify and distribute this software is granted
241.11 + * provided that this copyright notice appears in all copies. For
241.12 + * precise terms see the accompanying LICENSE file.
241.13 + *
241.14 + * This software is provided "AS IS" with no warranty of any kind,
241.15 + * express or implied, and with no claim as to its suitability for any
241.16 + * purpose.
241.17 + *
241.18 + */
241.19 +
241.20 +#include<iostream>
241.21 +#include<lemon/concept_check.h>
241.22 +
241.23 +#include<lemon/smart_graph.h>
241.24 +#include<lemon/concept/graph.h>
241.25 +#include<lemon/concept/undir_graph.h>
241.26 +
241.27 +#include<lemon/list_graph.h>
241.28 +#include<lemon/full_graph.h>
241.29 +#include<lemon/graph_adaptor.h>
241.30 +
241.31 +#include"test/test_tools.h"
241.32 +#include"test/graph_test.h"
241.33 +
241.34 +/**
241.35 +\file
241.36 +This test makes consistency checks of graph adaptors.
241.37 +
241.38 +\todo More extensive tests are needed
241.39 +*/
241.40 +
241.41 +using namespace lemon;
241.42 +using namespace lemon::concept;
241.43 +
241.44 +
241.45 +
241.46 +int main()
241.47 +{
241.48 + {
241.49 + typedef StaticGraph Graph;
241.50 + checkConcept<StaticGraph, GraphAdaptor<Graph> >();
241.51 +
241.52 + checkConcept<StaticGraph, RevGraphAdaptor<Graph> >();
241.53 +
241.54 + checkConcept<StaticGraph, SubGraphAdaptor<Graph,
241.55 + Graph::NodeMap<bool> , Graph::EdgeMap<bool> > >();
241.56 + checkConcept<StaticGraph, NodeSubGraphAdaptor<Graph,
241.57 + Graph::NodeMap<bool> > >();
241.58 + checkConcept<StaticGraph, EdgeSubGraphAdaptor<Graph,
241.59 + Graph::EdgeMap<bool> > >();
241.60 +
241.61 + checkConcept<StaticGraph, SubBidirGraphAdaptor<Graph,
241.62 + Graph::EdgeMap<bool>, Graph::EdgeMap<bool> > >();
241.63 + // checkConcept<StaticGraph, BidirGraph<Graph> >();
241.64 + checkConcept<StaticGraph, ResGraphAdaptor<Graph, int,
241.65 + Graph::EdgeMap<int>, Graph::EdgeMap<int> > >();
241.66 +
241.67 + checkConcept<StaticGraph, ErasingFirstGraphAdaptor<Graph,
241.68 + Graph::NodeMap<Graph::Edge> > >();
241.69 +
241.70 + /// \bug why does not compile with StaticGraph
241.71 + checkConcept<BaseIterableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
241.72 + checkConcept<IterableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
241.73 + checkConcept<MappableUndirGraphConcept, UndirGraphAdaptor<ListGraph> >();
241.74 + }
241.75 + std::cout << __FILE__ ": All tests passed.\n";
241.76 +
241.77 + return 0;
241.78 +}
242.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
242.2 +++ b/test/graph_factory_test.cc Mon May 23 04:48:14 2005 +0000
242.3 @@ -0,0 +1,154 @@
242.4 +/* -*- C++ -*-
242.5 + * test/graph_test.cc - Part of LEMON, a generic C++ optimization library
242.6 + *
242.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
242.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
242.9 + *
242.10 + * Permission to use, modify and distribute this software is granted
242.11 + * provided that this copyright notice appears in all copies. For
242.12 + * precise terms see the accompanying LICENSE file.
242.13 + *
242.14 + * This software is provided "AS IS" with no warranty of any kind,
242.15 + * express or implied, and with no claim as to its suitability for any
242.16 + * purpose.
242.17 + *
242.18 + */
242.19 +
242.20 +#include<iostream>
242.21 +#include<lemon/smart_graph.h>
242.22 +#include<lemon/concept/graph.h>
242.23 +#include<lemon/concept/maps.h>
242.24 +#include<lemon/list_graph_base.h>
242.25 +#include<lemon/full_graph.h>
242.26 +
242.27 +#include"test_tools.h"
242.28 +#include"graph_test.h"
242.29 +
242.30 +/**
242.31 +\file
242.32 +This test makes consistency checks of list graph structures.
242.33 +
242.34 +G.addNode(), G.addEdge(), G.source(), G.target()
242.35 +
242.36 +\todo Checks for empty graphs and isolated points.
242.37 +conversion.
242.38 +*/
242.39 +
242.40 +using namespace lemon;
242.41 +
242.42 +template<class Graph> void bidirPetersen(Graph &G)
242.43 +{
242.44 + typedef typename Graph::Edge Edge;
242.45 + typedef typename Graph::EdgeIt EdgeIt;
242.46 +
242.47 + checkGraphEdgeList(G,15);
242.48 +
242.49 + std::vector<Edge> ee;
242.50 +
242.51 + for(EdgeIt e(G);e!=INVALID;++e) ee.push_back(e);
242.52 +
242.53 + for(typename std::vector<Edge>::iterator p=ee.begin();p!=ee.end();p++)
242.54 + G.addEdge(G.target(*p),G.source(*p));
242.55 +}
242.56 +
242.57 +template<class Graph> void checkPetersen(Graph &G)
242.58 +{
242.59 + typedef typename Graph::Node Node;
242.60 +
242.61 + typedef typename Graph::EdgeIt EdgeIt;
242.62 + typedef typename Graph::NodeIt NodeIt;
242.63 +
242.64 + checkGraphNodeList(G,10);
242.65 + checkGraphEdgeList(G,30);
242.66 +
242.67 + for(NodeIt n(G);n!=INVALID;++n) {
242.68 + checkGraphInEdgeList(G,n,3);
242.69 + checkGraphOutEdgeList(G,n,3);
242.70 + }
242.71 +}
242.72 +
242.73 +//Compile Graph
242.74 +template void lemon::concept::checkCompileStaticGraph<concept::StaticGraph>
242.75 +(concept::StaticGraph &);
242.76 +
242.77 +template
242.78 +void lemon::concept::checkCompileExtendableGraph<concept::ExtendableGraph>
242.79 +(concept::ExtendableGraph &);
242.80 +
242.81 +template
242.82 +void lemon::concept::checkCompileErasableGraph<concept::ErasableGraph>
242.83 +(concept::ErasableGraph &);
242.84 +
242.85 +//Compile SmartGraph
242.86 +template
242.87 +void lemon::concept::checkCompileExtendableGraph<SmartGraph>(SmartGraph &);
242.88 +template
242.89 +void lemon::concept::checkCompileGraphFindEdge<SmartGraph>(SmartGraph &);
242.90 +
242.91 +//Compile SymSmartGraph
242.92 +//template void hugo::checkCompileGraph<SymSmartGraph>(SymSmartGraph &);
242.93 +//template void hugo::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
242.94 +
242.95 +//Compile ListGraph
242.96 +template
242.97 +void lemon::concept::checkCompileExtendableGraph<ListGraph>(ListGraph &);
242.98 +template
242.99 +void lemon::concept::checkCompileErasableGraph<ListGraph>(ListGraph &);
242.100 +template
242.101 +void lemon::concept::checkCompileGraphFindEdge<ListGraph>(ListGraph &);
242.102 +
242.103 +
242.104 +//Compile SymListGraph
242.105 +//template void hugo::checkCompileGraph<SymListGraph>(SymListGraph &);
242.106 +//template void hugo::checkCompileErasableGraph<SymListGraph>(SymListGraph &);
242.107 +//template void hugo::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
242.108 +
242.109 +//Compile FullGraph
242.110 +template void lemon::concept::checkCompileStaticGraph<FullGraph>(FullGraph &);
242.111 +template
242.112 +void lemon::concept::checkCompileGraphFindEdge<FullGraph>(FullGraph &);
242.113 +
242.114 +
242.115 +int main()
242.116 +{
242.117 + {
242.118 + SmartGraph G;
242.119 + addPetersen(G);
242.120 + bidirPetersen(G);
242.121 + checkPetersen(G);
242.122 + }
242.123 + {
242.124 + ListGraph G;
242.125 + addPetersen(G);
242.126 + bidirPetersen(G);
242.127 + checkPetersen(G);
242.128 + }
242.129 + {
242.130 + // SymSmartGraph G;
242.131 + // addPetersen(G);
242.132 + // checkPetersen(G);
242.133 + }
242.134 + {
242.135 + // SymListGraph G;
242.136 + // addPetersen(G);
242.137 + // checkPetersen(G);
242.138 + }
242.139 +
242.140 + ///\file
242.141 + ///\todo map tests.
242.142 + ///\todo copy constr tests.
242.143 +
242.144 +
242.145 + // Some map tests.
242.146 + // FIXME: These shouldn't be here.
242.147 + using namespace concept;
242.148 + function_requires< ReadMapConcept< ReadMap<int,int> > >();
242.149 + function_requires< WriteMapConcept< WriteMap<int,int> > >();
242.150 + function_requires< ReadWriteMapConcept< ReadWriteMap<int,int> > >();
242.151 + function_requires< ReferenceMapConcept< ReferenceMap<int,int> > >();
242.152 +
242.153 +
242.154 + std::cout << __FILE__ ": All tests passed.\n";
242.155 +
242.156 + return 0;
242.157 +}
243.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243.2 +++ b/test/graph_test.cc Mon May 23 04:48:14 2005 +0000
243.3 @@ -0,0 +1,66 @@
243.4 +// -*- c++ -*-
243.5 +
243.6 +#include <iostream>
243.7 +#include <vector>
243.8 +
243.9 +#include <lemon/concept/graph.h>
243.10 +#include <lemon/list_graph.h>
243.11 +#include <lemon/smart_graph.h>
243.12 +#include <lemon/full_graph.h>
243.13 +
243.14 +#include "test_tools.h"
243.15 +#include "graph_test.h"
243.16 +#include "map_test.h"
243.17 +
243.18 +
243.19 +using namespace lemon;
243.20 +using namespace lemon::concept;
243.21 +
243.22 +
243.23 +int main() {
243.24 + { // checking graph components
243.25 + checkConcept<BaseGraphComponent, BaseGraphComponent >();
243.26 +
243.27 + checkConcept<BaseIterableGraphComponent, BaseIterableGraphComponent >();
243.28 +
243.29 + checkConcept<IDableGraphComponent, IDableGraphComponent >();
243.30 + checkConcept<MaxIDableGraphComponent, MaxIDableGraphComponent >();
243.31 +
243.32 + checkConcept<BaseExtendableGraphComponent, BaseExtendableGraphComponent >();
243.33 + checkConcept<BaseErasableGraphComponent, BaseErasableGraphComponent >();
243.34 +
243.35 + checkConcept<IterableGraphComponent, IterableGraphComponent >();
243.36 +
243.37 + checkConcept<MappableGraphComponent, MappableGraphComponent >();
243.38 +
243.39 + checkConcept<ExtendableGraphComponent, ExtendableGraphComponent >();
243.40 + checkConcept<ErasableGraphComponent, ErasableGraphComponent >();
243.41 + checkConcept<ClearableGraphComponent, ClearableGraphComponent >();
243.42 + }
243.43 + { // checking skeleton graphs
243.44 + checkConcept<StaticGraph, StaticGraph >();
243.45 + checkConcept<ExtendableGraph, ExtendableGraph >();
243.46 + checkConcept<ErasableGraph, ErasableGraph >();
243.47 + }
243.48 + { // checking list graph
243.49 + checkConcept<ErasableGraph, ListGraph >();
243.50 +
243.51 + checkGraph<ListGraph>();
243.52 + checkGraphNodeMap<ListGraph>();
243.53 + checkGraphEdgeMap<ListGraph>();
243.54 + }
243.55 + { // checking smart graph
243.56 + checkConcept<ExtendableGraph, SmartGraph >();
243.57 +
243.58 + checkGraph<SmartGraph>();
243.59 + checkGraphNodeMap<SmartGraph>();
243.60 + checkGraphEdgeMap<SmartGraph>();
243.61 + }
243.62 + { // checking full graph
243.63 + checkConcept<StaticGraph, FullGraph >();
243.64 + }
243.65 +
243.66 + std::cout << __FILE__ ": All tests passed.\n";
243.67 +
243.68 + return 0;
243.69 +}
244.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
244.2 +++ b/test/graph_test.h Mon May 23 04:48:14 2005 +0000
244.3 @@ -0,0 +1,90 @@
244.4 +/* -*- C++ -*-
244.5 + * test/graph_test.h - Part of LEMON, a generic C++ optimization library
244.6 + *
244.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
244.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
244.9 + *
244.10 + * Permission to use, modify and distribute this software is granted
244.11 + * provided that this copyright notice appears in all copies. For
244.12 + * precise terms see the accompanying LICENSE file.
244.13 + *
244.14 + * This software is provided "AS IS" with no warranty of any kind,
244.15 + * express or implied, and with no claim as to its suitability for any
244.16 + * purpose.
244.17 + *
244.18 + */
244.19 +#ifndef LEMON_TEST_GRAPH_TEST_H
244.20 +#define LEMON_TEST_GRAPH_TEST_H
244.21 +
244.22 +
244.23 +#include "test_tools.h"
244.24 +
244.25 +//! \ingroup misc
244.26 +//! \file
244.27 +//! \brief Some utility and test cases to test graph classes.
244.28 +namespace lemon {
244.29 +
244.30 + template<class Graph> void checkGraphNodeList(Graph &G, int nn)
244.31 + {
244.32 + typename Graph::NodeIt n(G);
244.33 + for(int i=0;i<nn;i++) {
244.34 + check(n!=INVALID,"Wrong Node list linking.");
244.35 + ++n;
244.36 + }
244.37 + check(n==INVALID,"Wrong Node list linking.");
244.38 + }
244.39 +
244.40 + template<class Graph>
244.41 + void checkGraphEdgeList(Graph &G, int nn)
244.42 + {
244.43 + typedef typename Graph::EdgeIt EdgeIt;
244.44 +
244.45 + EdgeIt e(G);
244.46 + for(int i=0;i<nn;i++) {
244.47 + check(e!=INVALID,"Wrong Edge list linking.");
244.48 + ++e;
244.49 + }
244.50 + check(e==INVALID,"Wrong Edge list linking.");
244.51 + }
244.52 +
244.53 + template<class Graph>
244.54 + void checkGraphOutEdgeList(Graph &G, typename Graph::Node n, int nn)
244.55 + {
244.56 + typename Graph::OutEdgeIt e(G,n);
244.57 + for(int i=0;i<nn;i++) {
244.58 + check(e!=INVALID,"Wrong OutEdge list linking.");
244.59 + check(n==G.source(e), "Wrong OutEdge list linking.");
244.60 + ++e;
244.61 + }
244.62 + check(e==INVALID,"Wrong OutEdge list linking.");
244.63 + }
244.64 +
244.65 + template<class Graph> void
244.66 + checkGraphInEdgeList(Graph &G, typename Graph::Node n, int nn)
244.67 + {
244.68 + typename Graph::InEdgeIt e(G,n);
244.69 + for(int i=0;i<nn;i++) {
244.70 + check(e!=INVALID,"Wrong InEdge list linking.");
244.71 + check(n==G.target(e), "Wrong InEdge list linking.");
244.72 + ++e;
244.73 + }
244.74 + check(e==INVALID,"Wrong InEdge list linking.");
244.75 + }
244.76 +
244.77 + template <class Graph>
244.78 + void checkGraph() {
244.79 + const int num = 5;
244.80 + Graph G;
244.81 + addPetersen(G, num);
244.82 + bidirGraph(G);
244.83 + checkBidirPetersen(G, num);
244.84 + }
244.85 +
244.86 + ///\file
244.87 + ///\todo Check target(), source() as well;
244.88 +
244.89 +
244.90 +} //namespace lemon
244.91 +
244.92 +
244.93 +#endif
245.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
245.2 +++ b/test/graph_utils_test.cc Mon May 23 04:48:14 2005 +0000
245.3 @@ -0,0 +1,37 @@
245.4 +// -*- c++ -*-
245.5 +
245.6 +#include <iostream>
245.7 +#include <vector>
245.8 +
245.9 +#include <lemon/graph_utils.h>
245.10 +
245.11 +#include <lemon/list_graph.h>
245.12 +#include <lemon/smart_graph.h>
245.13 +#include <lemon/full_graph.h>
245.14 +
245.15 +#include "test_tools.h"
245.16 +#include "graph_utils_test.h"
245.17 +
245.18 +
245.19 +using namespace lemon;
245.20 +
245.21 +
245.22 +int main() {
245.23 + ///\file
245.24 + { // checking list graph
245.25 + checkGraphCounters<ListGraph>();
245.26 + }
245.27 + { // checking smart graph
245.28 + checkGraphCounters<SmartGraph>();
245.29 + }
245.30 + {
245.31 + int num = 5;
245.32 + FullGraph fg(num);
245.33 + check(countNodes(fg) == num, "FullGraph: wrong node number.");
245.34 + check(countEdges(fg) == num*num, "FullGraph: wrong edge number.");
245.35 + }
245.36 +
245.37 + std::cout << __FILE__ ": All tests passed.\n";
245.38 +
245.39 + return 0;
245.40 +}
246.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
246.2 +++ b/test/graph_utils_test.h Mon May 23 04:48:14 2005 +0000
246.3 @@ -0,0 +1,44 @@
246.4 +/* -*- C++ -*-
246.5 + * test/graph_utils_test.h - Part of LEMON, a generic C++ optimization library
246.6 + *
246.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
246.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
246.9 + *
246.10 + * Permission to use, modify and distribute this software is granted
246.11 + * provided that this copyright notice appears in all copies. For
246.12 + * precise terms see the accompanying LICENSE file.
246.13 + *
246.14 + * This software is provided "AS IS" with no warranty of any kind,
246.15 + * express or implied, and with no claim as to its suitability for any
246.16 + * purpose.
246.17 + *
246.18 + */
246.19 +#ifndef LEMON_TEST_GRAPH_UTILS_TEST_H
246.20 +#define LEMON_TEST_GRAPH_UTILS_TEST_H
246.21 +
246.22 +
246.23 +#include "test_tools.h"
246.24 +
246.25 +//! \ingroup misc
246.26 +//! \file
246.27 +//! \brief Test cases for graph utils.
246.28 +namespace lemon {
246.29 +
246.30 + template <typename Graph>
246.31 + void checkGraphCounters() {
246.32 + const int num = 5;
246.33 + Graph graph;
246.34 + addPetersen(graph, num);
246.35 + bidirGraph(graph);
246.36 + check(countNodes(graph) == 2*num, "Wrong node number.");
246.37 + check(countEdges(graph) == 6*num, "Wrong edge number.");
246.38 + for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
246.39 + check(countOutEdges(graph, it) == 3, "Wrong out degree number.");
246.40 + check(countInEdges(graph, it) == 3, "Wrong in degree number.");
246.41 + }
246.42 + }
246.43 +
246.44 +} //namespace lemon
246.45 +
246.46 +
246.47 +#endif
247.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
247.2 +++ b/test/heap_test.cc Mon May 23 04:48:14 2005 +0000
247.3 @@ -0,0 +1,98 @@
247.4 +// -*- c++ -*-
247.5 +
247.6 +#include <iostream>
247.7 +#include <fstream>
247.8 +#include <string>
247.9 +#include <vector>
247.10 +
247.11 +#include <lemon/concept_check.h>
247.12 +#include <lemon/concept/heap.h>
247.13 +
247.14 +#include <lemon/smart_graph.h>
247.15 +
247.16 +#include <lemon/graph_reader.h>
247.17 +
247.18 +#include <lemon/bin_heap.h>
247.19 +#include <lemon/fib_heap.h>
247.20 +#include <lemon/radix_heap.h>
247.21 +
247.22 +#include "test_tools.h"
247.23 +
247.24 +#include "heap_test.h"
247.25 +
247.26 +
247.27 +using namespace lemon;
247.28 +using namespace lemon::concept;
247.29 +
247.30 +
247.31 +int main() {
247.32 +
247.33 + typedef int Item;
247.34 + typedef int Prio;
247.35 + typedef IntIntMap ItemIntMap;
247.36 +
247.37 + typedef ListGraph Graph;
247.38 +
247.39 + typedef Graph::Edge Edge;
247.40 + typedef Graph::Node Node;
247.41 + typedef Graph::EdgeIt EdgeIt;
247.42 + typedef Graph::NodeIt NodeIt;
247.43 + typedef Graph::EdgeMap<int> LengthMap;
247.44 +
247.45 + Graph graph;
247.46 + LengthMap length(graph);
247.47 + Node start;
247.48 +
247.49 + /// \todo create own test graph
247.50 +
247.51 + std::string f_name;
247.52 + if( getenv("srcdir") )
247.53 + f_name = std::string(getenv("srcdir"));
247.54 + else f_name = ".";
247.55 + f_name += "/dijkstra_test.lgf";
247.56 +
247.57 + std::ifstream input(f_name.c_str());
247.58 + check(input, "Input file '" << f_name << "' not found.");
247.59 + readGraph(input, graph, length, start);
247.60 +
247.61 + {
247.62 + std::cerr << "Checking Bin Heap" << std::endl;
247.63 +
247.64 + typedef BinHeap<Item, Prio, ItemIntMap> IntHeap;
247.65 + checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
247.66 + heapSortTest<IntHeap>(100);
247.67 + heapIncreaseTest<IntHeap>(100);
247.68 +
247.69 + typedef FibHeap<Node, Prio, Graph::NodeMap<int> > NodeHeap;
247.70 + checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
247.71 + dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
247.72 + }
247.73 + {
247.74 + std::cerr << "Checking Fib Heap" << std::endl;
247.75 +
247.76 + typedef FibHeap<Item, Prio, ItemIntMap> IntHeap;
247.77 + checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
247.78 + heapSortTest<IntHeap>(100);
247.79 + heapIncreaseTest<IntHeap>(100);
247.80 +
247.81 + typedef FibHeap<Node, Prio, Graph::NodeMap<int> > NodeHeap;
247.82 + checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
247.83 + dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
247.84 + }
247.85 + {
247.86 + std::cerr << "Checking Radix Heap" << std::endl;
247.87 +
247.88 + typedef RadixHeap<Item, ItemIntMap> IntHeap;
247.89 + checkConcept<Heap<Item, Prio, ItemIntMap>, IntHeap>();
247.90 + heapSortTest<IntHeap>(100);
247.91 + heapIncreaseTest<IntHeap>(100);
247.92 +
247.93 + typedef RadixHeap<Node, Graph::NodeMap<int> > NodeHeap;
247.94 + checkConcept<Heap<Node, Prio, Graph::NodeMap<int> >, NodeHeap>();
247.95 + dijkstraHeapTest<Graph, LengthMap, NodeHeap>(graph, length, start);
247.96 + }
247.97 +
247.98 + std::cout << __FILE__ ": All tests passed.\n";
247.99 +
247.100 + return 0;
247.101 +}
248.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
248.2 +++ b/test/heap_test.h Mon May 23 04:48:14 2005 +0000
248.3 @@ -0,0 +1,110 @@
248.4 +// -+- c++ -+-
248.5 +
248.6 +#include <vector>
248.7 +#include <algorithm>
248.8 +
248.9 +#include <lemon/dijkstra.h>
248.10 +
248.11 +class IntIntMap : public std::vector<int> {
248.12 +public:
248.13 + typedef std::vector<int> Parent;
248.14 +
248.15 + IntIntMap() : Parent() {}
248.16 + IntIntMap(int n) : Parent(n) {}
248.17 + IntIntMap(int n, int v) : Parent(n, v) {}
248.18 +
248.19 + void set(int key, int value) {
248.20 + Parent::operator[](key) = value;
248.21 + }
248.22 +};
248.23 +
248.24 +
248.25 +template <typename _Heap>
248.26 +void heapSortTest(int n) {
248.27 + typedef _Heap Heap;
248.28 + IntIntMap map(n, -1);
248.29 +
248.30 + Heap heap(map);
248.31 +
248.32 + std::vector<int> v(n);
248.33 +
248.34 + for (int i = 0; i < n; ++i) {
248.35 + v[i] = rand() % 1000;
248.36 + heap.push(i, v[i]);
248.37 + }
248.38 + std::sort(v.begin(), v.end());
248.39 + for (int i = 0; i < n; ++i) {
248.40 + check(v[i] == heap.prio() ,"Wrong order in heap sort.");
248.41 + heap.pop();
248.42 + }
248.43 +}
248.44 +
248.45 +template <typename _Heap>
248.46 +void heapIncreaseTest(int n) {
248.47 + typedef _Heap Heap;
248.48 + IntIntMap map(n, -1);
248.49 +
248.50 + Heap heap(map);
248.51 +
248.52 + std::vector<int> v(n);
248.53 +
248.54 + for (int i = 0; i < n; ++i) {
248.55 + v[i] = rand() % 1000;
248.56 + heap.push(i, v[i]);
248.57 + }
248.58 + for (int i = 0; i < n; ++i) {
248.59 + v[i] += rand() % 1000;
248.60 + heap.increase(i, v[i]);
248.61 + }
248.62 + std::sort(v.begin(), v.end());
248.63 + for (int i = 0; i < n; ++i) {
248.64 + check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
248.65 + heap.pop();
248.66 + }
248.67 +}
248.68 +
248.69 +
248.70 +
248.71 +template <typename _Traits, typename _Heap>
248.72 +struct DefHeapTraits : public _Traits {
248.73 + typedef _Heap Heap;
248.74 +};
248.75 +
248.76 +template <typename _Graph, typename _LengthMap, typename _Heap>
248.77 +void dijkstraHeapTest(_Graph& graph, _LengthMap& length,
248.78 + typename _Graph::Node& start) {
248.79 +
248.80 + typedef _Heap Heap;
248.81 + typedef _Graph Graph;
248.82 + typedef _LengthMap LengthMap;
248.83 +
248.84 + typedef typename Graph::Node Node;
248.85 + typedef typename Graph::Edge Edge;
248.86 + typedef typename Graph::NodeIt NodeIt;
248.87 + typedef typename Graph::EdgeIt EdgeIt;
248.88 +
248.89 + Dijkstra<Graph, LengthMap,
248.90 + DefHeapTraits<DijkstraDefaultTraits<Graph, LengthMap>, Heap> >
248.91 + dijkstra(graph, length);
248.92 +
248.93 + dijkstra.run(start);
248.94 +
248.95 + for(EdgeIt e(graph); e!=INVALID; ++e) {
248.96 + Node u=graph.source(e);
248.97 + Node v=graph.target(e);
248.98 + if (dijkstra.reached(u)) {
248.99 + check( dijkstra.dist(v) - dijkstra.dist(u) <= length[e],
248.100 + "Error in a shortest path tree edge!");
248.101 + }
248.102 + }
248.103 +
248.104 + for(NodeIt v(graph); v!=INVALID; ++v) {
248.105 + if ( dijkstra.reached(v) && dijkstra.pred(v) != INVALID ) {
248.106 + Edge e=dijkstra.pred(v);
248.107 + Node u=graph.source(e);
248.108 + check( dijkstra.dist(v) - dijkstra .dist(u) == length[e],
248.109 + "Error in a shortest path tree edge!");
248.110 + }
248.111 + }
248.112 +
248.113 +}
249.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249.2 +++ b/test/kruskal_test.cc Mon May 23 04:48:14 2005 +0000
249.3 @@ -0,0 +1,119 @@
249.4 +/* -*- C++ -*-
249.5 + * test/kruskal_test.cc - Part of LEMON, a generic C++ optimization library
249.6 + *
249.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
249.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
249.9 + *
249.10 + * Permission to use, modify and distribute this software is granted
249.11 + * provided that this copyright notice appears in all copies. For
249.12 + * precise terms see the accompanying LICENSE file.
249.13 + *
249.14 + * This software is provided "AS IS" with no warranty of any kind,
249.15 + * express or implied, and with no claim as to its suitability for any
249.16 + * purpose.
249.17 + *
249.18 + */
249.19 +
249.20 +#include <iostream>
249.21 +#include <vector>
249.22 +
249.23 +#include "test_tools.h"
249.24 +#include <lemon/maps.h>
249.25 +#include <lemon/kruskal.h>
249.26 +#include <lemon/list_graph.h>
249.27 +#include <lemon/concept/maps.h>
249.28 +#include <lemon/concept/graph.h>
249.29 +
249.30 +
249.31 +using namespace std;
249.32 +using namespace lemon;
249.33 +
249.34 +void checkCompileKruskal()
249.35 +{
249.36 + concept::WriteMap<concept::StaticGraph::Edge,bool> w;
249.37 +
249.38 + kruskalEdgeMap(concept::StaticGraph(),
249.39 + concept::ReadMap<concept::StaticGraph::Edge,int>(),
249.40 + w);
249.41 +}
249.42 +
249.43 +int main() {
249.44 +
249.45 + typedef ListGraph::Node Node;
249.46 + typedef ListGraph::Edge Edge;
249.47 + typedef ListGraph::NodeIt NodeIt;
249.48 + typedef ListGraph::EdgeIt EdgeIt;
249.49 +
249.50 + ListGraph G;
249.51 +
249.52 + Node s=G.addNode();
249.53 + Node v1=G.addNode();
249.54 + Node v2=G.addNode();
249.55 + Node v3=G.addNode();
249.56 + Node v4=G.addNode();
249.57 + Node t=G.addNode();
249.58 +
249.59 + Edge e1 = G.addEdge(s, v1);
249.60 + Edge e2 = G.addEdge(s, v2);
249.61 + Edge e3 = G.addEdge(v1, v2);
249.62 + Edge e4 = G.addEdge(v2, v1);
249.63 + Edge e5 = G.addEdge(v1, v3);
249.64 + Edge e6 = G.addEdge(v3, v2);
249.65 + Edge e7 = G.addEdge(v2, v4);
249.66 + Edge e8 = G.addEdge(v4, v3);
249.67 + Edge e9 = G.addEdge(v3, t);
249.68 + Edge e10 = G.addEdge(v4, t);
249.69 +
249.70 + typedef ListGraph::EdgeMap<int> ECostMap;
249.71 + typedef ListGraph::EdgeMap<bool> EBoolMap;
249.72 +
249.73 + ECostMap edge_cost_map(G, 2);
249.74 + EBoolMap tree_map(G);
249.75 +
249.76 +
249.77 + //Test with const map.
249.78 + check(kruskalEdgeMap(G, ConstMap<ListGraph::Edge,int>(2), tree_map)==10,
249.79 + "Total cost should be 10");
249.80 + //Test with a edge map (filled with uniform costs).
249.81 + check(kruskalEdgeMap(G, edge_cost_map, tree_map)==10,
249.82 + "Total cost should be 10");
249.83 +
249.84 + edge_cost_map.set(e1, -10);
249.85 + edge_cost_map.set(e2, -9);
249.86 + edge_cost_map.set(e3, -8);
249.87 + edge_cost_map.set(e4, -7);
249.88 + edge_cost_map.set(e5, -6);
249.89 + edge_cost_map.set(e6, -5);
249.90 + edge_cost_map.set(e7, -4);
249.91 + edge_cost_map.set(e8, -3);
249.92 + edge_cost_map.set(e9, -2);
249.93 + edge_cost_map.set(e10, -1);
249.94 +
249.95 + vector<Edge> tree_edge_vec;
249.96 +
249.97 + //Test with a edge map and inserter.
249.98 + check(kruskalEdgeMap_IteratorOut(G, edge_cost_map,
249.99 + back_inserter(tree_edge_vec))
249.100 + ==-31,
249.101 + "Total cost should be -31.");
249.102 +
249.103 + tree_edge_vec.clear();
249.104 +
249.105 + //The above test could also be coded like this:
249.106 + check(kruskal(G,
249.107 + makeKruskalMapInput(G, edge_cost_map),
249.108 + makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
249.109 + ==-31,
249.110 + "Total cost should be -31.");
249.111 +
249.112 + check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
249.113 +
249.114 + check(tree_edge_vec[0]==e1 &&
249.115 + tree_edge_vec[1]==e2 &&
249.116 + tree_edge_vec[2]==e5 &&
249.117 + tree_edge_vec[3]==e7 &&
249.118 + tree_edge_vec[4]==e9,
249.119 + "Wrong tree.");
249.120 +
249.121 + return 0;
249.122 +}
250.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250.2 +++ b/test/lp_test.cc Mon May 23 04:48:14 2005 +0000
250.3 @@ -0,0 +1,155 @@
250.4 +#include<lemon/lp_skeleton.h>
250.5 +
250.6 +#ifdef HAVE_CONFIG_H
250.7 +#include <config.h>
250.8 +#endif
250.9 +
250.10 +#ifdef HAVE_GLPK
250.11 +#include <lemon/lp_glpk.h>
250.12 +#elif HAVE_CPLEX
250.13 +#include <lemon/lp_cplex.h>
250.14 +#endif
250.15 +
250.16 +using namespace lemon;
250.17 +
250.18 +#ifdef HAVE_GLPK
250.19 +typedef LpGlpk LpDefault;
250.20 +#elif HAVE_CPLEX
250.21 +typedef LpCplex LpDefault;
250.22 +#endif
250.23 +
250.24 +void lpTest(LpSolverBase & lp)
250.25 +{
250.26 + typedef LpSolverBase LP;
250.27 +
250.28 + std::vector<LP::Col> x(10);
250.29 + // for(int i=0;i<10;i++) x.push_back(lp.addCol());
250.30 + lp.addColSet(x);
250.31 +
250.32 + std::vector<LP::Col> y(10);
250.33 + lp.addColSet(y);
250.34 +
250.35 + std::map<int,LP::Col> z;
250.36 +
250.37 + z.insert(std::make_pair(12,INVALID));
250.38 + z.insert(std::make_pair(2,INVALID));
250.39 + z.insert(std::make_pair(7,INVALID));
250.40 + z.insert(std::make_pair(5,INVALID));
250.41 +
250.42 + lp.addColSet(z);
250.43 +
250.44 +
250.45 + LP::Expr e,f,g;
250.46 + LP::Col p1,p2,p3,p4,p5;
250.47 + LP::Constr c;
250.48 +
250.49 + e[p1]=2;
250.50 + e.constComp()=12;
250.51 + e[p1]+=2;
250.52 + e.constComp()+=12;
250.53 + e[p1]-=2;
250.54 + e.constComp()-=12;
250.55 +
250.56 + e=2;
250.57 + e=2.2;
250.58 + e=p1;
250.59 + e=f;
250.60 +
250.61 + e+=2;
250.62 + e+=2.2;
250.63 + e+=p1;
250.64 + e+=f;
250.65 +
250.66 + e-=2;
250.67 + e-=2.2;
250.68 + e-=p1;
250.69 + e-=f;
250.70 +
250.71 + e*=2;
250.72 + e*=2.2;
250.73 + e/=2;
250.74 + e/=2.2;
250.75 +
250.76 + e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
250.77 + (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
250.78 + (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
250.79 + 2.2*f+f*2.2+f/2.2+
250.80 + 2*f+f*2+f/2+
250.81 + 2.2*p1+p1*2.2+p1/2.2+
250.82 + 2*p1+p1*2+p1/2
250.83 + );
250.84 +
250.85 +
250.86 + c = (e <= f );
250.87 + c = (e <= 2.2);
250.88 + c = (e <= 2 );
250.89 + c = (e <= p1 );
250.90 + c = (2.2<= f );
250.91 + c = (2 <= f );
250.92 + c = (p1 <= f );
250.93 + c = (p1 <= p2 );
250.94 + c = (p1 <= 2.2);
250.95 + c = (p1 <= 2 );
250.96 + c = (2.2<= p2 );
250.97 + c = (2 <= p2 );
250.98 +
250.99 + c = (e >= f );
250.100 + c = (e >= 2.2);
250.101 + c = (e >= 2 );
250.102 + c = (e >= p1 );
250.103 + c = (2.2>= f );
250.104 + c = (2 >= f );
250.105 + c = (p1 >= f );
250.106 + c = (p1 >= p2 );
250.107 + c = (p1 >= 2.2);
250.108 + c = (p1 >= 2 );
250.109 + c = (2.2>= p2 );
250.110 + c = (2 >= p2 );
250.111 +
250.112 + c = (e == f );
250.113 + c = (e == 2.2);
250.114 + c = (e == 2 );
250.115 + c = (e == p1 );
250.116 + c = (2.2== f );
250.117 + c = (2 == f );
250.118 + c = (p1 == f );
250.119 + //c = (p1 == p2 );
250.120 + c = (p1 == 2.2);
250.121 + c = (p1 == 2 );
250.122 + c = (2.2== p2 );
250.123 + c = (2 == p2 );
250.124 +
250.125 + c = (2 <= e <= 3);
250.126 + c = (2 <= p1<= 3);
250.127 +
250.128 + c = (2 >= e >= 3);
250.129 + c = (2 >= p1>= 3);
250.130 +
250.131 + e[x[3]]=2;
250.132 + e[x[3]]=4;
250.133 + e[x[3]]=1;
250.134 + e.constComp()=12;
250.135 +
250.136 + lp.addRow(LP::INF,e,23);
250.137 + lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
250.138 + lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
250.139 +
250.140 + lp.addRow(x[1]+x[3]<=x[5]-3);
250.141 + lp.addRow(-7<=x[1]+x[3]-12<=3);
250.142 + lp.addRow(x[1]<=x[5]);
250.143 +
250.144 +
250.145 +
250.146 +}
250.147 +
250.148 +int main()
250.149 +{
250.150 + LpSkeleton lp_skel;
250.151 + lpTest(lp_skel);
250.152 +
250.153 + LpDefault lp;
250.154 +
250.155 + lpTest(lp);
250.156 +
250.157 + return 0;
250.158 +}
251.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
251.2 +++ b/test/map_test.h Mon May 23 04:48:14 2005 +0000
251.3 @@ -0,0 +1,95 @@
251.4 +/* -*- C++ -*-
251.5 + * test/map_test.h - Part of LEMON, a generic C++ optimization library
251.6 + *
251.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
251.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
251.9 + *
251.10 + * Permission to use, modify and distribute this software is granted
251.11 + * provided that this copyright notice appears in all copies. For
251.12 + * precise terms see the accompanying LICENSE file.
251.13 + *
251.14 + * This software is provided "AS IS" with no warranty of any kind,
251.15 + * express or implied, and with no claim as to its suitability for any
251.16 + * purpose.
251.17 + *
251.18 + */
251.19 +#ifndef LEMON_TEST_MAP_TEST_H
251.20 +#define LEMON_TEST_MAP_TEST_H
251.21 +
251.22 +
251.23 +#include <vector>
251.24 +
251.25 +#include "test_tools.h"
251.26 +
251.27 +
251.28 +//! \ingroup misc
251.29 +//! \file
251.30 +//! \brief Some utilities to test map classes.
251.31 +
251.32 +namespace lemon {
251.33 +
251.34 +
251.35 + template <typename Graph>
251.36 + void checkGraphNodeMap() {
251.37 + Graph graph;
251.38 + const int num = 16;
251.39 +
251.40 + typedef typename Graph::Node Node;
251.41 +
251.42 + std::vector<Node> nodes;
251.43 + for (int i = 0; i < num; ++i) {
251.44 + nodes.push_back(graph.addNode());
251.45 + }
251.46 + typedef typename Graph::template NodeMap<int> IntNodeMap;
251.47 + IntNodeMap map(graph, 42);
251.48 + for (int i = 0; i < (int)nodes.size(); ++i) {
251.49 + check(map[nodes[i]] == 42, "Wrong map constructor.");
251.50 + }
251.51 + for (int i = 0; i < num; ++i) {
251.52 + nodes.push_back(graph.addNode());
251.53 + map[nodes.back()] = 23;
251.54 + }
251.55 + graph.clear();
251.56 + nodes.clear();
251.57 + }
251.58 +
251.59 + template <typename Graph>
251.60 + void checkGraphEdgeMap() {
251.61 + Graph graph;
251.62 + const int num = 16;
251.63 +
251.64 + typedef typename Graph::Node Node;
251.65 + typedef typename Graph::Edge Edge;
251.66 +
251.67 + std::vector<Node> nodes;
251.68 + for (int i = 0; i < num; ++i) {
251.69 + nodes.push_back(graph.addNode());
251.70 + }
251.71 +
251.72 + std::vector<Edge> edges;
251.73 + for (int i = 0; i < num; ++i) {
251.74 + for (int j = 0; j < i; ++j) {
251.75 + edges.push_back(graph.addEdge(nodes[i], nodes[j]));
251.76 + }
251.77 + }
251.78 +
251.79 + typedef typename Graph::template EdgeMap<int> IntEdgeMap;
251.80 + IntEdgeMap map(graph, 42);
251.81 +
251.82 + for (int i = 0; i < (int)edges.size(); ++i) {
251.83 + check(map[edges[i]] == 42, "Wrong map constructor.");
251.84 + }
251.85 +
251.86 + for (int i = 0; i < num; ++i) {
251.87 + for (int j = i + 1; j < num; ++j) {
251.88 + edges.push_back(graph.addEdge(nodes[i], nodes[j]));
251.89 + map[edges.back()] = 23;
251.90 + }
251.91 + }
251.92 + graph.clear();
251.93 + edges.clear();
251.94 + }
251.95 +
251.96 +}
251.97 +
251.98 +#endif
252.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
252.2 +++ b/test/maps_test.cc Mon May 23 04:48:14 2005 +0000
252.3 @@ -0,0 +1,57 @@
252.4 +#include <lemon/concept_check.h>
252.5 +#include <lemon/concept/maps.h>
252.6 +#include <lemon/maps.h>
252.7 +
252.8 +#include "test_tools.h"
252.9 +
252.10 +using namespace lemon;
252.11 +using namespace lemon::concept;
252.12 +
252.13 +struct A {};
252.14 +struct B {};
252.15 +class F
252.16 +{
252.17 +public:
252.18 + B operator()(const A &) const {return B();}
252.19 +};
252.20 +
252.21 +int func(A) {return 3;}
252.22 +
252.23 +typedef ReadMap<A,double> DoubleMap;
252.24 +
252.25 +int main()
252.26 +{ // checking graph components
252.27 +
252.28 + checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
252.29 + checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
252.30 + checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
252.31 + checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
252.32 +
252.33 + checkConcept<ReadMap<A,double>, AddMap<DoubleMap,DoubleMap> >();
252.34 + checkConcept<ReadMap<A,double>, SubMap<DoubleMap,DoubleMap> >();
252.35 + checkConcept<ReadMap<A,double>, MulMap<DoubleMap,DoubleMap> >();
252.36 + checkConcept<ReadMap<A,double>, DivMap<DoubleMap,DoubleMap> >();
252.37 + checkConcept<ReadMap<A,double>, NegMap<DoubleMap> >();
252.38 + checkConcept<ReadMap<A,double>, AbsMap<DoubleMap> >();
252.39 + checkConcept<ReadMap<A,double>, ShiftMap<DoubleMap> >();
252.40 + checkConcept<ReadMap<A,double>, ScaleMap<DoubleMap> >();
252.41 +
252.42 + checkConcept<ReadMap<B,double>, ComposeMap<DoubleMap,ReadMap<B,A> > >();
252.43 +
252.44 + checkConcept<ReadMap<A,B>, FunctorMap<A,B,F> >();
252.45 +
252.46 + int a;
252.47 +
252.48 + a=mapFunctor(constMap<A,int>(2))(A());
252.49 + check(a==2,"Something is wrong with mapFunctor");
252.50 +
252.51 + B b;
252.52 + b=functorMap<A,B>(F())[A()];
252.53 +
252.54 + a=functorMap<A,int>(&func)[A()];
252.55 + check(a==3,"Something is wrong with functorMap");
252.56 +
252.57 + std::cout << __FILE__ ": All tests passed.\n";
252.58 +
252.59 + return 0;
252.60 +}
253.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
253.2 +++ b/test/max_matching_test.cc Mon May 23 04:48:14 2005 +0000
253.3 @@ -0,0 +1,183 @@
253.4 +/* -*- C++ -*-
253.5 + * test/max_matching_test.cc -
253.6 + * Part of LEMON, a generic C++ optimization library
253.7 + *
253.8 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
253.9 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
253.10 + *
253.11 + * Permission to use, modify and distribute this software is granted
253.12 + * provided that this copyright notice appears in all copies. For
253.13 + * precise terms see the accompanying LICENSE file.
253.14 + *
253.15 + * This software is provided "AS IS" with no warranty of any kind,
253.16 + * express or implied, and with no claim as to its suitability for any
253.17 + * purpose.
253.18 + *
253.19 + */
253.20 +
253.21 +#include <iostream>
253.22 +#include <vector>
253.23 +#include <queue>
253.24 +#include <math.h>
253.25 +#include <cstdlib>
253.26 +
253.27 +#include "test_tools.h"
253.28 +#include <lemon/invalid.h>
253.29 +#include <lemon/list_graph.h>
253.30 +#include <lemon/max_matching.h>
253.31 +
253.32 +using namespace std;
253.33 +using namespace lemon;
253.34 +
253.35 +int main() {
253.36 +
253.37 + typedef UndirListGraph Graph;
253.38 +
253.39 + typedef Graph::Edge Edge;
253.40 + typedef Graph::UndirEdgeIt UndirEdgeIt;
253.41 + typedef Graph::IncEdgeIt IncEdgeIt;
253.42 + typedef Graph::NodeIt NodeIt;
253.43 + typedef Graph::Node Node;
253.44 +
253.45 + Graph g;
253.46 + g.clear();
253.47 +
253.48 + std::vector<Graph::Node> nodes;
253.49 + for (int i=0; i<13; ++i)
253.50 + nodes.push_back(g.addNode());
253.51 +
253.52 + g.addEdge(nodes[0], nodes[0]);
253.53 + g.addEdge(nodes[6], nodes[10]);
253.54 + g.addEdge(nodes[5], nodes[10]);
253.55 + g.addEdge(nodes[4], nodes[10]);
253.56 + g.addEdge(nodes[3], nodes[11]);
253.57 + g.addEdge(nodes[1], nodes[6]);
253.58 + g.addEdge(nodes[4], nodes[7]);
253.59 + g.addEdge(nodes[1], nodes[8]);
253.60 + g.addEdge(nodes[0], nodes[8]);
253.61 + g.addEdge(nodes[3], nodes[12]);
253.62 + g.addEdge(nodes[6], nodes[9]);
253.63 + g.addEdge(nodes[9], nodes[11]);
253.64 + g.addEdge(nodes[2], nodes[10]);
253.65 + g.addEdge(nodes[10], nodes[8]);
253.66 + g.addEdge(nodes[5], nodes[8]);
253.67 + g.addEdge(nodes[6], nodes[3]);
253.68 + g.addEdge(nodes[0], nodes[5]);
253.69 + g.addEdge(nodes[6], nodes[12]);
253.70 +
253.71 + MaxMatching<Graph> max_matching(g);
253.72 + max_matching.runEdmonds(0);
253.73 +
253.74 + int s=0;
253.75 + Graph::NodeMap<Node> mate(g,INVALID);
253.76 + max_matching.writeNMapNode(mate);
253.77 + for(NodeIt v(g); v!=INVALID; ++v) {
253.78 + if ( mate[v]!=INVALID ) ++s;
253.79 + }
253.80 + int size=(int)s/2; //size will be used as the size of a maxmatching
253.81 +
253.82 + for(NodeIt v(g); v!=INVALID; ++v) {
253.83 + max_matching.mate(v);
253.84 + }
253.85 +
253.86 + check ( size == max_matching.size(), "mate() returns a different size matching than max_matching.size()" );
253.87 +
253.88 + Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos0(g);
253.89 + max_matching.writePos(pos0);
253.90 +
253.91 + max_matching.resetMatching();
253.92 + max_matching.runEdmonds(1);
253.93 + s=0;
253.94 + max_matching.writeNMapNode(mate);
253.95 + for(NodeIt v(g); v!=INVALID; ++v) {
253.96 + if ( mate[v]!=INVALID ) ++s;
253.97 + }
253.98 + check ( (int)s/2 == size, "The size does not equal!" );
253.99 +
253.100 + Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos1(g);
253.101 + max_matching.writePos(pos1);
253.102 +
253.103 + max_matching.run();
253.104 + s=0;
253.105 + max_matching.writeNMapNode(mate);
253.106 + for(NodeIt v(g); v!=INVALID; ++v) {
253.107 + if ( mate[v]!=INVALID ) ++s;
253.108 + }
253.109 + check ( (int)s/2 == size, "The size does not equal!" );
253.110 +
253.111 + Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos2(g);
253.112 + max_matching.writePos(pos2);
253.113 +
253.114 + max_matching.resetMatching();
253.115 + max_matching.run();
253.116 + s=0;
253.117 + max_matching.writeNMapNode(mate);
253.118 + for(NodeIt v(g); v!=INVALID; ++v) {
253.119 + if ( mate[v]!=INVALID ) ++s;
253.120 + }
253.121 + check ( (int)s/2 == size, "The size does not equal!" );
253.122 +
253.123 + Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos(g);
253.124 + max_matching.writePos(pos);
253.125 +
253.126 + bool ismatching=true;
253.127 + for(NodeIt v(g); v!=INVALID; ++v) {
253.128 + if ( mate[v]!=INVALID ) {
253.129 + Node u=mate[v];
253.130 + if (mate[u]!=v) ismatching=false;
253.131 + }
253.132 + }
253.133 + check ( ismatching, "It is not a matching!" );
253.134 +
253.135 + bool coincide=true;
253.136 + for(NodeIt v(g); v!=INVALID; ++v) {
253.137 + if ( pos0[v] != pos1[v] || pos1[v]!=pos2[v] || pos2[v]!=pos[v] ) {
253.138 + coincide=false;
253.139 + }
253.140 + }
253.141 + check ( coincide, "The decompositions do not coincide! " );
253.142 +
253.143 + bool noedge=true;
253.144 + for(UndirEdgeIt e(g); e!=INVALID; ++e) {
253.145 + if ( (pos[g.target(e)]==max_matching.C && pos[g.source(e)]==max_matching.D) ||
253.146 + (pos[g.target(e)]==max_matching.D && pos[g.source(e)]==max_matching.C) )
253.147 + noedge=false;
253.148 + }
253.149 + check ( noedge, "There are edges between D and C!" );
253.150 +
253.151 + bool oddcomp=true;
253.152 + Graph::NodeMap<bool> todo(g,true);
253.153 + int num_comp=0;
253.154 + for(NodeIt v(g); v!=INVALID; ++v) {
253.155 + if ( pos[v]==max_matching.D && todo[v] ) {
253.156 + int comp_size=1;
253.157 + ++num_comp;
253.158 + std::queue<Node> Q;
253.159 + Q.push(v);
253.160 + todo.set(v,false);
253.161 + while (!Q.empty()) {
253.162 + Node w=Q.front();
253.163 + Q.pop();
253.164 + for(IncEdgeIt e(g,w); e!=INVALID; ++e) {
253.165 + Node u=g.runningNode(e);
253.166 + if ( pos[u]==max_matching.D && todo[u] ) {
253.167 + ++comp_size;
253.168 + Q.push(u);
253.169 + todo.set(u,false);
253.170 + }
253.171 + }
253.172 + }
253.173 + if ( !(comp_size % 2) ) oddcomp=false;
253.174 + }
253.175 + }
253.176 + check ( oddcomp, "A component of g[D] is not odd." );
253.177 +
253.178 + int barrier=0;
253.179 + for(NodeIt v(g); v!=INVALID; ++v) {
253.180 + if ( pos[v]==max_matching.A ) ++barrier;
253.181 + }
253.182 + int expected_size=(int)( countNodes(g)-num_comp+barrier)/2;
253.183 + check ( size==expected_size, "The size of the matching is wrong." );
253.184 +
253.185 + return 0;
253.186 +}
254.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
254.2 +++ b/test/min_cost_flow_test.cc Mon May 23 04:48:14 2005 +0000
254.3 @@ -0,0 +1,126 @@
254.4 +/* -*- C++ -*-
254.5 + * test/min_cost_flow_test.cc - Part of LEMON, a generic C++ optimization library
254.6 + *
254.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
254.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
254.9 + *
254.10 + * Permission to use, modify and distribute this software is granted
254.11 + * provided that this copyright notice appears in all copies. For
254.12 + * precise terms see the accompanying LICENSE file.
254.13 + *
254.14 + * This software is provided "AS IS" with no warranty of any kind,
254.15 + * express or implied, and with no claim as to its suitability for any
254.16 + * purpose.
254.17 + *
254.18 + */
254.19 +
254.20 +#include <iostream>
254.21 +#include "test_tools.h"
254.22 +#include <lemon/list_graph.h>
254.23 +#include <lemon/min_cost_flow.h>
254.24 +//#include <path.h>
254.25 +//#include <maps.h>
254.26 +
254.27 +using namespace lemon;
254.28 +
254.29 +
254.30 +bool passed = true;
254.31 +/*
254.32 +void check(bool rc, char *msg="") {
254.33 + passed = passed && rc;
254.34 + if(!rc) {
254.35 + std::cerr << "Test failed! ("<< msg << ")" << std::endl; \
254.36 +
254.37 +
254.38 + }
254.39 +}
254.40 +*/
254.41 +
254.42 +
254.43 +int main()
254.44 +{
254.45 + typedef ListGraph Graph;
254.46 + typedef Graph::Node Node;
254.47 + typedef Graph::Edge Edge;
254.48 +
254.49 + Graph graph;
254.50 +
254.51 + //Ahuja könyv példája
254.52 +
254.53 + Node s=graph.addNode();
254.54 + Node v1=graph.addNode();
254.55 + Node v2=graph.addNode();
254.56 + Node v3=graph.addNode();
254.57 + Node v4=graph.addNode();
254.58 + Node v5=graph.addNode();
254.59 + Node t=graph.addNode();
254.60 +
254.61 + Edge s_v1=graph.addEdge(s, v1);
254.62 + Edge v1_v2=graph.addEdge(v1, v2);
254.63 + Edge s_v3=graph.addEdge(s, v3);
254.64 + Edge v2_v4=graph.addEdge(v2, v4);
254.65 + Edge v2_v5=graph.addEdge(v2, v5);
254.66 + Edge v3_v5=graph.addEdge(v3, v5);
254.67 + Edge v4_t=graph.addEdge(v4, t);
254.68 + Edge v5_t=graph.addEdge(v5, t);
254.69 +
254.70 +
254.71 + Graph::EdgeMap<int> length(graph);
254.72 +
254.73 + length.set(s_v1, 6);
254.74 + length.set(v1_v2, 4);
254.75 + length.set(s_v3, 10);
254.76 + length.set(v2_v4, 5);
254.77 + length.set(v2_v5, 1);
254.78 + length.set(v3_v5, 4);
254.79 + length.set(v4_t, 8);
254.80 + length.set(v5_t, 8);
254.81 +
254.82 + Graph::EdgeMap<int> capacity(graph);
254.83 +
254.84 + capacity.set(s_v1, 2);
254.85 + capacity.set(v1_v2, 2);
254.86 + capacity.set(s_v3, 1);
254.87 + capacity.set(v2_v4, 1);
254.88 + capacity.set(v2_v5, 1);
254.89 + capacity.set(v3_v5, 1);
254.90 + capacity.set(v4_t, 1);
254.91 + capacity.set(v5_t, 2);
254.92 +
254.93 + // ConstMap<Edge, int> const1map(1);
254.94 + std::cout << "Mincostflows algorithm test..." << std::endl;
254.95 +
254.96 + MinCostFlow< Graph, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
254.97 + surb_test(graph, length, capacity, s, t);
254.98 +
254.99 + int k=1;
254.100 +
254.101 + surb_test.augment();
254.102 + check( surb_test.flowValue() == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
254.103 +
254.104 + check( surb_test.run(k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
254.105 +
254.106 + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
254.107 +
254.108 + k=2;
254.109 +
254.110 + check( surb_test.run(k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41");
254.111 +
254.112 + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
254.113 +
254.114 + surb_test.augment();
254.115 + surb_test.augment();
254.116 + surb_test.augment();
254.117 + k=4;
254.118 +
254.119 + check( surb_test.run(k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64");
254.120 +
254.121 + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
254.122 +
254.123 +
254.124 + std::cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
254.125 + << std::endl;
254.126 +
254.127 + return passed ? 0 : 1;
254.128 +
254.129 +}
255.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
255.2 +++ b/test/path_test.cc Mon May 23 04:48:14 2005 +0000
255.3 @@ -0,0 +1,96 @@
255.4 +/* -*- C++ -*-
255.5 + * test/path_test.cc - Part of LEMON, a generic C++ optimization library
255.6 + *
255.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
255.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
255.9 + *
255.10 + * Permission to use, modify and distribute this software is granted
255.11 + * provided that this copyright notice appears in all copies. For
255.12 + * precise terms see the accompanying LICENSE file.
255.13 + *
255.14 + * This software is provided "AS IS" with no warranty of any kind,
255.15 + * express or implied, and with no claim as to its suitability for any
255.16 + * purpose.
255.17 + *
255.18 + */
255.19 +
255.20 +#include <string>
255.21 +#include <iostream>
255.22 +#include <lemon/concept/path.h>
255.23 +#include <lemon/path.h>
255.24 +#include <lemon/list_graph.h>
255.25 +
255.26 +using namespace std;
255.27 +using namespace lemon;
255.28 +using namespace lemon::concept;
255.29 +
255.30 +template<class Path> void checkCompilePath(Path &P)
255.31 +{
255.32 + typedef typename Path::EdgeIt EdgeIt;
255.33 + typedef typename Path::NodeIt NodeIt;
255.34 + typedef typename Path::GraphNode GraphNode;
255.35 + typedef typename Path::GraphEdge GraphEdge;
255.36 + //typedef typename Path::Builder Builder;
255.37 + //??? ha csinalok ilyet es siman Builderrel peldanyositok, akkor warningol. Talan friend miatt? De ki az?
255.38 +
255.39 + EdgeIt ei;
255.40 + NodeIt ni;
255.41 + GraphNode gn;
255.42 + GraphEdge ge;
255.43 +
255.44 + size_t st;
255.45 + bool b;
255.46 +
255.47 + //Path(const Graph &_G) {} //the constructor has been already called
255.48 +
255.49 + st=P.length(); //size_t length() const {return 0;}
255.50 + b=P.empty(); //bool empty() const {}
255.51 + P.clear(); //void clear() {}
255.52 +
255.53 + gn=P.target(); //GraphNode/*It*/ target() const {return INVALID;}
255.54 + gn=P.source(); //GraphNode/*It*/ source() const {return INVALID;}
255.55 +
255.56 + ei=P.first(ei); //It& first(It &i) const { return i=It(*this); }
255.57 +
255.58 + ni=P.target(ei); //NodeIt target(const EdgeIt& e) const {}
255.59 + ni=P.source(ei); //NodeIt source(const EdgeIt& e) const {}
255.60 +
255.61 +
255.62 + ListGraph lg;
255.63 + Path p(lg);
255.64 +
255.65 + EdgeIt i; //EdgeIt() {}
255.66 + EdgeIt j(INVALID); //EdgeIt(Invalid) {}
255.67 + EdgeIt k(p); //EdgeIt(const Path &_p) {}
255.68 +
255.69 + i=++j; //EdgeIt& operator++() {}
255.70 + ++k;
255.71 + b=(i==j); //bool operator==(const EdgeIt& e) const {return true;}
255.72 + b=(i!=j); //bool operator!=(const EdgeIt& e) const {return true;}
255.73 +
255.74 +
255.75 + NodeIt l; //NodeIt() {}
255.76 + NodeIt m(INVALID); //NodeIt(Invalid) {}
255.77 + NodeIt n(p); //NodeIt(const Path &_p) {}
255.78 +
255.79 + l=++m; //NodeIt& operator++() {}
255.80 + b=(m==n); //bool operator==(const NodeIt& e) const {}
255.81 + b=(m!=n); //bool operator!=(const NodeIt& e) const {}
255.82 +
255.83 + typename Path::Builder builder(p); //Builder(Path &_P) : P(_P) {}
255.84 + builder.setStartNode(gn); //void setStartNode(const GraphNode &) {}
255.85 + builder.pushFront(ge); //void pushFront(const GraphEdge& e) {}
255.86 + builder.pushBack(ge); //void pushBack(const GraphEdge& e) {}
255.87 + builder.commit(); //void commit() {}
255.88 + builder.reserveFront(st); //void reserveFront(size_t r) {}
255.89 + builder.reserveBack(st); //void reserveBack(size_t r) {}
255.90 +
255.91 +}
255.92 +
255.93 +template void checkCompilePath< concept::Path<ListGraph> >(concept::Path<ListGraph> &);
255.94 +template void checkCompilePath< DirPath<ListGraph> >(DirPath<ListGraph> &);
255.95 +template void checkCompilePath< UndirPath<ListGraph> >(UndirPath<ListGraph> &);
255.96 +
255.97 +int main()
255.98 +{
255.99 +}
256.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
256.2 +++ b/test/preflow_graph.dim Mon May 23 04:48:14 2005 +0000
256.3 @@ -0,0 +1,20 @@
256.4 +p max 10 17
256.5 +n 2 s
256.6 +n 9 t
256.7 +a 1 2 20
256.8 +a 1 3 0
256.9 +a 2 2 3
256.10 +a 2 3 8
256.11 +a 2 4 8
256.12 +a 3 6 5
256.13 +a 4 3 5
256.14 +a 4 6 5
256.15 +a 4 7 5
256.16 +a 5 4 3
256.17 +a 6 8 3
256.18 +a 6 7 10
256.19 +a 6 9 10
256.20 +a 7 9 8
256.21 +a 9 10 20
256.22 +a 9 2 5
256.23 +a 10 6 5
256.24 \ No newline at end of file
257.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
257.2 +++ b/test/preflow_test.cc Mon May 23 04:48:14 2005 +0000
257.3 @@ -0,0 +1,201 @@
257.4 +/* -*- C++ -*-
257.5 + * test/preflow_test.cc - Part of LEMON, a generic C++ optimization library
257.6 + *
257.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
257.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
257.9 + *
257.10 + * Permission to use, modify and distribute this software is granted
257.11 + * provided that this copyright notice appears in all copies. For
257.12 + * precise terms see the accompanying LICENSE file.
257.13 + *
257.14 + * This software is provided "AS IS" with no warranty of any kind,
257.15 + * express or implied, and with no claim as to its suitability for any
257.16 + * purpose.
257.17 + *
257.18 + */
257.19 +
257.20 +#include <fstream>
257.21 +#include <string>
257.22 +
257.23 +#include "test_tools.h"
257.24 +#include <lemon/smart_graph.h>
257.25 +#include <lemon/dimacs.h>
257.26 +#include <lemon/preflow.h>
257.27 +#include <lemon/concept/graph.h>
257.28 +#include <lemon/concept/maps.h>
257.29 +
257.30 +using namespace lemon;
257.31 +
257.32 +void check_Preflow()
257.33 +{
257.34 + typedef int VType;
257.35 + typedef concept::StaticGraph Graph;
257.36 +
257.37 + typedef Graph::Node Node;
257.38 + typedef Graph::Edge Edge;
257.39 + typedef concept::ReadMap<Edge,VType> CapMap;
257.40 + typedef concept::ReadWriteMap<Edge,VType> FlowMap;
257.41 + typedef concept::ReadWriteMap<Node,bool> CutMap;
257.42 +
257.43 + typedef Preflow<Graph, int, CapMap, FlowMap> PType;
257.44 +
257.45 + Graph g;
257.46 + Node n;
257.47 + CapMap cap;
257.48 + FlowMap flow;
257.49 + CutMap cut;
257.50 +
257.51 + PType preflow_test(g,n,n,cap,flow);
257.52 +
257.53 + preflow_test.run();
257.54 + preflow_test.flowValue();
257.55 + preflow_test.source(n);
257.56 + preflow_test.flowMap(flow);
257.57 +
257.58 + preflow_test.phase1(PType::NO_FLOW);
257.59 + preflow_test.minCut(cut);
257.60 +
257.61 + preflow_test.phase2();
257.62 + preflow_test.target(n);
257.63 + preflow_test.capacityMap(cap);
257.64 + preflow_test.minMinCut(cut);
257.65 + preflow_test.maxMinCut(cut);
257.66 +}
257.67 +
257.68 +int cut_value ( SmartGraph& g, SmartGraph::NodeMap<bool>& cut,
257.69 + SmartGraph::EdgeMap<int>& cap) {
257.70 +
257.71 + int c=0;
257.72 + for(SmartGraph::EdgeIt e(g); e!=INVALID; ++e) {
257.73 + if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
257.74 + }
257.75 + return c;
257.76 +}
257.77 +
257.78 +int main() {
257.79 +
257.80 + typedef SmartGraph Graph;
257.81 +
257.82 + typedef Graph::Node Node;
257.83 + typedef Graph::NodeIt NodeIt;
257.84 + typedef Graph::EdgeIt EdgeIt;
257.85 + typedef Graph::EdgeMap<int> CapMap;
257.86 + typedef Graph::EdgeMap<int> FlowMap;
257.87 + typedef Graph::NodeMap<bool> CutMap;
257.88 +
257.89 + typedef Preflow<Graph, int> PType;
257.90 +
257.91 + std::string f_name;
257.92 + if( getenv("srcdir") )
257.93 + f_name = std::string(getenv("srcdir"));
257.94 + else f_name = ".";
257.95 + f_name += "/preflow_graph.dim";
257.96 +
257.97 + std::ifstream file(f_name.c_str());
257.98 +
257.99 + check(file, "Input file '" << f_name << "' not found.");
257.100 +
257.101 + Graph g;
257.102 + Node s, t;
257.103 + CapMap cap(g);
257.104 + readDimacs(file, g, cap, s, t);
257.105 +
257.106 + FlowMap flow(g,0);
257.107 +
257.108 +
257.109 +
257.110 + PType preflow_test(g, s, t, cap, flow);
257.111 + preflow_test.run(PType::ZERO_FLOW);
257.112 +
257.113 + CutMap min_cut(g,false);
257.114 + preflow_test.minCut(min_cut);
257.115 + int min_cut_value=cut_value(g,min_cut,cap);
257.116 +
257.117 + CutMap min_min_cut(g,false);
257.118 + preflow_test.minMinCut(min_min_cut);
257.119 + int min_min_cut_value=cut_value(g,min_min_cut,cap);
257.120 +
257.121 + CutMap max_min_cut(g,false);
257.122 + preflow_test.maxMinCut(max_min_cut);
257.123 + int max_min_cut_value=cut_value(g,max_min_cut,cap);
257.124 +
257.125 + check(preflow_test.flowValue() == min_cut_value &&
257.126 + min_cut_value == min_min_cut_value &&
257.127 + min_min_cut_value == max_min_cut_value,
257.128 + "The max flow value is not equal to the three min cut values.");
257.129 +
257.130 + int flow_value=preflow_test.flowValue();
257.131 +
257.132 +
257.133 +
257.134 + for(EdgeIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
257.135 + preflow_test.capacityMap(cap);
257.136 +
257.137 + preflow_test.phase1(PType::PRE_FLOW);
257.138 +
257.139 + CutMap min_cut1(g,false);
257.140 + preflow_test.minCut(min_cut1);
257.141 + min_cut_value=cut_value(g,min_cut1,cap);
257.142 +
257.143 + check(preflow_test.flowValue() == min_cut_value &&
257.144 + min_cut_value == 2*flow_value,
257.145 + "The max flow value or the min cut value is wrong.");
257.146 +
257.147 + preflow_test.phase2();
257.148 +
257.149 + CutMap min_cut2(g,false);
257.150 + preflow_test.minCut(min_cut2);
257.151 + min_cut_value=cut_value(g,min_cut2,cap);
257.152 +
257.153 + CutMap min_min_cut2(g,false);
257.154 + preflow_test.minMinCut(min_min_cut2);
257.155 + min_min_cut_value=cut_value(g,min_min_cut2,cap);
257.156 +
257.157 + preflow_test.maxMinCut(max_min_cut);
257.158 + max_min_cut_value=cut_value(g,max_min_cut,cap);
257.159 +
257.160 + check(preflow_test.flowValue() == min_cut_value &&
257.161 + min_cut_value == min_min_cut_value &&
257.162 + min_min_cut_value == max_min_cut_value &&
257.163 + min_cut_value == 2*flow_value,
257.164 + "The max flow value or the three min cut values were not doubled");
257.165 +
257.166 +
257.167 +
257.168 + EdgeIt e(g);
257.169 + for( int i=1; i==10; ++i ) {
257.170 + flow.set(e,0);
257.171 + ++e;
257.172 + }
257.173 +
257.174 + preflow_test.flowMap(flow);
257.175 +
257.176 + NodeIt tmp1(g,s);
257.177 + ++tmp1;
257.178 + if ( tmp1 != INVALID ) s=tmp1;
257.179 +
257.180 + NodeIt tmp2(g,t);
257.181 + ++tmp2;
257.182 + if ( tmp2 != INVALID ) t=tmp2;
257.183 +
257.184 + preflow_test.source(s);
257.185 + preflow_test.target(t);
257.186 +
257.187 + preflow_test.run();
257.188 +
257.189 + CutMap min_cut3(g,false);
257.190 + preflow_test.minCut(min_cut3);
257.191 + min_cut_value=cut_value(g,min_cut3,cap);
257.192 +
257.193 + CutMap min_min_cut3(g,false);
257.194 + preflow_test.minMinCut(min_min_cut3);
257.195 + min_min_cut_value=cut_value(g,min_min_cut3,cap);
257.196 +
257.197 + preflow_test.maxMinCut(max_min_cut);
257.198 + max_min_cut_value=cut_value(g,max_min_cut,cap);
257.199 +
257.200 + check(preflow_test.flowValue() == min_cut_value &&
257.201 + min_cut_value == min_min_cut_value &&
257.202 + min_min_cut_value == max_min_cut_value,
257.203 + "The max flow value or the three min cut values are incorrect.");
257.204 +}
258.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
258.2 +++ b/test/suurballe_test.cc Mon May 23 04:48:14 2005 +0000
258.3 @@ -0,0 +1,108 @@
258.4 +/* -*- C++ -*-
258.5 + * test/suurballe_test.cc - Part of LEMON, a generic C++ optimization library
258.6 + *
258.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
258.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
258.9 + *
258.10 + * Permission to use, modify and distribute this software is granted
258.11 + * provided that this copyright notice appears in all copies. For
258.12 + * precise terms see the accompanying LICENSE file.
258.13 + *
258.14 + * This software is provided "AS IS" with no warranty of any kind,
258.15 + * express or implied, and with no claim as to its suitability for any
258.16 + * purpose.
258.17 + *
258.18 + */
258.19 +
258.20 +#include <iostream>
258.21 +#include <lemon/list_graph.h>
258.22 +#include <lemon/suurballe.h>
258.23 +//#include <path.h>
258.24 +#include "test_tools.h"
258.25 +
258.26 +using namespace lemon;
258.27 +
258.28 +
258.29 +bool passed = true;
258.30 +
258.31 +
258.32 +int main()
258.33 +{
258.34 + typedef ListGraph Graph;
258.35 + typedef Graph::Node Node;
258.36 + typedef Graph::Edge Edge;
258.37 +
258.38 + Graph graph;
258.39 +
258.40 + //Ahuja könyv példája
258.41 +
258.42 + Node s=graph.addNode();
258.43 + Node v1=graph.addNode();
258.44 + Node v2=graph.addNode();
258.45 + Node v3=graph.addNode();
258.46 + Node v4=graph.addNode();
258.47 + Node v5=graph.addNode();
258.48 + Node t=graph.addNode();
258.49 +
258.50 + Edge s_v1=graph.addEdge(s, v1);
258.51 + Edge v1_v2=graph.addEdge(v1, v2);
258.52 + Edge s_v3=graph.addEdge(s, v3);
258.53 + Edge v2_v4=graph.addEdge(v2, v4);
258.54 + Edge v2_v5=graph.addEdge(v2, v5);
258.55 + Edge v3_v5=graph.addEdge(v3, v5);
258.56 + Edge v4_t=graph.addEdge(v4, t);
258.57 + Edge v5_t=graph.addEdge(v5, t);
258.58 +
258.59 +
258.60 + Graph::EdgeMap<int> length(graph);
258.61 +
258.62 + length.set(s_v1, 6);
258.63 + length.set(v1_v2, 4);
258.64 + length.set(s_v3, 10);
258.65 + length.set(v2_v4, 5);
258.66 + length.set(v2_v5, 1);
258.67 + length.set(v3_v5, 5);
258.68 + length.set(v4_t, 8);
258.69 + length.set(v5_t, 8);
258.70 +
258.71 + std::cout << "Minlengthpaths algorithm test..." << std::endl;
258.72 +
258.73 +
258.74 + int k=3;
258.75 + Suurballe< Graph, Graph::EdgeMap<int> >
258.76 + surb_test(graph, length, s, t);
258.77 +
258.78 + check( surb_test.run(k) == 2 && surb_test.totalLength() == 46,
258.79 + "Two paths, total length should be 46");
258.80 +
258.81 + check( surb_test.checkComplementarySlackness(),
258.82 + "Complementary slackness conditions are not met.");
258.83 +
258.84 + // typedef DirPath<Graph> DPath;
258.85 + // DPath P(graph);
258.86 +
258.87 + /*
258.88 + surb_test.getPath(P,0);
258.89 + check(P.length() == 4, "First path should contain 4 edges.");
258.90 + std::cout<<P.length()<<std::endl;
258.91 + surb_test.getPath(P,1);
258.92 + check(P.length() == 3, "Second path: 3 edges.");
258.93 + std::cout<<P.length()<<std::endl;
258.94 + */
258.95 +
258.96 + k=1;
258.97 + check( surb_test.run(k) == 1 && surb_test.totalLength() == 19,
258.98 + "One path, total length should be 19");
258.99 +
258.100 + check( surb_test.checkComplementarySlackness(),
258.101 + "Complementary slackness conditions are not met.");
258.102 +
258.103 + // surb_test.getPath(P,0);
258.104 + // check(P.length() == 4, "First path should contain 4 edges.");
258.105 +
258.106 + std::cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
258.107 + << std::endl;
258.108 +
258.109 + return passed ? 0 : 1;
258.110 +
258.111 +}
259.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
259.2 +++ b/test/sym_graph_test.cc Mon May 23 04:48:14 2005 +0000
259.3 @@ -0,0 +1,98 @@
259.4 +/* -*- C++ -*-
259.5 + * test/sym_graph_test.cc - Part of LEMON, a generic C++ optimization library
259.6 + *
259.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
259.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
259.9 + *
259.10 + * Permission to use, modify and distribute this software is granted
259.11 + * provided that this copyright notice appears in all copies. For
259.12 + * precise terms see the accompanying LICENSE file.
259.13 + *
259.14 + * This software is provided "AS IS" with no warranty of any kind,
259.15 + * express or implied, and with no claim as to its suitability for any
259.16 + * purpose.
259.17 + *
259.18 + */
259.19 +
259.20 +#include<iostream>
259.21 +
259.22 +#include<lemon/concept/sym_graph.h>
259.23 +
259.24 +#include<lemon/list_graph.h>
259.25 +#include<lemon/smart_graph.h>
259.26 +#include<lemon/full_graph.h>
259.27 +
259.28 +#include"test_tools.h"
259.29 +#include"graph_test.h"
259.30 +#include"sym_graph_test.h"
259.31 +
259.32 +/**
259.33 +\file
259.34 +This test makes consistency checks of list graph structures.
259.35 +
259.36 +G.addNode(), G.addEdge(), G.source(), G.target()
259.37 +
259.38 +\todo Checks for empty graphs and isolated points.
259.39 +conversion.
259.40 +*/
259.41 +
259.42 +using namespace lemon;
259.43 +
259.44 +template<class Graph> void checkPetersen(Graph &G)
259.45 +{
259.46 + typedef typename Graph::NodeIt NodeIt;
259.47 +
259.48 +
259.49 + checkGraphNodeList(G,10);
259.50 + checkGraphEdgeList(G,30);
259.51 + checkGraphSymEdgeList(G,15);
259.52 +
259.53 + for(NodeIt n(G);n!=INVALID;++n) {
259.54 + checkGraphInEdgeList(G,n,3);
259.55 + checkGraphOutEdgeList(G,n,3);
259.56 + }
259.57 +}
259.58 +
259.59 +//Compile Graph
259.60 +template void lemon::checkCompileStaticSymGraph<concept::StaticSymGraph>
259.61 +(concept::StaticSymGraph &);
259.62 +
259.63 +template void lemon::checkCompileSymGraph<concept::ExtendableSymGraph>
259.64 +(concept::ExtendableSymGraph &);
259.65 +
259.66 +template void lemon::checkCompileErasableSymGraph<concept::ErasableSymGraph>
259.67 +(concept::ErasableSymGraph &);
259.68 +
259.69 +
259.70 +//Compile SymSmartGraph
259.71 +template void lemon::checkCompileSymGraph<SymSmartGraph>(SymSmartGraph &);
259.72 +template
259.73 +void lemon::concept::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
259.74 +
259.75 +//Compile SymListGraph
259.76 +template void lemon::checkCompileSymGraph<SymListGraph>(SymListGraph &);
259.77 +template void lemon::checkCompileErasableSymGraph<SymListGraph>(SymListGraph &);
259.78 +template
259.79 +void lemon::concept::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
259.80 +
259.81 +int main()
259.82 +{
259.83 + {
259.84 + SymSmartGraph G;
259.85 + addSymPetersen(G);
259.86 + checkPetersen(G);
259.87 + }
259.88 + {
259.89 + SymListGraph G;
259.90 + addSymPetersen(G);
259.91 + checkPetersen(G);
259.92 + }
259.93 +
259.94 + ///\file
259.95 + ///\todo map tests.
259.96 + ///\todo copy constr tests.
259.97 +
259.98 + std::cout << __FILE__ ": All tests passed.\n";
259.99 +
259.100 + return 0;
259.101 +}
260.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
260.2 +++ b/test/sym_graph_test.h Mon May 23 04:48:14 2005 +0000
260.3 @@ -0,0 +1,183 @@
260.4 +/* -*- C++ -*-
260.5 + * test/sym_graph_test.h - Part of LEMON, a generic C++ optimization library
260.6 + *
260.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
260.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
260.9 + *
260.10 + * Permission to use, modify and distribute this software is granted
260.11 + * provided that this copyright notice appears in all copies. For
260.12 + * precise terms see the accompanying LICENSE file.
260.13 + *
260.14 + * This software is provided "AS IS" with no warranty of any kind,
260.15 + * express or implied, and with no claim as to its suitability for any
260.16 + * purpose.
260.17 + *
260.18 + */
260.19 +#ifndef LEMON_TEST_SYM_GRAPH_TEST_H
260.20 +#define LEMON_TEST_SYM_GRAPH_TEST_H
260.21 +
260.22 +
260.23 +#include "graph_test.h"
260.24 +#include "test_tools.h"
260.25 +
260.26 +//! \ingroup misc
260.27 +//! \file
260.28 +//! \brief Some utility to test symmetric graph classes.
260.29 +namespace lemon {
260.30 +
260.31 + /// \e
260.32 +
260.33 + /// \todo This should go to lemon/concept/symgraph.h
260.34 + ///
260.35 + template<class Graph> void checkCompileStaticSymGraph(Graph &G)
260.36 + {
260.37 + typedef typename Graph::Node Node;
260.38 + typedef typename Graph::NodeIt NodeIt;
260.39 + typedef typename Graph::SymEdge SymEdge;
260.40 + typedef typename Graph::SymEdgeIt SymEdgeIt;
260.41 + typedef typename Graph::Edge Edge;
260.42 + typedef typename Graph::EdgeIt EdgeIt;
260.43 + typedef typename Graph::InEdgeIt InEdgeIt;
260.44 + typedef typename Graph::OutEdgeIt OutEdgeIt;
260.45 +
260.46 + lemon::concept::checkCompileStaticGraph(G);
260.47 +
260.48 + {
260.49 + SymEdge i; SymEdge j(i); SymEdge k(INVALID);
260.50 + i=j;
260.51 + bool b; b=true;
260.52 + b=(i==INVALID); b=(i!=INVALID);
260.53 + b=(i==j); b=(i!=j); b=(i<j);
260.54 + Edge e;
260.55 + e = G.forward(i);
260.56 + e = G.backward(i);
260.57 + }
260.58 + {
260.59 + SymEdgeIt i; SymEdgeIt j(i); SymEdgeIt k(INVALID); SymEdgeIt l(G);
260.60 + i=j;
260.61 + j=G.first(i);
260.62 + j=++i;
260.63 + bool b; b=true;
260.64 + b=(i==INVALID); b=(i!=INVALID);
260.65 + SymEdge n(i);
260.66 + n=i;
260.67 + b=(i==j); b=(i!=j); b=(i<j);
260.68 + //SymEdge ->SymEdgeIt conversion
260.69 + SymEdgeIt ni(G,n);
260.70 + }
260.71 + {
260.72 + Edge i, j;
260.73 + j = G.opposite(i);
260.74 + }
260.75 + {
260.76 + Node n;
260.77 + SymEdge se;
260.78 + se=INVALID;
260.79 + n=G.source(se);
260.80 + n=G.target(se);
260.81 + }
260.82 + // id tests
260.83 + { SymEdge n; int i=G.id(n); i=i; }
260.84 + //SymEdgeMap tests
260.85 + {
260.86 + SymEdge k;
260.87 + typename Graph::template SymEdgeMap<int> m(G);
260.88 + typename Graph::template SymEdgeMap<int> const &cm = m; //Const map
260.89 + //Inicialize with default value
260.90 + typename Graph::template SymEdgeMap<int> mdef(G,12);
260.91 + typename Graph::template SymEdgeMap<int> mm(cm); //Copy
260.92 + typename Graph::template SymEdgeMap<double> dm(cm); //Copy from another type
260.93 + int v;
260.94 + v=m[k]; m[k]=v; m.set(k,v);
260.95 + v=cm[k];
260.96 +
260.97 + m=cm;
260.98 + dm=cm; //Copy from another type
260.99 + {
260.100 + //Check the typedef's
260.101 + typename Graph::template SymEdgeMap<int>::Value val;
260.102 + val = 1;
260.103 + typename Graph::template SymEdgeMap<int>::Key key;
260.104 + key = typename Graph::SymEdgeIt(G);
260.105 + }
260.106 + }
260.107 + { //bool SymEdgeMap
260.108 + SymEdge k;
260.109 + typename Graph::template SymEdgeMap<bool> m(G);
260.110 + typename Graph::template SymEdgeMap<bool> const &cm = m; //Const map
260.111 + //Inicialize with default value
260.112 + typename Graph::template SymEdgeMap<bool> mdef(G,12);
260.113 + typename Graph::template SymEdgeMap<bool> mm(cm); //Copy
260.114 + typename Graph::template SymEdgeMap<int> dm(cm); //Copy from another type
260.115 + bool v;
260.116 + v=m[k]; m[k]=v; m.set(k,v);
260.117 + v=cm[k];
260.118 +
260.119 + m=cm;
260.120 + dm=cm; //Copy from another type
260.121 + m=dm; //Copy to another type
260.122 + {
260.123 + //Check the typedef's
260.124 + typename Graph::template SymEdgeMap<bool>::Value val;
260.125 + val=true;
260.126 + typename Graph::template SymEdgeMap<bool>::Key key;
260.127 + key= typename Graph::SymEdgeIt(G);
260.128 + }
260.129 + }
260.130 + }
260.131 +
260.132 + template<class Graph> void checkCompileSymGraph(Graph &G)
260.133 + {
260.134 + checkCompileStaticSymGraph(G);
260.135 +
260.136 + typedef typename Graph::Node Node;
260.137 + typedef typename Graph::NodeIt NodeIt;
260.138 + typedef typename Graph::SymEdge SymEdge;
260.139 + typedef typename Graph::SymEdgeIt SymEdgeIt;
260.140 + typedef typename Graph::Edge Edge;
260.141 + typedef typename Graph::EdgeIt EdgeIt;
260.142 + typedef typename Graph::InEdgeIt InEdgeIt;
260.143 + typedef typename Graph::OutEdgeIt OutEdgeIt;
260.144 +
260.145 + Node n,m;
260.146 + n=G.addNode();
260.147 + m=G.addNode();
260.148 + SymEdge e;
260.149 + e = G.addEdge(n,m);
260.150 +
260.151 + // G.clear();
260.152 + }
260.153 +
260.154 + template<class Graph> void checkCompileSymGraphEraseSymEdge(Graph &G)
260.155 + {
260.156 + typename Graph::SymEdge n;
260.157 + G.erase(n);
260.158 + }
260.159 +
260.160 + template<class Graph> void checkCompileErasableSymGraph(Graph &G)
260.161 + {
260.162 + checkCompileSymGraph(G);
260.163 + lemon::concept::checkCompileGraphEraseNode(G);
260.164 + checkCompileSymGraphEraseSymEdge(G);
260.165 + }
260.166 +
260.167 + template<class Graph> void checkGraphSymEdgeList(Graph &G, int nn)
260.168 + {
260.169 + typedef typename Graph::SymEdgeIt SymEdgeIt;
260.170 +
260.171 + SymEdgeIt e(G);
260.172 + for(int i=0;i<nn;i++) {
260.173 + check(e!=INVALID,"Wrong SymEdge list linking.");
260.174 + ++e;
260.175 + }
260.176 + check(e==INVALID,"Wrong SymEdge list linking.");
260.177 + }
260.178 +
260.179 + ///\file
260.180 + ///\todo Check target(), source() as well;
260.181 +
260.182 +
260.183 +} //namespace lemon
260.184 +
260.185 +
260.186 +#endif
261.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
261.2 +++ b/test/test_tools.h Mon May 23 04:48:14 2005 +0000
261.3 @@ -0,0 +1,173 @@
261.4 +/* -*- C++ -*-
261.5 + * test/test_tools.h - Part of LEMON, a generic C++ optimization library
261.6 + *
261.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
261.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
261.9 + *
261.10 + * Permission to use, modify and distribute this software is granted
261.11 + * provided that this copyright notice appears in all copies. For
261.12 + * precise terms see the accompanying LICENSE file.
261.13 + *
261.14 + * This software is provided "AS IS" with no warranty of any kind,
261.15 + * express or implied, and with no claim as to its suitability for any
261.16 + * purpose.
261.17 + *
261.18 + */
261.19 +
261.20 +#ifndef LEMON_TEST_TEST_TOOLS_H
261.21 +#define LEMON_TEST_TEST_TOOLS_H
261.22 +
261.23 +#include <iostream>
261.24 +#include <vector>
261.25 +
261.26 +#include <lemon/invalid.h>
261.27 +
261.28 +using namespace lemon;
261.29 +
261.30 +//! \ingroup misc
261.31 +//! \file
261.32 +//! \brief Some utilities to write test programs.
261.33 +
261.34 +
261.35 +///If \c rc is fail, writes an error message end exit.
261.36 +
261.37 +///If \c rc is fail, writes an error message end exit.
261.38 +///The error message contains the file name and the line number of the
261.39 +///source code in a standard from, which makes it possible to go there
261.40 +///using good source browsers like e.g. \c emacs.
261.41 +///
261.42 +///For example
261.43 +///\code check(0==1,"This is obviously false.");\endcode will
261.44 +///print this (and then exits).
261.45 +///\verbatim graph_test.cc:123: error: This is obviously false. \endverbatim
261.46 +///
261.47 +///\todo It should be in \c error.h
261.48 +#define check(rc, msg) \
261.49 + if(!(rc)) { \
261.50 + std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
261.51 + exit(1); \
261.52 + } else { } \
261.53 +
261.54 +///Structure returned by \ref addPetersen().
261.55 +
261.56 +///Structure returned by \ref addPetersen().
261.57 +///
261.58 +template<class Graph> struct PetStruct
261.59 +{
261.60 + ///Vector containing the outer nodes.
261.61 + std::vector<typename Graph::Node> outer;
261.62 + ///Vector containing the inner nodes.
261.63 + std::vector<typename Graph::Node> inner;
261.64 + ///Vector containing the edges of the inner circle.
261.65 + std::vector<typename Graph::Edge> incir;
261.66 + ///Vector containing the edges of the outer circle.
261.67 + std::vector<typename Graph::Edge> outcir;
261.68 + ///Vector containing the chord edges.
261.69 + std::vector<typename Graph::Edge> chords;
261.70 +};
261.71 +
261.72 +
261.73 +
261.74 +///Adds a Petersen graph to \c G.
261.75 +
261.76 +///Adds a Petersen graph to \c G.
261.77 +///\return The nodes and edges of the generated graph.
261.78 +
261.79 +template<typename Graph>
261.80 +PetStruct<Graph> addPetersen(Graph &G,int num = 5)
261.81 +{
261.82 + PetStruct<Graph> n;
261.83 +
261.84 + for(int i=0;i<num;i++) {
261.85 + n.outer.push_back(G.addNode());
261.86 + n.inner.push_back(G.addNode());
261.87 + }
261.88 +
261.89 + for(int i=0;i<num;i++) {
261.90 + n.chords.push_back(G.addEdge(n.outer[i],n.inner[i]));
261.91 + n.outcir.push_back(G.addEdge(n.outer[i],n.outer[(i+1) % num]));
261.92 + n.incir.push_back(G.addEdge(n.inner[i],n.inner[(i+2) % num]));
261.93 + }
261.94 + return n;
261.95 +}
261.96 +
261.97 +/// \brief Adds to the graph the reverse pair of all edges.
261.98 +///
261.99 +/// Adds to the graph the reverse pair of all edges.
261.100 +///
261.101 +template<class Graph> void bidirGraph(Graph &G)
261.102 +{
261.103 + typedef typename Graph::Edge Edge;
261.104 + typedef typename Graph::EdgeIt EdgeIt;
261.105 +
261.106 + std::vector<Edge> ee;
261.107 +
261.108 + for(EdgeIt e(G);e!=INVALID;++e) ee.push_back(e);
261.109 +
261.110 + for(typename std::vector<Edge>::iterator p=ee.begin();p!=ee.end();p++)
261.111 + G.addEdge(G.target(*p),G.source(*p));
261.112 +}
261.113 +
261.114 +
261.115 +/// \brief Checks the bidirectioned Petersen graph.
261.116 +///
261.117 +/// Checks the bidirectioned Petersen graph.
261.118 +///
261.119 +template<class Graph> void checkBidirPetersen(Graph &G, int num = 5)
261.120 +{
261.121 + typedef typename Graph::Node Node;
261.122 +
261.123 + typedef typename Graph::EdgeIt EdgeIt;
261.124 + typedef typename Graph::NodeIt NodeIt;
261.125 +
261.126 + checkGraphNodeList(G, 2 * num);
261.127 + checkGraphEdgeList(G, 6 * num);
261.128 +
261.129 + for(NodeIt n(G);n!=INVALID;++n) {
261.130 + checkGraphInEdgeList(G, n, 3);
261.131 + checkGraphOutEdgeList(G, n, 3);
261.132 + }
261.133 +}
261.134 +
261.135 +///Structure returned by \ref addSymPetersen().
261.136 +
261.137 +///Structure returned by \ref addSymPetersen().
261.138 +///
261.139 +template<class Graph> struct SymPetStruct
261.140 +{
261.141 + ///Vector containing the outer nodes.
261.142 + std::vector<typename Graph::Node> outer;
261.143 + ///Vector containing the inner nodes.
261.144 + std::vector<typename Graph::Node> inner;
261.145 + ///Vector containing the edges of the inner circle.
261.146 + std::vector<typename Graph::SymEdge> incir;
261.147 + ///Vector containing the edges of the outer circle.
261.148 + std::vector<typename Graph::SymEdge> outcir;
261.149 + ///Vector containing the chord edges.
261.150 + std::vector<typename Graph::SymEdge> chords;
261.151 +};
261.152 +
261.153 +///Adds a Petersen graph to the symmetric \c G.
261.154 +
261.155 +///Adds a Petersen graph to the symmetric \c G.
261.156 +///\return The nodes and edges of the generated graph.
261.157 +
261.158 +template<typename Graph>
261.159 +SymPetStruct<Graph> addSymPetersen(Graph &G,int num=5)
261.160 +{
261.161 + SymPetStruct<Graph> n;
261.162 +
261.163 + for(int i=0;i<num;i++) {
261.164 + n.outer.push_back(G.addNode());
261.165 + n.inner.push_back(G.addNode());
261.166 + }
261.167 +
261.168 + for(int i=0;i<num;i++) {
261.169 + n.chords.push_back(G.addEdge(n.outer[i],n.inner[i]));
261.170 + n.outcir.push_back(G.addEdge(n.outer[i],n.outer[(i+1)%5]));
261.171 + n.incir.push_back(G.addEdge(n.inner[i],n.inner[(i+2)%5]));
261.172 + }
261.173 + return n;
261.174 +}
261.175 +
261.176 +#endif
262.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
262.2 +++ b/test/test_tools_fail.cc Mon May 23 04:48:14 2005 +0000
262.3 @@ -0,0 +1,23 @@
262.4 +/* -*- C++ -*-
262.5 + * test/test_tools_fail.cc - Part of LEMON, a generic C++ optimization library
262.6 + *
262.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
262.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
262.9 + *
262.10 + * Permission to use, modify and distribute this software is granted
262.11 + * provided that this copyright notice appears in all copies. For
262.12 + * precise terms see the accompanying LICENSE file.
262.13 + *
262.14 + * This software is provided "AS IS" with no warranty of any kind,
262.15 + * express or implied, and with no claim as to its suitability for any
262.16 + * purpose.
262.17 + *
262.18 + */
262.19 +
262.20 +#include "test_tools.h"
262.21 +
262.22 +int main()
262.23 +{
262.24 + check(false, "Don't panic. Failing is the right behaviour here.");
262.25 + return 0;
262.26 +}
263.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
263.2 +++ b/test/test_tools_pass.cc Mon May 23 04:48:14 2005 +0000
263.3 @@ -0,0 +1,23 @@
263.4 +/* -*- C++ -*-
263.5 + * test/test_tools_pass.cc - Part of LEMON, a generic C++ optimization library
263.6 + *
263.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
263.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
263.9 + *
263.10 + * Permission to use, modify and distribute this software is granted
263.11 + * provided that this copyright notice appears in all copies. For
263.12 + * precise terms see the accompanying LICENSE file.
263.13 + *
263.14 + * This software is provided "AS IS" with no warranty of any kind,
263.15 + * express or implied, and with no claim as to its suitability for any
263.16 + * purpose.
263.17 + *
263.18 + */
263.19 +
263.20 +#include "test_tools.h"
263.21 +
263.22 +int main()
263.23 +{
263.24 + check(true, "It should pass.");
263.25 + return 0;
263.26 +}
264.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
264.2 +++ b/test/time_measure_test.cc Mon May 23 04:48:14 2005 +0000
264.3 @@ -0,0 +1,36 @@
264.4 +/* -*- C++ -*-
264.5 + * test/time_measure_test.cc - Part of LEMON, a generic C++ optimization library
264.6 + *
264.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
264.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
264.9 + *
264.10 + * Permission to use, modify and distribute this software is granted
264.11 + * provided that this copyright notice appears in all copies. For
264.12 + * precise terms see the accompanying LICENSE file.
264.13 + *
264.14 + * This software is provided "AS IS" with no warranty of any kind,
264.15 + * express or implied, and with no claim as to its suitability for any
264.16 + * purpose.
264.17 + *
264.18 + */
264.19 +
264.20 +#include <lemon/time_measure.h>
264.21 +
264.22 +///\file \brief Test cases for time_measure.h
264.23 +///
264.24 +///\todo To be extended
264.25 +
264.26 +
264.27 +using namespace lemon;
264.28 +
264.29 +int main()
264.30 +{
264.31 + Timer T;
264.32 + while(T.getRealTime()<1.0) ;
264.33 + std::cout << T << '\n';
264.34 + T.reset();
264.35 + while(T.getRealTime()<2.0) ;
264.36 + std::cout << T << '\n';
264.37 +
264.38 + return 0;
264.39 +}
265.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
265.2 +++ b/test/undir_graph_test.cc Mon May 23 04:48:14 2005 +0000
265.3 @@ -0,0 +1,120 @@
265.4 +// -*- C++ -*-
265.5 +
265.6 +#include <lemon/bits/undir_graph_extender.h>
265.7 +#include <lemon/concept/undir_graph.h>
265.8 +#include <lemon/list_graph.h>
265.9 +#include <lemon/smart_graph.h>
265.10 +#include <lemon/full_graph.h>
265.11 +
265.12 +#include <lemon/graph_utils.h>
265.13 +
265.14 +#include "test_tools.h"
265.15 +
265.16 +
265.17 +using namespace lemon;
265.18 +using namespace lemon::concept;
265.19 +
265.20 +void check_concepts() {
265.21 + typedef UndirGraphExtender<ListGraphBase> UndirListGraphBase;
265.22 +
265.23 + typedef IterableUndirGraphExtender<
265.24 + AlterableUndirGraphExtender<UndirListGraphBase> > IterableUndirListGraph;
265.25 +
265.26 + typedef MappableUndirGraphExtender<IterableUndirListGraph>
265.27 + MappableUndirListGraph;
265.28 +
265.29 + typedef ErasableUndirGraphExtender<
265.30 + ClearableUndirGraphExtender<
265.31 + ExtendableUndirGraphExtender<MappableUndirListGraph> > > Graph;
265.32 +
265.33 + checkConcept<BaseIterableUndirGraphConcept, Graph>();
265.34 + checkConcept<IterableUndirGraphConcept, Graph>();
265.35 + checkConcept<MappableUndirGraphConcept, Graph>();
265.36 +
265.37 + checkConcept<UndirGraph, Graph>();
265.38 + checkConcept<ErasableUndirGraph, Graph>();
265.39 +
265.40 + checkConcept<UndirGraph, UndirListGraph>();
265.41 + checkConcept<ErasableUndirGraph, UndirListGraph>();
265.42 +
265.43 + checkConcept<UndirGraph, UndirSmartGraph>();
265.44 + checkConcept<ExtendableUndirGraph, UndirSmartGraph>();
265.45 +
265.46 + checkConcept<UndirGraph, UndirGraph>();
265.47 +}
265.48 +
265.49 +template <typename Graph>
265.50 +void check_item_counts(Graph &g, int n, int e) {
265.51 + check(countNodes(g)==n, "Wrong node number.");
265.52 + check(countEdges(g)==2*e, "Wrong edge number.");
265.53 +}
265.54 +
265.55 +template <typename Graph>
265.56 +void print_items(Graph &g) {
265.57 +
265.58 + typedef typename Graph::NodeIt NodeIt;
265.59 + typedef typename Graph::UndirEdgeIt UEdgeIt;
265.60 + typedef typename Graph::EdgeIt EdgeIt;
265.61 +
265.62 + std::cout << "Nodes" << std::endl;
265.63 + int i=0;
265.64 + for(NodeIt it(g); it!=INVALID; ++it, ++i) {
265.65 + std::cout << " " << i << ": " << g.id(it) << std::endl;
265.66 + }
265.67 +
265.68 + std::cout << "UndirEdge" << std::endl;
265.69 + i=0;
265.70 + for(UEdgeIt it(g); it!=INVALID; ++it, ++i) {
265.71 + std::cout << " " << i << ": " << g.id(it)
265.72 + << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it))
265.73 + << ")" << std::endl;
265.74 + }
265.75 +
265.76 + std::cout << "Edge" << std::endl;
265.77 + i=0;
265.78 + for(EdgeIt it(g); it!=INVALID; ++it, ++i) {
265.79 + std::cout << " " << i << ": " << g.id(it)
265.80 + << " (" << g.id(g.source(it)) << ", " << g.id(g.target(it))
265.81 + << ")" << std::endl;
265.82 + }
265.83 +
265.84 +}
265.85 +
265.86 +template <typename Graph>
265.87 +void check_graph() {
265.88 +
265.89 + typedef typename Graph::Node Node;
265.90 + typedef typename Graph::UndirEdge UEdge;
265.91 + typedef typename Graph::Edge Edge;
265.92 + typedef typename Graph::NodeIt NodeIt;
265.93 + typedef typename Graph::UndirEdgeIt UEdgeIt;
265.94 + typedef typename Graph::EdgeIt EdgeIt;
265.95 +
265.96 + Graph g;
265.97 +
265.98 + check_item_counts(g,0,0);
265.99 +
265.100 + Node
265.101 + n1 = g.addNode(),
265.102 + n2 = g.addNode(),
265.103 + n3 = g.addNode();
265.104 +
265.105 + UEdge
265.106 + e1 = g.addEdge(n1, n2),
265.107 + e2 = g.addEdge(n2, n3);
265.108 +
265.109 + // print_items(g);
265.110 +
265.111 + check_item_counts(g,3,2);
265.112 +
265.113 +
265.114 +}
265.115 +
265.116 +int main() {
265.117 + check_concepts();
265.118 +
265.119 + check_graph<UndirListGraph>();
265.120 + check_graph<UndirSmartGraph>();
265.121 +
265.122 + return 0;
265.123 +}
266.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
266.2 +++ b/test/unionfind_test.cc Mon May 23 04:48:14 2005 +0000
266.3 @@ -0,0 +1,208 @@
266.4 +/* -*- C++ -*-
266.5 + * test/unionfind_test.cc - Part of LEMON, a generic C++ optimization library
266.6 + *
266.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
266.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
266.9 + *
266.10 + * Permission to use, modify and distribute this software is granted
266.11 + * provided that this copyright notice appears in all copies. For
266.12 + * precise terms see the accompanying LICENSE file.
266.13 + *
266.14 + * This software is provided "AS IS" with no warranty of any kind,
266.15 + * express or implied, and with no claim as to its suitability for any
266.16 + * purpose.
266.17 + *
266.18 + */
266.19 +
266.20 +#include <iostream>
266.21 +
266.22 +#include <lemon/maps.h>
266.23 +#include <lemon/unionfind.h>
266.24 +#include "test_tools.h"
266.25 +
266.26 +using namespace lemon;
266.27 +using namespace std;
266.28 +
266.29 +template <typename T>
266.30 +class BaseMap : public StdMap<int,T> {};
266.31 +
266.32 +typedef UnionFindEnum<int, BaseMap> UFE;
266.33 +
266.34 +void print(UFE const &ufe) {
266.35 + UFE::ClassIt cit;
266.36 + cout << "Print the classes of the structure:" << endl;
266.37 + int i = 1;
266.38 + for (ufe.first(cit); ufe.valid(cit); ufe.next(cit)) {
266.39 + cout << " " << i << " (" << cit << "):" << flush;
266.40 + UFE::ItemIt iit;
266.41 + for (ufe.first(iit, cit); ufe.valid(iit); ufe.next(iit)) {
266.42 + cout << " " << iit << flush;
266.43 + }
266.44 + cout << endl;
266.45 + i++;
266.46 + }
266.47 + cout << "done" << endl;
266.48 +}
266.49 +
266.50 +
266.51 +int main() {
266.52 + UFE::MapType base;
266.53 + UFE U(base);
266.54 +
266.55 +// print(U);
266.56 +
266.57 + cout << "Insert 1..." << endl;
266.58 + U.insert(1);
266.59 +// print(U);
266.60 +
266.61 + cout << "Insert 2..." << endl;
266.62 + U.insert(2);
266.63 +// print(U);
266.64 +
266.65 + cout << "Join 1 and 2..." << endl;
266.66 + check(U.join(1,2),"Test failed.");
266.67 +// print(U);
266.68 +
266.69 + cout << "Insert 3, 4, 5, 6, 7..." << endl;
266.70 + U.insert(3);
266.71 + U.insert(4);
266.72 + U.insert(5);
266.73 + U.insert(6);
266.74 + U.insert(7);
266.75 +// print (U);
266.76 +
266.77 + cout << "Join 1 - 4, 2 - 4 and 3 - 5 ..." << endl;
266.78 + check(U.join(1,4),"Test failed.");
266.79 + check(!U.join(2,4),"Test failed.");
266.80 + check(U.join(3,5),"Test failed.");
266.81 +// print(U);
266.82 +
266.83 + cout << "Insert 8 to the component of 5 ..." << endl;
266.84 + U.insert(8,5);
266.85 +// print(U);
266.86 +
266.87 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.88 + check(U.size(4) == 3,"Test failed.");
266.89 + cout << "Size of the class of 5: " << U.size(5) << endl;
266.90 + check(U.size(5) == 3,"Test failed.");
266.91 + cout << "Size of the class of 6: " << U.size(6) << endl;
266.92 + check(U.size(6) == 1,"Test failed.");
266.93 + cout << "Size of the class of 2: " << U.size(2) << endl;
266.94 + check(U.size(2) == 3,"Test failed.");
266.95 +
266.96 + cout << "Insert 9 ..." << endl;
266.97 + U.insert(9);
266.98 +// print(U);
266.99 + cout << "Insert 10 to the component of 9 ..." << endl;
266.100 + U.insert(10,9);
266.101 +// print(U);
266.102 +
266.103 + cout << "Join 8 and 10..." << endl;
266.104 + check(U.join(8,10),"Test failed.");
266.105 +// print(U);
266.106 +
266.107 + cout << "Move 9 to the class of 4 ..." << endl;
266.108 + check(U.move(9,4),"Test failed.");
266.109 +// print(U);
266.110 +
266.111 + cout << "Move 9 to the class of 2 ..." << endl;
266.112 + check(!U.move(9,2),"Test failed.");
266.113 +// print(U);
266.114 +
266.115 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.116 + check(U.size(4) == 4,"Test failed.");
266.117 + cout << "Size of the class of 9: " << U.size(9) << endl;
266.118 + check(U.size(9) == 4,"Test failed.");
266.119 +
266.120 + cout << "Move 5 to the class of 6 ..." << endl;
266.121 + check(U.move(5,6),"Test failed.");
266.122 +// print(U);
266.123 +
266.124 + cout << "Size of the class of 5: " << U.size(5) << endl;
266.125 + check(U.size(5) == 2,"Test failed.");
266.126 + cout << "Size of the class of 8: " << U.size(8) << endl;
266.127 + check(U.size(8) == 3,"Test failed.");
266.128 +
266.129 + cout << "Move 7 to the class of 10 ..." << endl;
266.130 + check(U.move(7,10),"Test failed.");
266.131 +// print(U);
266.132 +
266.133 + cout << "Size of the class of 7: " << U.size(7) << endl;
266.134 + check(U.size(7) == 4,"Test failed.");
266.135 +
266.136 + cout <<"Erase 9... " << endl;
266.137 + U.erase(9);
266.138 +// print(U);
266.139 +
266.140 + cout <<"Erase 1... " << endl;
266.141 + U.erase(1);
266.142 +// print(U);
266.143 +
266.144 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.145 + check(U.size(4) == 2,"Test failed.");
266.146 + cout << "Size of the class of 2: " << U.size(2) << endl;
266.147 + check(U.size(2) == 2,"Test failed.");
266.148 +
266.149 +
266.150 + cout <<"Erase 1... " << endl;
266.151 + U.erase(1);
266.152 +// print(U);
266.153 +
266.154 + cout <<"Erase 6... " << endl;
266.155 + U.erase(6);
266.156 +// print(U);
266.157 +
266.158 + cout << "Split the class of 8... " << endl;
266.159 + U.split(8);
266.160 +// print(U);
266.161 +
266.162 +
266.163 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.164 + check(U.size(4) == 2,"Test failed.");
266.165 + cout << "Size of the class of 3: " << U.size(3) << endl;
266.166 + check(U.size(3) == 1,"Test failed.");
266.167 + cout << "Size of the class of 2: " << U.size(2) << endl;
266.168 + check(U.size(2) == 2,"Test failed.");
266.169 +
266.170 +
266.171 + cout << "Join 3 - 4 and 2 - 4 ..." << endl;
266.172 + check(U.join(3,4),"Test failed.");
266.173 + check(!U.join(2,4),"Test failed.");
266.174 +// print(U);
266.175 +
266.176 +
266.177 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.178 + check(U.size(4) == 3,"Test failed.");
266.179 + cout << "Size of the class of 3: " << U.size(3) << endl;
266.180 + check(U.size(3) == 3,"Test failed.");
266.181 + cout << "Size of the class of 2: " << U.size(2) << endl;
266.182 + check(U.size(2) == 3,"Test failed.");
266.183 +
266.184 + cout << "Calling makeRep(4)..." << endl;
266.185 + U.makeRep(4);
266.186 +// print(U);
266.187 + cout << "Calling makeRep(3)..." << endl;
266.188 + U.makeRep(3);
266.189 +// print(U);
266.190 + cout << "Calling makeRep(2)..." << endl;
266.191 + U.makeRep(2);
266.192 +// print(U);
266.193 +
266.194 + cout << "Size of the class of 4: " << U.size(4) << endl;
266.195 + check(U.size(4) == 3,"Test failed.");
266.196 + cout << "Size of the class of 3: " << U.size(3) << endl;
266.197 + check(U.size(3) == 3,"Test failed.");
266.198 + cout << "Size of the class of 2: " << U.size(2) << endl;
266.199 + check(U.size(2) == 3,"Test failed.");
266.200 +
266.201 +
266.202 + cout << "eraseClass 4 ..." << endl;
266.203 + U.eraseClass(4);
266.204 +// print(U);
266.205 +
266.206 + cout << "eraseClass 7 ..." << endl;
266.207 + U.eraseClass(7);
266.208 +// print(U);
266.209 +
266.210 + cout << "done." << endl;
266.211 +}
267.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
267.2 +++ b/test/xy_test.cc Mon May 23 04:48:14 2005 +0000
267.3 @@ -0,0 +1,80 @@
267.4 +/* -*- C++ -*-
267.5 + * test/xy_test.cc - Part of LEMON, a generic C++ optimization library
267.6 + *
267.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
267.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
267.9 + *
267.10 + * Permission to use, modify and distribute this software is granted
267.11 + * provided that this copyright notice appears in all copies. For
267.12 + * precise terms see the accompanying LICENSE file.
267.13 + *
267.14 + * This software is provided "AS IS" with no warranty of any kind,
267.15 + * express or implied, and with no claim as to its suitability for any
267.16 + * purpose.
267.17 + *
267.18 + */
267.19 +
267.20 +#include <lemon/xy.h>
267.21 +#include <iostream>
267.22 +#include "test_tools.h"
267.23 +
267.24 +using namespace std;
267.25 +using namespace lemon;
267.26 +int main()
267.27 +{
267.28 +
267.29 + cout << "Testing classes `xy' and `boundingbox'." << endl;
267.30 +
267.31 + typedef xy<int> XY;
267.32 +
267.33 + XY seged;
267.34 + XY a(1,2);
267.35 + XY b(3,4);
267.36 +
267.37 + seged = a+b;
267.38 + check(seged.x==4 && seged.y==6, "Wrong vector addition");
267.39 +
267.40 + seged = a-b;
267.41 + check(seged.x==-2 && seged.y==-2, "a-b");
267.42 +
267.43 + check(a.normSquare()==5,"Wrong norm calculation");
267.44 + check(a*b==11, "a*b");
267.45 +
267.46 + int l=2;
267.47 + seged = a*l;
267.48 + check(seged.x==2 && seged.y==4, "a*l");
267.49 +
267.50 + seged = b/l;
267.51 + check(seged.x==1 && seged.y==2, "b/l");
267.52 +
267.53 + typedef BoundingBox<int> BB;
267.54 + BB doboz1;
267.55 + check(doboz1.empty(), "It should be empty.");
267.56 +
267.57 + doboz1 += a;
267.58 + check(!doboz1.empty(), "It should not be empty.");
267.59 + doboz1 += b;
267.60 +
267.61 + check(doboz1.bottomLeft().x==1 &&
267.62 + doboz1.bottomLeft().y==2 &&
267.63 + doboz1.topRight().x==3 &&
267.64 + doboz1.topRight().y==4,
267.65 + "added points to box");
267.66 +
267.67 + seged.x=2;seged.y=3;
267.68 + check(doboz1.inside(seged),"It should be inside.");
267.69 +
267.70 + seged.x=1;seged.y=3;
267.71 + check(doboz1.inside(seged),"It should be inside.");
267.72 +
267.73 + seged.x=0;seged.y=3;
267.74 + check(!doboz1.inside(seged),"It should not be inside.");
267.75 +
267.76 + BB doboz2(seged);
267.77 + check(!doboz2.empty(),
267.78 + "It should not be empty. Constructed from 1 point.");
267.79 +
267.80 + doboz2 += doboz1;
267.81 + check(doboz2.inside(seged),
267.82 + "It should be inside. Incremented a box with an other.");
267.83 +}