00001 #line 6220 "MIN_CYCLE_BASIS.lw"
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 #line 1773 "MIN_CYCLE_BASIS.lw"
00038
00069 #ifndef MIN_CYCLE_BASIS_H
00070 #define MIN_CYCLE_BASIS_H
00071
00072 #ifdef LEDA_GE_V5
00073 #include <LEDA/graph/graph.h>
00074 #include <LEDA/graph/edge_array.h>
00075 #include <LEDA/graph/node_array.h>
00076 #include <LEDA/graph/shortest_path.h>
00077 #include <LEDA/graph/templates/shortest_path.h>
00078 #include <LEDA/core/d_int_set.h>
00079 #include <LEDA/core/array.h>
00080 #include <LEDA/core/list.h>
00081 #include <LEDA/core/sortseq.h>
00082 #include <LEDA/core/tuple.h>
00083 #else
00084 #include <LEDA/graph.h>
00085 #include <LEDA/d_int_set.h>
00086 #include <LEDA/edge_array.h>
00087 #include <LEDA/node_array.h>
00088 #include <LEDA/array.h>
00089 #include <LEDA/list.h>
00090 #include <LEDA/sortseq.h>
00091 #include <LEDA/shortest_path.h>
00092 #include <LEDA/templates/shortest_path.t>
00093 #include <LEDA/tuple.h>
00094 #endif
00095
00096 #include <LEP/mcb/SIGNED_GRAPH.h>
00097
00098
00099 namespace mcb
00100 {
00101
00102 #if defined(LEDA_NAMESPACE)
00103 using leda::graph;
00104 using leda::array;
00105 using leda::edge;
00106 using leda::edge_array;
00107 using leda::d_int_set;
00108 using leda::list;
00109 using leda::sortseq;
00110 using leda::three_tuple;
00111 using leda::two_tuple;
00112 using leda::DIJKSTRA_T;
00113 using leda::node_set;
00114 #endif
00115
00116
00117
00118
00119 #line 1873 "MIN_CYCLE_BASIS.lw"
00120
00121 extern bool MCB_verify_basis( const leda::graph& g,
00122 leda::array< leda::d_int_set >& mcb,
00123 const mcb::edge_num& enumb,
00124 bool check_cycle_basis
00125 );
00126
00127 extern void MCB_output_basis( const leda::graph& g,
00128 leda::array< leda::d_int_set >& C,
00129 const mcb::edge_num& enumb,
00130 leda::array< leda::list< leda::edge > >& mcb );
00131
00132 extern void MCB_output_basis( const leda::graph& g,
00133 const leda::array< leda::list<leda::edge> >& mcb,
00134 const mcb::edge_num& enumb,
00135 leda::array< leda::d_int_set >& C );
00136
00137 extern void MCB_output_basis( const leda::graph& g,
00138 const leda::array< mcb::spvecgf2 >& C,
00139 const mcb::edge_num& enumb,
00140 leda::array< leda::list< leda::edge > >& mcb );
00141
00142 extern void MCB_output_basis( const leda::graph& g,
00143 const leda::array< mcb::spvecgf2 >& C,
00144 const mcb::edge_num& enumb,
00145 leda::array< leda::d_int_set >& mcb );
00146
00171 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00172 leda::array< leda::d_int_set >& mcb,
00173 leda::array< leda::d_int_set >& proof,
00174 const mcb::edge_num& enumb
00175 );
00176
00197 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00198 leda::array< leda::d_int_set >& mcb,
00199 const edge_num& enumb
00200 );
00201
00226 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00227 leda::array< mcb::spvecgf2 >& mcb,
00228 leda::array< mcb::spvecgf2 >& proof,
00229 const edge_num& enumb
00230 );
00231
00252 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00253 leda::array< mcb::spvecgf2 >& mcb,
00254 const edge_num& enumb
00255 );
00256
00278 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00279 leda::array< leda::list<leda::edge> >& mcb,
00280 leda::array< leda::list<leda::edge> >& proof
00281 );
00282
00299 extern int MIN_CYCLE_BASIS_DEPINA( const leda::graph& g,
00300 leda::array< leda::list<leda::edge> >& mcb
00301 );
00302
00303
00304 extern void MCB_construct_superset( const leda::graph& G,
00305 leda::sortseq< leda::two_tuple<int,int>, leda::d_int_set >& super,
00306 const edge_num& enumb);
00307
00308 extern void MCB_construct_unweighted_paths( const leda::graph& G,
00309 leda::node_array< leda::node_array<leda::edge> >& pred );
00310
00337 extern int MIN_CYCLE_BASIS_HYBRID( const leda::graph& g,
00338 leda::array< leda::d_int_set >& mcb,
00339 leda::array< leda::d_int_set >& proof,
00340 const edge_num& enumb
00341 );
00342
00363 extern int MIN_CYCLE_BASIS_HYBRID( const leda::graph& g,
00364 leda::array< leda::d_int_set >& mcb,
00365 const edge_num& enumb
00366 );
00367
00390 extern int MIN_CYCLE_BASIS_HYBRID( const leda::graph& g,
00391 leda::array< leda::list<leda::edge> >& mcb,
00392 leda::array< leda::list<leda::edge> >& proof
00393 );
00394
00411 extern int MIN_CYCLE_BASIS_HYBRID( const leda::graph& g,
00412 leda::array< leda::list<leda::edge> >& mcb
00413 );
00414
00415 extern void swap( leda::d_int_set& a, leda::d_int_set& b );
00416
00417
00418
00419 #line 2272 "MIN_CYCLE_BASIS.lw"
00420 template<class W, class CONT>
00421 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00422 const edge_array<W>& len,
00423 array< CONT >& mcb,
00424 array< CONT >& proof,
00425 const edge_num& enumb
00426 );
00427
00456 template<class W>
00457 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00458 const edge_array<W>& len,
00459 array< spvecgf2 >& mcb,
00460 array< spvecgf2 >& proof,
00461 const edge_num& enumb
00462 )
00463 {
00464 return MIN_CYCLE_BASIS_DEPINA< W, spvecgf2 >( g,len,mcb,proof,enumb );
00465 }
00466
00495 template<class W>
00496 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00497 const edge_array<W>& len,
00498 array< d_int_set >& mcb,
00499 array< d_int_set >& proof,
00500 const edge_num& enumb
00501 )
00502 {
00503 return MIN_CYCLE_BASIS_DEPINA< W, d_int_set >( g,len,mcb,proof,enumb );
00504 }
00505
00506
00507
00508 template<class W, class CONT>
00509 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00510 const edge_array<W>& len,
00511 array< CONT >& mcb,
00512 array< CONT >& proof,
00513 const edge_num& enumb
00514 )
00515 {
00516
00517 #line 2703 "MIN_CYCLE_BASIS.lw"
00518 #if ! defined(LEDA_CHECKING_OFF)
00519 if ( g.is_undirected() == false )
00520 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
00521 (directed?)");
00522 if ( Is_Undirected_Simple( g ) == false )
00523 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
00524 (parallel,anti-parallel edges or loops?)");
00525 #endif
00526
00527 #line 2369 "MIN_CYCLE_BASIS.lw"
00528
00529 #line 2741 "MIN_CYCLE_BASIS.lw"
00530 #if ! defined(LEDA_CHECKING_OFF)
00531 edge e1;
00532 forall_edges( e1 , g ) {
00533 if ( len[e1] < 0 )
00534 error_handler(999,"MIN_CYCLE_BASIS: illegal edge \
00535 (negative weight)");
00536 }
00537 #endif
00538
00539 #line 2370 "MIN_CYCLE_BASIS.lw"
00540
00541 #line 2729 "MIN_CYCLE_BASIS.lw"
00542 int N = enumb.dim_cycle_space();
00543 mcb.resize( N );
00544 proof.resize(N);
00545
00546
00547
00548 #line 2372 "MIN_CYCLE_BASIS.lw"
00549 #ifdef LEP_STATS
00550 float Tcycle = 0.0, Torthog = 0.0, Ttemp;
00551 #endif
00552
00553 array< CONT >& C = mcb;
00554 array< CONT >& S = proof;
00555
00556 #line 2757 "MIN_CYCLE_BASIS.lw"
00557
00558 sgraph<W,leda::bin_heap> sg( g , len, enumb ) ;
00559
00560
00561 #line 2380 "MIN_CYCLE_BASIS.lw"
00562
00563 for( int i = 0 ; i < N; i++ ) { S[i].insert( i ); }
00564
00565 W min = W(), ret = W();
00566
00567 for( int k = 0; k < N; k++ ) {
00568
00569 #line 2782 "MIN_CYCLE_BASIS.lw"
00570 #ifdef LEP_STATS
00571 leda::used_time( Ttemp );
00572 #endif
00573 #line 2822 "MIN_CYCLE_BASIS.lw"
00574 #ifndef MCB_LEP_UNDIR_NO_EXCHANGE_HEURISTIC
00575
00576 int minS = k;
00577 for( int r = k+1; r < N; r++ ) {
00578 if ( S[r].size() < S[minS].size() )
00579 minS = r;
00580 }
00581 if ( minS != k ) {
00582 mcb::swap( S[k], S[minS] );
00583 }
00584 #endif
00585
00586 #line 2786 "MIN_CYCLE_BASIS.lw"
00587 #ifdef LEP_STATS
00588 Torthog += leda::used_time( Ttemp );
00589 #endif
00590 #line 2835 "MIN_CYCLE_BASIS.lw"
00591 ret = sg.get_shortest_odd_cycle( S[k], C[k] );
00592 min+= ret;
00593
00594 #line 2790 "MIN_CYCLE_BASIS.lw"
00595 #ifdef LEP_STATS
00596 Tcycle += leda::used_time( Ttemp );
00597 #endif
00598
00599 #line 2840 "MIN_CYCLE_BASIS.lw"
00600 for( int l = k+1; l < N; l++ ) {
00601
00602
00603 if ( (C[k].intersect(S[l])).size() %2 == 1 ) {
00604 S[ l ] %= S[k];
00605 }
00606 }
00607
00608 #line 2794 "MIN_CYCLE_BASIS.lw"
00609 #ifdef LEP_STATS
00610 Torthog += leda::used_time( Ttemp );
00611 #endif
00612
00613
00614 #line 2387 "MIN_CYCLE_BASIS.lw"
00615 }
00616
00617 #ifdef LEP_STATS
00618 std::cout << "LEP_STATS: cycle computation time: " << Tcycle << std::endl;
00619 std::cout << "LEP_STATS: orthogonal base maintain time: " << Torthog << std::endl;
00620 #endif
00621
00622 return min;
00623 }
00624
00625
00626 #line 2403 "MIN_CYCLE_BASIS.lw"
00627
00651 template<class W>
00652 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00653 const edge_array<W>& len,
00654 array< d_int_set >& mcb,
00655 const edge_num& enumb
00656 )
00657 {
00658 array< d_int_set > proof_temp;
00659 return MIN_CYCLE_BASIS_DEPINA( g, len, mcb, proof_temp, enumb );
00660 }
00661
00686 template<class W>
00687 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00688 const edge_array<W>& len,
00689 array< spvecgf2 >& mcb,
00690 const edge_num& enumb
00691 )
00692 {
00693 array< spvecgf2 > proof_temp;
00694 return MIN_CYCLE_BASIS_DEPINA( g, len, mcb, proof_temp, enumb );
00695 }
00696
00697
00698 #line 2487 "MIN_CYCLE_BASIS.lw"
00699
00719 template<class W>
00720 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00721 const edge_array<W>& len,
00722 array< list<edge> >& mcb )
00723 {
00724 edge_num enumb(g);
00725 array< d_int_set > mcb_temp, proof_temp;
00726 W min = MIN_CYCLE_BASIS_DEPINA( g, len, mcb_temp, proof_temp, enumb );
00727
00728 MCB_output_basis( g, mcb_temp, enumb, mcb );
00729 return min;
00730 }
00731
00732
00733 #line 2527 "MIN_CYCLE_BASIS.lw"
00734
00760 template<class W>
00761 W MIN_CYCLE_BASIS_DEPINA( const graph& g,
00762 const edge_array<W>& len,
00763 array< list<edge> >& mcb,
00764 array< list<edge> >& proof)
00765 {
00766 edge_num enumb(g);
00767 array< d_int_set > mcb_temp, proof_temp;
00768 W min = MIN_CYCLE_BASIS_DEPINA( g, len, mcb_temp, proof_temp, enumb );
00769
00770 MCB_output_basis( g, mcb_temp, enumb, mcb );
00771 MCB_output_basis( g, proof_temp, enumb, proof );
00772 return min;
00773 }
00774
00775
00776 #line 4329 "MIN_CYCLE_BASIS.lw"
00777 template<class W>
00778 bool MIN_CYCLE_BASIS_DEPINA_CHECK( const graph& g,
00779 const edge_array<W>& len,
00780 array< d_int_set >& mcb,
00781 array< d_int_set >& proof,
00782 const edge_num& enumb )
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 {
00796
00797 #line 2703 "MIN_CYCLE_BASIS.lw"
00798 #if ! defined(LEDA_CHECKING_OFF)
00799 if ( g.is_undirected() == false )
00800 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
00801 (directed?)");
00802 if ( Is_Undirected_Simple( g ) == false )
00803 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
00804 (parallel,anti-parallel edges or loops?)");
00805 #endif
00806
00807 #line 4349 "MIN_CYCLE_BASIS.lw"
00808
00809 #line 2741 "MIN_CYCLE_BASIS.lw"
00810 #if ! defined(LEDA_CHECKING_OFF)
00811 edge e1;
00812 forall_edges( e1 , g ) {
00813 if ( len[e1] < 0 )
00814 error_handler(999,"MIN_CYCLE_BASIS: illegal edge \
00815 (negative weight)");
00816 }
00817 #endif
00818
00819 #line 4350 "MIN_CYCLE_BASIS.lw"
00820 sgraph<W,leda::bin_heap> sg( g, len, enumb );
00821
00822 if ( MCB_verify_basis( g, mcb, enumb, true ) == false ||
00823 MCB_verify_basis( g, proof, enumb, false ) == false ||
00824 mcb.size() != proof.size() )
00825 return false;
00826
00827
00828 W cycle_len;
00829 list<int> L;
00830 for( int i = 0; i < mcb.size(); i++ ) {
00831 d_int_set TEMP;
00832 W min = sg.get_shortest_odd_cycle( proof[i] , TEMP );
00833
00834
00835 cycle_len = W();
00836 L.clear();
00837 mcb[i].get_element_list(L);
00838 int el;
00839 forall( el, L ) cycle_len += len[ enumb(el) ];
00840
00841 if ( cycle_len != min )
00842 return false;
00843 }
00844 return true;
00845 }
00846
00847 template<class W>
00848 bool MIN_CYCLE_BASIS_DEPINA_CHECK( const graph& g,
00849 const edge_array<W>& len,
00850 array< spvecgf2 >& mcb,
00851 array< spvecgf2 >& proof,
00852 const edge_num& enumb )
00853
00854 {
00855 #if ! defined(LEDA_CHECKING_OFF)
00856 if ( mcb.size() != proof.size() || mcb.size() != enumb.dim_cycle_space() )
00857 error_handler(999,"MIN_CYCLE_BASIS: wrong array sizes :(");
00858 #endif
00859 array< d_int_set > mcbD;
00860 array< d_int_set > proofD;
00861 mcbD.resize( mcb.size() );
00862 proofD.resize( proof.size() );
00863 for( int i = 0; i < mcb.size(); i++ ) {
00864 mcbD[i] = mcb[i].to_d_int_set();
00865 proofD[i] = proof[i].to_d_int_set();
00866 }
00867 return MIN_CYCLE_BASIS_DEPINA_CHECK( g, len, mcbD, proofD, enumb );
00868 }
00869
00870
00871
00872 #line 4407 "MIN_CYCLE_BASIS.lw"
00873 template<class W>
00874 bool MIN_CYCLE_BASIS_DEPINA_CHECK( const graph& g,
00875 const edge_array<W>& len,
00876 array< list<edge> >& mcb,
00877 array< list<edge> >& proof
00878 )
00879 {
00880 edge_num enumb( g );
00881 array< d_int_set > mcb_temp, proof_temp;
00882 MCB_output_basis( g, mcb, enumb, mcb_temp );
00883 MCB_output_basis( g, proof, enumb, proof_temp );
00884 return MIN_CYCLE_BASIS_DEPINA_CHECK( g, len, mcb_temp, proof_temp, enumb );
00885 }
00886
00887
00888 #line 3754 "MIN_CYCLE_BASIS.lw"
00889
00890 template<class W>
00891 void MCB_construct_paths( const graph& G,
00892 const edge_array<W>& len,
00893 node_array< node_array<edge> >& pred
00894 )
00895 {
00896
00897 node v;
00898 node_array<W> dist(G);
00899
00900
00901 forall_nodes( v, G ) {
00902 pred[v].init( G, nil );
00903
00904
00905 DIJKSTRA_T<W>( G, v, len, dist, pred[v] );
00906 }
00907 }
00908
00909
00910
00911 template<class W>
00912 void MCB_construct_superset( const graph& G,
00913 const edge_array<W>& len,
00914 sortseq< three_tuple<W,int,int>, d_int_set >& super,
00915 const edge_num& enumb)
00916 {
00917
00918 #line 3833 "MIN_CYCLE_BASIS.lw"
00919
00920 d_int_set C;
00921 node v,w,u,vz,ezs,ezt;
00922 edge e,ez;
00923
00924 int c = 0;
00925 node_array<int> degree(G,0);
00926 node_set touched( G );
00927 bool dege;
00928
00929 #line 3783 "MIN_CYCLE_BASIS.lw"
00930 W min;
00931
00932
00933 node_array< node_array<edge> > pred( G );
00934 MCB_construct_paths<W>( G, len, pred );
00935
00936
00937 forall_nodes( v , G ) {
00938
00939
00940 forall_edges( e, G ) {
00941
00942 #line 3853 "MIN_CYCLE_BASIS.lw"
00943 dege = false;
00944
00945 w = G.source(e);
00946 u = G.target(e);
00947
00948
00949 if ( v == w || v == u ||
00950 pred[ v ][ w ] == nil || pred[ v ][ u ] == nil ||
00951 pred[ v ][ w ] == e || pred[ v ][ u ] == e ||
00952 pred[ w ][ v ] == e || pred[ u ][ v ] == e )
00953 continue;
00954
00955
00956 C.clear();
00957
00958
00959 C.insert( enumb(e) );
00960 ezs = G.source( e );
00961 ezt = G.target( e );
00962 degree[ ezs ]++;
00963 degree[ ezt ]++;
00964 touched.insert( ezs );
00965 touched.insert( ezt );
00966
00967
00968
00969 #line 3796 "MIN_CYCLE_BASIS.lw"
00970 min = len[ e ];
00971
00972
00973 int en;
00974 node x,y;
00975
00976
00977 if ( v->id() < w->id() ) { y = v; x = w; }
00978 else { y = w; x = v; }
00979
00980 #line 3889 "MIN_CYCLE_BASIS.lw"
00981 while( pred[ y ][ x ] != nil && dege == false ) {
00982 ez = pred[ y ][ x ];
00983 en = enumb( ez );
00984 if ( ! C.member( en ) ) {
00985 C.insert( en );
00986 ezs = G.source( ez );
00987 ezt = G.target( ez );
00988 degree[ ezs ]++;
00989 degree[ ezt ]++;
00990 if ( degree[ ezs ] > 2 || degree[ ezt ] > 2 )
00991 dege = true;
00992 touched.insert( ezs );
00993 touched.insert( ezt );
00994 min += len[ ez ];
00995 }
00996 x = G.opposite( ez, x );
00997 }
00998
00999 #line 3805 "MIN_CYCLE_BASIS.lw"
01000
01001 if ( v->id() < u->id() ) { y = v; x = u; }
01002 else { y = u; x = v; }
01003
01004 #line 3889 "MIN_CYCLE_BASIS.lw"
01005 while( pred[ y ][ x ] != nil && dege == false ) {
01006 ez = pred[ y ][ x ];
01007 en = enumb( ez );
01008 if ( ! C.member( en ) ) {
01009 C.insert( en );
01010 ezs = G.source( ez );
01011 ezt = G.target( ez );
01012 degree[ ezs ]++;
01013 degree[ ezt ]++;
01014 if ( degree[ ezs ] > 2 || degree[ ezt ] > 2 )
01015 dege = true;
01016 touched.insert( ezs );
01017 touched.insert( ezt );
01018 min += len[ ez ];
01019 }
01020 x = G.opposite( ez, x );
01021 }
01022
01023 #line 3808 "MIN_CYCLE_BASIS.lw"
01024
01025
01026
01027 while( touched.empty() == false ) {
01028 vz = touched.choose();
01029 touched.del( vz );
01030 if ( degree[ vz ] == 1 ) dege = true;
01031 degree[ vz ] = 0;
01032 }
01033
01034 if ( dege == true ) continue;
01035
01036
01037 three_tuple<W,int,int> tt( min, C.size(), c++ );
01038 super.insert( tt, C );
01039 }
01040 }
01041 }
01042
01043
01044 #line 4011 "MIN_CYCLE_BASIS.lw"
01045
01073 template<class W>
01074 W MIN_CYCLE_BASIS_HYBRID( const graph& g,
01075 const edge_array<W>& len,
01076 array< d_int_set >& mcb,
01077 array< d_int_set >& proof,
01078 const edge_num& enumb
01079 )
01080 {
01081
01082 #line 2703 "MIN_CYCLE_BASIS.lw"
01083 #if ! defined(LEDA_CHECKING_OFF)
01084 if ( g.is_undirected() == false )
01085 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
01086 (directed?)");
01087 if ( Is_Undirected_Simple( g ) == false )
01088 error_handler(999,"MIN_CYCLE_BASIS: illegal graph\
01089 (parallel,anti-parallel edges or loops?)");
01090 #endif
01091
01092 #line 4048 "MIN_CYCLE_BASIS.lw"
01093
01094 #line 2741 "MIN_CYCLE_BASIS.lw"
01095 #if ! defined(LEDA_CHECKING_OFF)
01096 edge e1;
01097 forall_edges( e1 , g ) {
01098 if ( len[e1] < 0 )
01099 error_handler(999,"MIN_CYCLE_BASIS: illegal edge \
01100 (negative weight)");
01101 }
01102 #endif
01103
01104 #line 4049 "MIN_CYCLE_BASIS.lw"
01105
01106 #line 2729 "MIN_CYCLE_BASIS.lw"
01107 int N = enumb.dim_cycle_space();
01108 mcb.resize( N );
01109 proof.resize(N);
01110
01111
01112
01113 #line 4051 "MIN_CYCLE_BASIS.lw"
01114 array< d_int_set >& C = mcb;
01115 array< d_int_set >& S = proof;
01116
01117
01118 for( int i = 0 ; i < N; i++ ) { S[i].insert( i ); }
01119
01120
01121 sortseq< three_tuple<W,int,int> ,d_int_set> super( leda::compare );
01122 MCB_construct_superset<W>( g, len, super, enumb );
01123
01124 #ifdef LEP_STATS
01125 static int lep_stats_queries = 0;
01126 std::cout << "LEP_STATS: horton set size: " << super.size() << std::endl;
01127 #endif
01128
01129 W min = W(), ret = W();
01130 leda::seq_item s;
01131
01132 for( int k = 0; k < N; k++ ) {
01133
01134 #line 4094 "MIN_CYCLE_BASIS.lw"
01135 #ifdef LEP_STATS
01136 lep_stats_queries++;
01137 #endif
01138
01139
01140 s = super.min_item();
01141 bool f = false;
01142 while ( s != nil ) {
01143 if ( ( (super[s]).intersect( S[k] ) ).size() % 2 == 1 ) {
01144 C[k] = super[s];
01145 ret = super.key( s ).first();
01146 super.del_item( s );
01147 f = true;
01148 break;
01149 }
01150 s = super.succ( s );
01151
01152 #ifdef LEP_STATS
01153 lep_stats_queries++;
01154 #endif
01155 }
01156 if ( f == false )
01157 error_handler(999,"MIN_CYCLE_BASIS (HYBRID):\
01158 superset contains no MCB :(");
01159 min += ret;
01160
01161 #line 4071 "MIN_CYCLE_BASIS.lw"
01162
01163 #line 2840 "MIN_CYCLE_BASIS.lw"
01164 for( int l = k+1; l < N; l++ ) {
01165
01166
01167 if ( (C[k].intersect(S[l])).size() %2 == 1 ) {
01168 S[ l ] %= S[k];
01169 }
01170 }
01171
01172 #line 4072 "MIN_CYCLE_BASIS.lw"
01173 }
01174
01175 #ifdef LEP_STATS
01176 std::cout << "LEP_STATS: horton set queries: " << lep_stats_queries << std::endl;
01177 #endif
01178
01179 return min;
01180 }
01181
01182
01183 #line 4127 "MIN_CYCLE_BASIS.lw"
01184
01206 template<class W>
01207 W MIN_CYCLE_BASIS_HYBRID( const graph& g,
01208 const edge_array<W>& len,
01209 array< d_int_set >& mcb,
01210 const edge_num& enumb
01211 )
01212 {
01213 array< d_int_set > proof_temp;
01214 return MIN_CYCLE_BASIS_HYBRID( g, len, mcb, proof_temp, enumb );
01215 }
01216
01241 template<class W>
01242 W MIN_CYCLE_BASIS_HYBRID( const graph& g,
01243 const edge_array<W>& len,
01244 array< list<edge> >& mcb,
01245 array< list<edge> >& proof
01246 )
01247 {
01248 array< d_int_set > mcb_temp, proof_temp;
01249 edge_num enumb( g );
01250 W min = MIN_CYCLE_BASIS_HYBRID( g, len, mcb_temp, proof_temp, enumb );
01251 MCB_output_basis( g, mcb_temp, enumb, mcb );
01252 MCB_output_basis( g, mcb_temp, enumb, proof );
01253 return min;
01254 }
01255
01274 template<class W>
01275 W MIN_CYCLE_BASIS_HYBRID( const graph& g,
01276 const edge_array<W>& len,
01277 array< list<edge> >& mcb
01278 )
01279 {
01280 array< d_int_set > mcb_temp, proof_temp;
01281 edge_num enumb( g );
01282 W min = MIN_CYCLE_BASIS_HYBRID( g, len, mcb_temp, proof_temp, enumb );
01283 MCB_output_basis( g, mcb_temp, enumb, mcb );
01284 return min;
01285 }
01286
01287
01288 #line 1859 "MIN_CYCLE_BASIS.lw"
01289 }
01290
01291 #endif // MIN_CYCLE_BASIS_H
01292
01293 #line 6217 "MIN_CYCLE_BASIS.lw"
01294
01295
01296