00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00208 #ifndef graph_template_INCLUDED
00209 #define graph_template_INCLUDED "graph_template.h"
00210
00211 #ifdef _KEEP_RCS_ID
00212 #endif
00213
00214 #ifndef defs_INCLUDED
00215 #include "defs.h"
00216 #endif
00217 #ifndef mempool_INCLUDED
00218 #include "mempool.h"
00219 #endif
00220 #ifndef cxx_template_INCLUDED
00221 #include "cxx_template.h"
00222 #endif
00223 #ifndef cxx_graph_i_INCLUDED
00224 #include "cxx_graph.i"
00225 #endif
00226 #include "cxx_memory.h"
00227
00228
00229 template <class EDGE_TYPE, class VERTEX_TYPE>
00230 class DIRECTED_GRAPH16 {
00231 private:
00232 MEM_POOL *_vmpool;
00233 MEM_POOL *_empool;
00234 VINDEX16 _vfree;
00235 EINDEX16 _efree;
00236
00237 DIRECTED_GRAPH16(const DIRECTED_GRAPH16&);
00238 protected:
00239 DYN_ARRAY<VERTEX_TYPE> _v;
00240 VINDEX16 _vcnt;
00241 DYN_ARRAY<EDGE_TYPE> _e;
00242 EINDEX16 _ecnt;
00243
00244 public:
00245 DIRECTED_GRAPH16(const VINDEX16 vsize, const EINDEX16 evsize);
00246 ~DIRECTED_GRAPH16() {
00247 _v.Free_array();
00248 _e.Free_array();
00249 MEM_POOL_Pop(_vmpool);
00250 MEM_POOL_Delete(_vmpool);
00251 CXX_DELETE(_vmpool,Malloc_Mem_Pool);
00252 MEM_POOL_Pop(_empool);
00253 MEM_POOL_Delete(_empool);
00254 CXX_DELETE(_empool,Malloc_Mem_Pool);
00255 }
00256
00257 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>&
00258 operator=(const DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>& g);
00259
00260 void Erase_Graph() {
00261 _v.Setidx(0); _vcnt = 0; _vfree = 0; _e.Setidx(0); _ecnt = 0;
00262 _efree = 0; }
00263
00264 VINDEX16 Add_Vertex();
00265 EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to);
00266 EINDEX16 Add_Unique_Edge(VINDEX16 from, VINDEX16 to);
00267
00268 EINDEX16 Get_Edge(VINDEX16 from, VINDEX16 to) const;
00269 void Delete_Vertex(VINDEX16 v);
00270 void Delete_Edge(EINDEX16 e);
00271
00272 VINDEX16 Get_Vertex() const;
00273 VINDEX16 Get_Next_Vertex(VINDEX16 v) const;
00274
00275 EINDEX16 Get_Edge() const;
00276 EINDEX16 Get_Next_Edge(EINDEX16 e) const;
00277
00278 BOOL Vertex_Is_In_Graph(VINDEX16 v) const {
00279 return ((v <=_v.Lastidx()) && v>0 && !_v[v].Is_Free()); }
00280 BOOL Edge_Is_In_Graph(EINDEX16 e) const {
00281 return ((e <=_e.Lastidx()) && e>0 && !_e[e].Is_Free()); }
00282
00283 VINDEX16 Get_Source(EINDEX16 e) const {
00284 Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00285 return _e[e].Get_Source(); }
00286 VINDEX16 Get_Sink(EINDEX16 e) const {
00287 Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00288 return _e[e].Get_Sink(); }
00289
00290 EINDEX16 Get_In_Edge(VINDEX16 v) const {
00291 Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00292 return _v[v].Get_In_Edge(); }
00293 EINDEX16 Get_Out_Edge(VINDEX16 v) const {
00294 Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00295 return _v[v].Get_Out_Edge(); }
00296
00297 EINDEX16 Get_Next_In_Edge(EINDEX16 e) const
00298 { return _e[e].Get_Next_In_Edge(); }
00299 EINDEX16 Get_Next_Out_Edge(EINDEX16 e) const
00300 { return _e[e].Get_Next_Out_Edge(); }
00301
00302 VINDEX16 Get_Vertex_Count() const { return _vcnt; }
00303 EINDEX16 Get_Edge_Count() const { return _ecnt; }
00304
00305 BOOL Is_Empty() const { return _vcnt == 0; }
00306
00307 void Print(FILE *file) const;
00308 };
00309
00310
00311
00312 template <class EDGE_TYPE, class VERTEX_TYPE>
00313 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::
00314 DIRECTED_GRAPH16( const VINDEX16 vsize, const EINDEX16 esize) {
00315
00316
00317
00318 _vmpool = CXX_NEW(MEM_POOL,Malloc_Mem_Pool);
00319 MEM_POOL_Initialize(_vmpool,"vmpool",FALSE);
00320 MEM_POOL_Push(_vmpool);
00321 _v.Set_Mem_Pool(_vmpool);
00322 _v.Alloc_array(vsize+1);
00323 _v.Setidx( 0 );
00324 _vcnt = 0;
00325 _vfree = 0;
00326
00327
00328
00329
00330
00331
00332 _empool = CXX_NEW(MEM_POOL,Malloc_Mem_Pool);
00333 MEM_POOL_Initialize(_empool,"empool",FALSE);
00334 MEM_POOL_Push(_empool);
00335 _e.Set_Mem_Pool(_empool);
00336 _e.Alloc_array(esize+1);
00337 _e.Setidx( 0 );
00338 _ecnt = 0;
00339 _efree = 0;
00340
00341 }
00342
00343 template <class EDGE_TYPE, class VERTEX_TYPE>
00344 VINDEX16
00345 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Vertex() {
00346 VINDEX16 new_vertex;
00347
00348
00349 if (_vcnt == GRAPH16_CAPACITY) return 0;
00350
00351 if (_vfree == 0) {
00352 new_vertex = _v.Newidx();
00353 } else {
00354 new_vertex = _vfree;
00355 _vfree = _v[_vfree].Get_Next_Free_Vertex();
00356 }
00357
00358
00359 _v[new_vertex].Set_Out_Edge(0);
00360 _v[new_vertex].Set_In_Edge(0);
00361
00362 _vcnt++;
00363
00364 return new_vertex;
00365
00366 }
00367
00368 template <class EDGE_TYPE, class VERTEX_TYPE>
00369 EINDEX16
00370 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Edge(VINDEX16 from, VINDEX16 to) {
00371 EINDEX16 new_edge;
00372
00373
00374 if (_ecnt == GRAPH16_CAPACITY) return 0;
00375 if (_efree == 0) {
00376 new_edge = _e.Newidx();
00377 } else {
00378 new_edge = _efree;
00379 _efree = _e[_efree].Get_Next_Free_Edge();
00380 }
00381
00382 _e[new_edge].Set_Source(from);
00383 _e[new_edge].Set_Sink(to);
00384
00385 _ecnt++;
00386
00387
00388 _e[new_edge].Set_Next_Out_Edge(_v[from].Get_Out_Edge());
00389 _v[from].Set_Out_Edge(new_edge);
00390
00391
00392 _e[new_edge].Set_Next_In_Edge(_v[to].Get_In_Edge());
00393 _v[to].Set_In_Edge(new_edge);
00394
00395 return new_edge;
00396
00397 }
00398
00399 template <class EDGE_TYPE, class VERTEX_TYPE>
00400 EINDEX16
00401 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Unique_Edge(VINDEX16 from, VINDEX16 to) {
00402 EINDEX16 new_edge;
00403
00404
00405
00406 if (new_edge=Get_Edge(from,to)) return new_edge;
00407
00408 return Add_Edge(from,to);
00409
00410 }
00411
00412 template <class EDGE_TYPE, class VERTEX_TYPE>
00413 EINDEX16
00414 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Edge(VINDEX16 from, VINDEX16 to) const {
00415 EINDEX16 e;
00416 e = _v[from].Get_Out_Edge();
00417 while (e != 0) {
00418 if (_e[e].Get_Sink() == to) return e;
00419 e = _e[e].Get_Next_Out_Edge();
00420 }
00421 return 0;
00422 }
00423
00424 template <class EDGE_TYPE, class VERTEX_TYPE>
00425 void
00426 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Delete_Vertex(VINDEX16 v) {
00427
00428 EINDEX16 e;
00429
00430
00431 Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00432
00433 while (e = _v[v].Get_In_Edge()) {
00434 Delete_Edge(e);
00435 };
00436 while (e = _v[v].Get_Out_Edge()) {
00437 Delete_Edge(e);
00438 };
00439
00440
00441 _v[v].Set_Next_Free_Vertex(_vfree);
00442 _v[v].Set_To_Free();
00443 _vfree = v;
00444
00445 _vcnt--;
00446
00447 }
00448
00449 template <class EDGE_TYPE, class VERTEX_TYPE>
00450 void
00451 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Delete_Edge(EINDEX16 e) {
00452
00453 VINDEX16 from, to;
00454 EINDEX16 e1;
00455
00456
00457 Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00458
00459 from = _e[e].Get_Source();
00460 to = _e[e].Get_Sink();
00461
00462 if (_v[from].Get_Out_Edge() == e) {
00463 _v[from].Set_Out_Edge(_e[e].Get_Next_Out_Edge());
00464 } else {
00465 e1 = _v[from].Get_Out_Edge();
00466 while (_e[e1].Get_Next_Out_Edge() != e)
00467 e1 = _e[e1].Get_Next_Out_Edge();
00468 _e[e1].Set_Next_Out_Edge(_e[e].Get_Next_Out_Edge());
00469 }
00470
00471 if (_v[to].Get_In_Edge() == e) {
00472 _v[to].Set_In_Edge(_e[e].Get_Next_In_Edge());
00473 } else {
00474 e1 = _v[to].Get_In_Edge();
00475 while (_e[e1].Get_Next_In_Edge() != e)
00476 e1 = _e[e1].Get_Next_In_Edge();
00477 _e[e1].Set_Next_In_Edge(_e[e].Get_Next_In_Edge());
00478 }
00479
00480 _e[e].Set_Next_Free_Edge(_efree);
00481 _e[e].Set_To_Free();
00482 _efree = e;
00483
00484 _ecnt--;
00485
00486 }
00487
00488 template <class EDGE_TYPE, class VERTEX_TYPE>
00489 VINDEX16
00490 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Vertex() const {
00491 VINDEX16 v;
00492
00493 if (Is_Empty()) return 0;
00494
00495 v = _v.Lastidx();
00496 while (v>0 &&_v[v].Is_Free() ) v--;
00497 Is_True( v>0 , ("Fail to get vertex\n"));
00498
00499 return v;
00500 }
00501
00502 template <class EDGE_TYPE, class VERTEX_TYPE>
00503 VINDEX16
00504 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Next_Vertex(VINDEX16 v) const {
00505
00506 Is_True( Vertex_Is_In_Graph(v), ("Vertex does not exist in graph\n"));
00507
00508 do {
00509 v--;
00510 } while (v>0 && _v[v].Is_Free() );
00511
00512 return v;
00513 }
00514
00515 template <class EDGE_TYPE, class VERTEX_TYPE>
00516 EINDEX16
00517 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Edge() const {
00518 EINDEX16 e;
00519
00520 if (_ecnt == 0) return 0;
00521
00522 e = _e.Lastidx();
00523 while (_e[e].Is_Free() && e>0) e--;
00524 Is_True( e>0 , ("Fail to get edge\n"));
00525
00526 return e;
00527 }
00528
00529 template <class EDGE_TYPE, class VERTEX_TYPE>
00530 EINDEX16
00531 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Next_Edge(EINDEX16 e) const {
00532
00533 Is_True( Edge_Is_In_Graph(e), ("Edge does not exist in graph\n"));
00534
00535 do {
00536 e--;
00537 } while (e > 0 && _e[e].Is_Free() );
00538
00539 return e;
00540 }
00541
00542 template <class EDGE_TYPE, class VERTEX_TYPE>
00543 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>&
00544 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::
00545 operator=(const DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>& g) {
00546
00547
00548
00549 _vfree = g._vfree;
00550 _vcnt = g._vcnt;
00551 _efree = g._efree;
00552 _ecnt = g._ecnt;
00553
00554 _v = g._v;
00555 _e = g._e;
00556
00557 return *this;
00558 }
00559
00560 template <class EDGE_TYPE, class VERTEX_TYPE>
00561 void
00562 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Print(FILE *file) const {
00563 VINDEX16 i;
00564 EINDEX16 e;
00565
00566 fprintf(file,"Print out graph edges and vertices ...\n");
00567 for (i=1; i<_e.Lastidx()+1; i++)
00568 if (!_e[i].Is_Free())
00569 fprintf(file, "%d: %d --> %d\n", i, _e[i]._from, _e[i]._to);
00570
00571 for (i=1; i<_v.Lastidx()+1; i++)
00572 if (!_v[i].Is_Free()) {
00573 fprintf(file, "( ");
00574 e = _v[i].Get_In_Edge();
00575 while (e) {
00576 fprintf(file, "%d ", e);
00577 e = _e[e].Get_Next_In_Edge();
00578 }
00579 fprintf(file, ") %d ( ", i);
00580 e = _v[i].Get_Out_Edge();
00581 while (e) {
00582 fprintf(file, "%d ", e);
00583 e = _e[e].Get_Next_Out_Edge();
00584 }
00585 fprintf(file, ")\n");
00586 }
00587 }
00588
00589 #endif // graph_template_INCLUDED
00590