Ut struktura. Elso valtozat.
authorklao
Sun, 21 Mar 2004 16:16:08 +0000
changeset 225b72b36a25170
parent 224 5bc1c83257f8
child 226 616bc397c83a
Ut struktura. Elso valtozat.
src/work/klao/.cvsignore
src/work/klao/Makefile
src/work/klao/path.h
src/work/klao/path_test.cc
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/work/klao/.cvsignore	Sun Mar 21 16:16:08 2004 +0000
     1.3 @@ -0,0 +1,2 @@
     1.4 +.depend
     1.5 +path_test
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/work/klao/Makefile	Sun Mar 21 16:16:08 2004 +0000
     2.3 @@ -0,0 +1,4 @@
     2.4 +BINARIES = path_test
     2.5 +INCLUDEDIRS= -I. -I.. -I../../include -I../{marci,jacint,alpar,johanna,akos}
     2.6 +include ../makefile
     2.7 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/work/klao/path.h	Sun Mar 21 16:16:08 2004 +0000
     3.3 @@ -0,0 +1,383 @@
     3.4 +// -*- c++ -*- //
     3.5 +
     3.6 +/**
     3.7 + *
     3.8 + * Class for representing paths in graphs.
     3.9 + *
    3.10 + */
    3.11 +
    3.12 +#ifndef HUGO_PATH_H
    3.13 +#define HUGO_PATH_H
    3.14 +
    3.15 +#include <deque>
    3.16 +
    3.17 +#include <invalid.h>
    3.18 +
    3.19 +namespace hugo {
    3.20 +
    3.21 +  /* Ennek az allocatorosdinak sokkal jobban utana kene nezni a hasznalata
    3.22 +     elott. Eleg bonyinak nez ki, ahogyan azokat az STL-ben hasznaljak. */
    3.23 +
    3.24 +  template<typename Graph>
    3.25 +  class Path {
    3.26 +
    3.27 +  public:
    3.28 +    typedef typename Graph::Edge GraphEdge;
    3.29 +    typedef typename Graph::Node GraphNode;
    3.30 +    class NodeIt;
    3.31 +    class EdgeIt;
    3.32 +
    3.33 +  protected:
    3.34 +    Graph& G;
    3.35 +    // FIXME: ehelyett eleg lenne tarolni ket boolt: a ket szelso el
    3.36 +    // iranyitasat:
    3.37 +    GraphNode _first, _last;
    3.38 +    typedef std::deque<GraphEdge> Container;
    3.39 +    Container edges;
    3.40 +
    3.41 +  public:
    3.42 +
    3.43 +    Path(Graph &_G) : G(_G), _first(INVALID), _last(INVALID) {}
    3.44 +
    3.45 +    /// Subpath defined by two nodes
    3.46 +    Path(Path const& P, NodeIt a, NodeIt b) { FIXME; }
    3.47 +    /// Subpath defined by tow edges. Contains edges in [a,b)
    3.48 +    Path(Path const& P, EdgeIt a, EdgeIt b) { FIXME; }
    3.49 +    
    3.50 +    size_t length() const { return edges.size(); }
    3.51 +    GraphNode from() const { return _first; }
    3.52 +    GraphNode to() const { return _last; }
    3.53 +
    3.54 +    NodeIt& first(NodeIt &n) const { return nth(n, 0); }
    3.55 +    EdgeIt& first(EdgeIt &e) const { return nth(e, 0); }
    3.56 +    template<typename It>
    3.57 +    It first() const { 
    3.58 +      It e;
    3.59 +      first(e);
    3.60 +      return e; 
    3.61 +    }
    3.62 +
    3.63 +    NodeIt& nth(NodeIt &, size_t) const;
    3.64 +    EdgeIt& nth(EdgeIt &, size_t) const;
    3.65 +    template<typename It>
    3.66 +    It nth(size_t n) const { 
    3.67 +      It e;
    3.68 +      nth(e, n);
    3.69 +      return e; 
    3.70 +    }
    3.71 +
    3.72 +    bool valid(const NodeIt &n) const { return n.idx <= length(); }
    3.73 +    bool valid(const EdgeIt &e) const { return e.it < edges.end(); }
    3.74 +
    3.75 +    bool isForward(const EdgeIt &e) const { return e.forw; }
    3.76 +
    3.77 +    EdgeIt& next(EdgeIt &e) const;
    3.78 +    NodeIt& next(NodeIt &n) const;
    3.79 +    template <typename It>
    3.80 +    It getNext(It it) const {
    3.81 +      It tmp(it); return next(tmp);
    3.82 +    }
    3.83 +
    3.84 +    // A path is constructed using the following four functions.
    3.85 +    // They return false if the requested operation is inconsistent
    3.86 +    // with the path constructed so far.
    3.87 +    // If your path has only one edge you MUST set either "from" or "to"!
    3.88 +    // So you probably SHOULD call it in any case to be safe (and check the
    3.89 +    // returned value to check if your path is consistent with your idea).
    3.90 +    bool pushFront(const GraphEdge &e);
    3.91 +    bool pushBack(const GraphEdge &e);
    3.92 +    bool setFrom(const GraphNode &n);
    3.93 +    bool setTo(const GraphNode &n);
    3.94 +
    3.95 +    // WARNING: these two functions return the head/tail of an edge with
    3.96 +    // respect to the direction of the path!
    3.97 +    // So G.head(P.graphEdge(e)) == P.graphNode(P.head(e)) holds only if 
    3.98 +    // P.forward(e) is true (or the edge is a loop)!
    3.99 +    NodeIt head(const EdgeIt& e) const;
   3.100 +    NodeIt tail(const EdgeIt& e) const;
   3.101 +
   3.102 +    // FIXME: ezeknek valami jobb nev kellene!!!
   3.103 +    GraphEdge graphEdge(const EdgeIt& e) const;
   3.104 +    GraphNode graphNode(const NodeIt& n) const;
   3.105 +
   3.106 +
   3.107 +    /*** Iterator classes ***/
   3.108 +    class EdgeIt {
   3.109 +      friend class Path;
   3.110 +
   3.111 +      typename Container::const_iterator it;
   3.112 +      bool forw;
   3.113 +    public:
   3.114 +      // FIXME: jarna neki ilyen is...
   3.115 +      // EdgeIt(Invalid);
   3.116 +
   3.117 +      bool forward() const { return forw; }
   3.118 +
   3.119 +      bool operator==(const EdgeIt& e) const { return it==e.it; }
   3.120 +      bool operator!=(const EdgeIt& e) const { return it!=e.it; }
   3.121 +      bool operator<(const EdgeIt& e) const { return it<e.it; }
   3.122 +    };
   3.123 +
   3.124 +    class NodeIt {
   3.125 +      friend class Path;
   3.126 +      friend class EdgeIt;
   3.127 +
   3.128 +      int idx;
   3.129 +      bool tail;  // Is this node the tail of the edge with same idx?
   3.130 +
   3.131 +    public:
   3.132 +      // FIXME: jarna neki ilyen is...
   3.133 +      // NodeIt(Invalid);
   3.134 +
   3.135 +      bool operator==(const NodeIt& n) const { return idx==n.idx; }
   3.136 +      bool operator!=(const NodeIt& n) const { return idx!=n.idx; }
   3.137 +      bool operator<(const NodeIt& n) const { return idx<n.idx; }
   3.138 +    };
   3.139 +
   3.140 +  private:
   3.141 +    bool edgeIncident(const GraphEdge &e, const GraphNode &a,
   3.142 +		      GraphNode &b);
   3.143 +    bool connectTwoEdges(const GraphEdge &e, const GraphEdge &f);
   3.144 +  };
   3.145 +
   3.146 +  template<typename Gr>
   3.147 +  typename Path<Gr>::EdgeIt&
   3.148 +  Path<Gr>::next(Path::EdgeIt &e) const {
   3.149 +    if( e.it == edges.end() ) 
   3.150 +      return e;
   3.151 +
   3.152 +    GraphNode common_node = ( e.forw ? G.head(*e.it) : G.tail(*e.it) );
   3.153 +    ++e.it;
   3.154 +
   3.155 +    // Invalid edgeit is always forward :)
   3.156 +    if( e.it == edges.end() ) {
   3.157 +      e.forw = true;
   3.158 +      return e;
   3.159 +    }
   3.160 +
   3.161 +    e.forw = ( G.tail(*e.it) == common_node );
   3.162 +    return e;
   3.163 +  }
   3.164 +
   3.165 +  template<typename Gr>
   3.166 +  typename Path<Gr>::NodeIt& Path<Gr>::next(NodeIt &n) const {
   3.167 +    if( n.idx >= length() ) {
   3.168 +      // FIXME: invalid
   3.169 +      n.idx = length()+1;
   3.170 +      return n;
   3.171 +    }
   3.172 +
   3.173 +    
   3.174 +    GraphNode next_node = ( n.tail ? G.head(edges[n.idx]) :
   3.175 +			      G.tail(edges[n.idx]) );
   3.176 +    ++n.idx;
   3.177 +    if( n.idx < length() ) {
   3.178 +      n.tail = ( next_node == G.tail(edges[n.idx]) );
   3.179 +    }
   3.180 +    else {
   3.181 +      n.tail = true;
   3.182 +    }
   3.183 +
   3.184 +    return n;
   3.185 +  }
   3.186 +
   3.187 +  template<typename Gr>
   3.188 +  bool Path<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a,
   3.189 +			  GraphNode &b) {
   3.190 +    if( G.tail(e) == a ) {
   3.191 +      b=G.head(e);
   3.192 +      return true;
   3.193 +    }
   3.194 +    if( G.head(e) == a ) {
   3.195 +      b=G.tail(e);
   3.196 +      return true;
   3.197 +    }
   3.198 +    return false;
   3.199 +  }
   3.200 +
   3.201 +  template<typename Gr>
   3.202 +  bool Path<Gr>::connectTwoEdges(const GraphEdge &e,
   3.203 +			     const GraphEdge &f) {
   3.204 +    if( edgeIncident(f, G.tail(e), _last) ) {
   3.205 +      _first = G.head(e);
   3.206 +      return true;
   3.207 +    }
   3.208 +    if( edgeIncident(f, G.head(e), _last) ) {
   3.209 +      _first = G.tail(e);
   3.210 +      return true;
   3.211 +    }
   3.212 +    return false;
   3.213 +  }
   3.214 +
   3.215 +  template<typename Gr>
   3.216 +  bool Path<Gr>::pushFront(const GraphEdge &e) {
   3.217 +    if( G.valid(_first) ) {
   3.218 +	if( edgeIncident(e, _first, _first) ) {
   3.219 +	  edges.push_front(e);
   3.220 +	  return true;
   3.221 +	}
   3.222 +	else
   3.223 +	  return false;
   3.224 +    }
   3.225 +    else if( length() < 1 || connectTwoEdges(e, edges[0]) ) {
   3.226 +      edges.push_front(e);
   3.227 +      return true;
   3.228 +    }
   3.229 +    else
   3.230 +      return false;
   3.231 +  }
   3.232 +
   3.233 +  template<typename Gr>
   3.234 +  bool Path<Gr>::pushBack(const GraphEdge &e) {
   3.235 +    if( G.valid(_last) ) {
   3.236 +	if( edgeIncident(e, _last, _last) ) {
   3.237 +	  edges.push_back(e);
   3.238 +	  return true;
   3.239 +	}
   3.240 +	else
   3.241 +	  return false;
   3.242 +    }
   3.243 +    else if( length() < 1 || connectTwoEdges(edges[0], e) ) {
   3.244 +      edges.push_back(e);
   3.245 +      return true;
   3.246 +    }
   3.247 +    else
   3.248 +      return false;
   3.249 +  }
   3.250 +
   3.251 +
   3.252 +  template<typename Gr>
   3.253 +  bool Path<Gr>::setFrom(const GraphNode &n) {
   3.254 +    if( G.valid(_first) ) {
   3.255 +      return _first == n;
   3.256 +    }
   3.257 +    else {
   3.258 +      if( length() > 0) {
   3.259 +	if( edgeIncident(edges[0], n, _last) ) {
   3.260 +	  _first = n;
   3.261 +	  return true;
   3.262 +	}
   3.263 +	else return false;
   3.264 +      }
   3.265 +      else {
   3.266 +	_first = _last = n;
   3.267 +	return true;
   3.268 +      }
   3.269 +    }
   3.270 +  }
   3.271 +
   3.272 +  template<typename Gr>
   3.273 +  bool Path<Gr>::setTo(const GraphNode &n) {
   3.274 +    if( G.valid(_last) ) {
   3.275 +      return _last == n;
   3.276 +    }
   3.277 +    else {
   3.278 +      if( length() > 0) {
   3.279 +	if( edgeIncident(edges[0], n, _first) ) {
   3.280 +	  _last = n;
   3.281 +	  return true;
   3.282 +	}
   3.283 +	else return false;
   3.284 +      }
   3.285 +      else {
   3.286 +	_first = _last = n;
   3.287 +	return true;
   3.288 +      }
   3.289 +    }
   3.290 +  }
   3.291 +
   3.292 +
   3.293 +  template<typename Gr>
   3.294 +  typename Path<Gr>::NodeIt
   3.295 +  Path<Gr>::tail(const EdgeIt& e) const {
   3.296 +    NodeIt n;
   3.297 +
   3.298 +    if( e.it == edges.end() ) {
   3.299 +      // FIXME: invalid-> invalid
   3.300 +      n.idx = length() + 1;
   3.301 +      n.tail = true;
   3.302 +      return n;
   3.303 +    }
   3.304 +
   3.305 +    n.idx = e.it-edges.begin();
   3.306 +    n.tail = e.forw;
   3.307 +  }
   3.308 +
   3.309 +  template<typename Gr>
   3.310 +  typename Path<Gr>::NodeIt
   3.311 +  Path<Gr>::head(const EdgeIt& e) const {
   3.312 +    if( e.it == edges.end()-1 ) {
   3.313 +      return _last;
   3.314 +    }
   3.315 +
   3.316 +    EdgeIt next_edge = e;
   3.317 +    next(next_edge);
   3.318 +    return tail(next_edge);
   3.319 +  }
   3.320 +      
   3.321 +  template<typename Gr>
   3.322 +  typename Path<Gr>::GraphEdge
   3.323 +  Path<Gr>::graphEdge(const EdgeIt& e) const {
   3.324 +    if( e.it != edges.end() ) {
   3.325 +      return *e.it;
   3.326 +    }
   3.327 +    else {
   3.328 +      return INVALID;
   3.329 +    }
   3.330 +  }
   3.331 +  
   3.332 +  template<typename Gr>
   3.333 +  typename Path<Gr>::GraphNode
   3.334 +  Path<Gr>::graphNode(const NodeIt& n) const {
   3.335 +    if( n.idx < length() ) {
   3.336 +      return n.tail ? G.tail(edges[n.idx]) : G.head(edges[n.idx]);
   3.337 +    }
   3.338 +    else if( n.idx == length() ) {
   3.339 +      return _last;
   3.340 +    }
   3.341 +    else {
   3.342 +      return INVALID;
   3.343 +    }
   3.344 +  }
   3.345 +
   3.346 +  template<typename Gr>
   3.347 +  typename Path<Gr>::EdgeIt& Path<Gr>::nth(EdgeIt &e, size_t k) const {
   3.348 +    if( k<0 || k>=length() ) {
   3.349 +      // FIXME: invalid EdgeIt
   3.350 +      e.it = edges.end();
   3.351 +      e.forw = true;
   3.352 +      return e;
   3.353 +    }
   3.354 +
   3.355 +    e.it = edges.begin()+k;
   3.356 +    if(k==0) {
   3.357 +      e.forw = ( G.tail(*e.it) == _first );
   3.358 +    }
   3.359 +    else {
   3.360 +      e.forw = ( G.tail(*e.it) == G.tail(edges[k-1]) ||
   3.361 +		 G.tail(*e.it) == G.head(edges[k-1]) );
   3.362 +    }
   3.363 +    return e;
   3.364 +  }
   3.365 +    
   3.366 +  template<typename Gr>
   3.367 +  typename Path<Gr>::NodeIt& Path<Gr>::nth(NodeIt &n, size_t k) const {
   3.368 +    if( k<0 || k>length() ) {
   3.369 +      // FIXME: invalid NodeIt
   3.370 +      n.idx = length()+1;
   3.371 +      n.tail = true;
   3.372 +      return n;
   3.373 +    }
   3.374 +    if( k==length() ) {
   3.375 +      n.idx = length();
   3.376 +      n.tail = true;
   3.377 +      return n;
   3.378 +    }
   3.379 +    n = tail(nth<EdgeIt>(k));
   3.380 +    return n;
   3.381 +  }
   3.382 +
   3.383 +
   3.384 +} // namespace hugo
   3.385 +
   3.386 +#endif // HUGO_PATH_H
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/work/klao/path_test.cc	Sun Mar 21 16:16:08 2004 +0000
     4.3 @@ -0,0 +1,118 @@
     4.4 +#include <string>
     4.5 +#include <iostream>
     4.6 +
     4.7 +#include <path.h>
     4.8 +#include <list_graph.h>
     4.9 +
    4.10 +using namespace std;
    4.11 +using namespace hugo;
    4.12 +
    4.13 +bool passed = true;
    4.14 +
    4.15 +void check(bool rc) {
    4.16 +  passed = passed && rc;
    4.17 +  if(!rc) {
    4.18 +    cout << "Test failed!" << endl;
    4.19 +  }
    4.20 +}
    4.21 +
    4.22 +int main() {
    4.23 +
    4.24 +  typedef ListGraph::Node Node;
    4.25 +  typedef ListGraph::Edge Edge;
    4.26 +
    4.27 +  ListGraph G;
    4.28 +
    4.29 +  Node s=G.addNode();
    4.30 +  Node v1=G.addNode();
    4.31 +  Node v2=G.addNode();
    4.32 +  Node v3=G.addNode();
    4.33 +  Node v4=G.addNode();
    4.34 +  Node t=G.addNode();
    4.35 +  
    4.36 +  Edge e1 = G.addEdge(s, v1);
    4.37 +  Edge e2 = G.addEdge(s, v2);
    4.38 +  Edge e3 = G.addEdge(v1, v2);
    4.39 +  Edge e4 = G.addEdge(v2, v1);
    4.40 +  Edge e5 = G.addEdge(v1, v3);
    4.41 +  Edge e6 = G.addEdge(v3, v2);
    4.42 +  Edge e7 = G.addEdge(v2, v4);
    4.43 +  Edge e8 = G.addEdge(v4, v3);
    4.44 +  Edge e9 = G.addEdge(v3, t);
    4.45 +  Edge e10 = G.addEdge(v4, t);
    4.46 +
    4.47 +  bool rc;
    4.48 +
    4.49 +  cout << "Ures path letrehozasa" << endl;
    4.50 +  typedef Path<ListGraph> LPath;
    4.51 +  LPath P(G);
    4.52 +
    4.53 +  cout << "P.length() == " << P.length() << endl;
    4.54 +  check(P.length() == 0);
    4.55 +
    4.56 +  cout << "P.from() valid? " << G.valid(P.from()) << endl;
    4.57 +  check(! G.valid(P.from()));
    4.58 +
    4.59 +  cout << "Hozzaadunk ket elet..." << endl;
    4.60 +  check(P.pushBack(e1));
    4.61 +  check(P.pushBack(e3));
    4.62 +  cout << "P.length() == " << P.length() << endl;
    4.63 +  check(P.length() == 2);
    4.64 +
    4.65 +  cout << "P.from() valid? " << G.valid(P.from()) << endl;
    4.66 +  check(G.valid(P.from()));
    4.67 +  
    4.68 +  cout << "P.from()==s ? " << (P.from()==s) << endl;
    4.69 +  check(P.from() == s);
    4.70 +
    4.71 +  cout << "Hozzaadunk egy nem illeszkedo elt." << endl;
    4.72 +  rc = P.pushBack(e8);
    4.73 +  cout << "Sukerult: " << rc << endl;
    4.74 +  check(!rc);
    4.75 +
    4.76 +  cout << "Meg 3 el hozzaadasa, nem mind sorrendben..." << endl;
    4.77 +  check(P.pushBack(e6));
    4.78 +  check(P.pushBack(e8));
    4.79 +  check(P.pushBack(e10));
    4.80 +
    4.81 +  cout << "P.length() == " << P.length() << endl;
    4.82 +  check(P.length() == 5);
    4.83 +
    4.84 +  cout << "P.from()==s ? " << (P.from()==s) << endl;
    4.85 +  check(P.from() == s);
    4.86 +  cout << "P.to()==t ? " << (P.to()==t) << endl;
    4.87 +  check(P.to() == t);
    4.88 +
    4.89 +  cout << "Vegpont bellitasa: " << endl;
    4.90 +  rc = P.setTo(v2);
    4.91 +  cout << "Hibasra: " << rc << endl;
    4.92 +  check(!rc);
    4.93 +  rc = P.setTo(t);
    4.94 +  cout << "Helyesre: " << rc << endl;
    4.95 +  check(rc);
    4.96 +
    4.97 +  cout << "Elek iranyitasanak ellenorzese." << endl;
    4.98 +  cout << "El: " << e1 << ", G.tail(el): " << G.head(e1) << endl;
    4.99 +  check(G.tail(e1)==s);
   4.100 +
   4.101 +  cout << "Vegigiteralunk az eleken." << endl;
   4.102 +  typedef LPath::NodeIt NodeIt;
   4.103 +  typedef LPath::EdgeIt EdgeIt;
   4.104 +  EdgeIt e = P.first<EdgeIt>();
   4.105 +  int i=1;
   4.106 +  for(; P.valid(e); P.next(e), ++i) {
   4.107 +    cout << i << ". el: " << P.graphEdge(e)
   4.108 +	 << ", elore el? " << P.isForward(e) << endl;
   4.109 +    if(i>=3 && i<5) 
   4.110 +      check(!P.isForward(e));
   4.111 +    else
   4.112 +      check(P.isForward(e));
   4.113 +  }
   4.114 +
   4.115 +
   4.116 +
   4.117 +  cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
   4.118 +       << endl;
   4.119 +
   4.120 +  return passed ? 0 : 1;
   4.121 +}