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