umcb.h

Go to the documentation of this file.
00001 //
00002 // This program can be freely used in an academic environment
00003 // ONLY for research purposes, subject to the following restrictions:
00004 //
00005 // 1. The origin of this software must not be misrepresented; you must not
00006 //    claim that you wrote the original software. If you use this software
00007 //    an acknowledgment in the product documentation is required.
00008 // 2. Altered source versions must be plainly marked as such, and must not be
00009 //    misrepresented as being the original software.
00010 // 3. This notice may not be removed or altered from any source distribution.
00011 //
00012 // Any other use is strictly prohibited by the author, without an explicit 
00013 // permission.
00014 //
00015 // Note that this program uses the LEDA library, which is NOT free. For more 
00016 // details visit Algorithmic Solutions at http://www.algorithmic-solutions.com/
00017 // There is also a free version of LEDA 6.0 or newer.
00018 //
00019 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00020 // ! Any commercial use of this software is strictly !
00021 // ! prohibited without explicit permission by the   !
00022 // ! author.                                         !
00023 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00024 //
00025 // This software is distributed in the hope that it will be useful,
00026 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00027 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00028 //
00029 // Copyright (C) 2004-2008 - Dimitris Michail <dmixdim@googlemail.com>, <michail@mpi-inf.mpg.de>
00030 //
00031 // $Id: umcb.h 6878 2008-03-13 02:50:16Z dmichail $ 
00032 //
00033 
00063 #ifndef UMCB_H
00064 #define UMCB_H
00065 
00066 #include <LEP/mcb/config.h>
00067 
00068 #ifdef LEDA_GE_V5
00069 #include <LEDA/graph/graph.h>
00070 #include <LEDA/graph/edge_array.h>
00071 #include <LEDA/graph/node_array.h>
00072 #include <LEDA/core/d_int_set.h>
00073 #include <LEDA/core/array.h>
00074 #include <LEDA/core/list.h>
00075 #else
00076 #include <LEDA/graph.h>
00077 #include <LEDA/d_int_set.h>
00078 #include <LEDA/edge_array.h>
00079 #include <LEDA/node_array.h>
00080 #include <LEDA/array.h>
00081 #include <LEDA/list.h>
00082 #endif
00083 
00084 #include <LEP/mcb/spvecgf2.h>
00085 #include <LEP/mcb/signed.h>
00086 #include <LEP/mcb/superset.h>
00087 #include <LEP/mcb/sptrees.h>
00088 #include <LEP/mcb/transform.h>
00089 #include <LEP/mcb/verify.h>
00090 
00091 // start our namespace
00092 namespace mcb 
00093 { 
00094 
00095 #if defined(LEDA_NAMESPACE)
00096     using leda::graph;
00097     using leda::array;
00098     using leda::edge;
00099     using leda::edge_array;
00100     using leda::d_int_set;
00101     using leda::list;
00102 #endif
00103 
00104     template<typename W, class Container>
00105     class SupportMCB
00106     {
00107         public:
00108             typedef W result_type;
00109 
00110             SupportMCB( const graph& g_, 
00111                         array< Container >& mcb_, 
00112                         array< Container >& proof_,
00113                         const mcb::edge_num& enumb_ 
00114                         ) 
00115                 : g(g_), C(mcb_), S(proof_), enumb(enumb_), N(enumb_.dim_cycle_space())
00116             {
00117 #if ! defined(LEDA_CHECKING_OFF)
00118                 if ( Is_Undirected_Simple( g ) == false )
00119                     error_handler(999,"MIN_CYCLE_BASIS: illegal graph (parallel,anti-parallel edges or loops?)");
00120 #endif
00121                 C.resize(N);
00122                 S.resize(N);
00123             }
00124 
00125             virtual ~SupportMCB() {}
00126 
00127             W run() { 
00128                 checkPreconditions();
00129 
00130 #ifdef LEP_STATS
00131                 float Tcycle = 0.0, Torthog = 0.0, Ttemp;
00132 #endif
00133 
00134                 initializeSupportVectors();
00135                 
00136                 W min = W();
00137                 for( int k = 0; k < N; ++k ) {
00138 #ifdef LEP_STATS
00139                     leda::used_time( Ttemp );
00140 #endif
00141                     chooseSparsestSupportHeuristic( k );
00142 
00143 #ifdef LEP_STATS
00144                     Torthog += leda::used_time( Ttemp );
00145 #endif
00146 
00147                     min += computeShortestOddCycle( k );
00148 
00149 #ifdef LEP_STATS
00150                     Tcycle += leda::used_time( Ttemp );
00151 #endif
00152                     updateSupportVectors( k );
00153 
00154 #ifdef LEP_STATS
00155                     Torthog += leda::used_time( Ttemp );
00156 #endif
00157 
00158                 }
00159 
00160 #ifdef LEP_STATS
00161                 std::cout << "LEP_STATS: cycle computation time: " << Tcycle << std::endl;
00162                 std::cout << "LEP_STATS: orthogonal base maintain time: " << Torthog << std::endl;
00163 #endif
00164 
00165                 return min;
00166             }
00167 
00168         private:
00169 
00170             virtual void checkPreconditions() = 0;
00171 
00172             void initializeSupportVectors() {
00173                 for( int i = 0; i < N; ++i ) { 
00174                     S[i].clear(); 
00175                     S[i].insert(i); 
00176                 } 
00177             }
00178 
00179             void chooseSparsestSupportHeuristic( int k ) { 
00180 #ifndef MCB_LEP_UNDIR_NO_EXCHANGE_HEURISTIC
00181                 int minS = k;
00182                 for( int r = k+1; r < N; ++r ) {
00183                     if ( S[r].size() < S[minS].size() )
00184                         minS = r;
00185                 }
00186                 if ( minS != k ) {  // swap
00187                     std::swap( S[k], S[minS] );
00188                 }
00189 #endif
00190             }
00191 
00192             virtual W computeShortestOddCycle( int k ) = 0;
00193 
00194             void updateSupportVectors( int k ) { 
00195                 for( int l = k+1; l < N; ++l )   {
00196                     if ( (C[k].intersect(S[l])).size() % 2 == 1 )   {
00197                         S[ l ] %= S[k];
00198                     }
00199                 }
00200             }
00201 
00202         protected:
00203             const graph& g;
00204             array<Container>& C;
00205             array<Container>& S;
00206             const mcb::edge_num& enumb; 
00207             int N; 
00208     };
00209 
00210     template<typename W, class Container>
00211     class WeightedSupportMCB: public SupportMCB< W, Container>
00212     {
00213         public:
00214             typedef SupportMCB< W, Container> base_type;
00215 
00216             WeightedSupportMCB( const graph& g_, 
00217                                 const edge_array<W>& len_,
00218                         array< Container >& mcb_, 
00219                         array< Container >& proof_,
00220                         const mcb::edge_num& enumb_ ) 
00221                 : base_type( g_, mcb_, proof_, enumb_ ), len(len_)
00222             {
00223             }
00224 
00225         private:
00226 
00227             void checkPreconditions() { 
00228 #if ! defined(LEDA_CHECKING_OFF)
00229                 edge e;
00230                 forall_edges( e , g ) {
00231                     if ( len[e] < 0 )
00232                         error_handler(999,"MIN_CYCLE_BASIS: illegal edge (negative weight)");
00233                 }
00234 #endif
00235             }
00236 
00237         protected:
00238             const edge_array<W>& len;
00239             using base_type::g;
00240     };
00241 
00242     template<typename W, class Container>
00243     class WeightedSignedSupportMCB: public WeightedSupportMCB< W, Container>
00244     {
00245         public:
00246             typedef WeightedSupportMCB< W, Container> base_type;
00247 
00248             WeightedSignedSupportMCB( const graph& g_, 
00249                                 const edge_array<W>& len_,
00250                         array< Container >& mcb_, 
00251                         array< Container >& proof_,
00252                         const mcb::edge_num& enumb_ ) 
00253                 : base_type( g_, len_, mcb_, proof_, enumb_ ), sg(g_, len_, enumb_)
00254             {
00255             }
00256 
00257         private:
00258 
00259             W computeShortestOddCycle( int k ) { 
00260                 return sg.get_shortest_odd_cycle( S[k], C[k] );
00261             }
00262 
00263         private:
00264             detail::WeightedSignedGraph<W,leda::bin_heap> sg;
00265             using base_type::C;
00266             using base_type::S;
00267     };
00268 
00269     template<class Container>
00270     class UnweightedSignedSupportMCB: public SupportMCB< int, Container >
00271     {
00272         public:
00273             typedef SupportMCB< int, Container> base_type;
00274 
00275             UnweightedSignedSupportMCB( const graph& g_, 
00276                         array< Container >& mcb_, 
00277                         array< Container >& proof_,
00278                         const mcb::edge_num& enumb_ 
00279                         ) 
00280                 : base_type( g_, mcb_, proof_, enumb_ ), sg( g_, enumb_ )
00281             {
00282             }
00283 
00284             ~UnweightedSignedSupportMCB() {}
00285 
00286         private:
00287             int computeShortestOddCycle( int k ) { 
00288                 return sg.get_shortest_odd_cycle( S[k], C[k] );
00289             }
00290 
00291             void checkPreconditions() {}
00292 
00293         private:
00294             detail::UnweightedSignedGraph sg;
00295             using base_type::C;
00296             using base_type::S;
00297     };
00298 
00299     template<typename W, class Container>
00300     class WeightedHortonSupportMCB: public WeightedSupportMCB<W, Container>
00301     {
00302         public:
00303             typedef WeightedSupportMCB<W, Container> base_type;
00304 
00305             WeightedHortonSupportMCB( const graph& g_, 
00306                                 const edge_array<W>& len_,
00307                         array< Container >& mcb_, 
00308                         array< Container >& proof_,
00309                         const mcb::edge_num& enumb_ ) 
00310                 : base_type( g_, len_, mcb_, proof_, enumb_ ), HS( g_, len_, enumb_ )
00311             {
00312             }
00313 
00314         private:
00315 
00316             W computeShortestOddCycle( int k ) { 
00317                 return HS.get_shortest_odd_cycle( S[k], C[k] );
00318             }
00319 
00320             HortonSuperset<W> HS;
00321             using base_type::C;
00322             using base_type::S;
00323     };
00324 
00325     template<typename W, class Container>
00326     class WeightedSPTreesSupportMCB: public WeightedSupportMCB<W, Container>
00327     {
00328         public:
00329             typedef WeightedSupportMCB<W, Container> base_type;
00330 
00331             WeightedSPTreesSupportMCB( const graph& g_, 
00332                                 const edge_array<W>& len_,
00333                         array< Container >& mcb_, 
00334                         array< Container >& proof_,
00335                         const mcb::edge_num& enumb_ ) 
00336                 : base_type( g_, len_, mcb_, proof_, enumb_ ), uhst( g_, len_, enumb_ )
00337             {
00338             }
00339 
00340         private:
00341 
00342             W computeShortestOddCycle( int k ) { 
00343                 uhst.updateTreeLabels( S[k] );
00344                 return uhst.getShortestOddCycle( S[k], C[k] );
00345             }
00346 
00347             UndirectedHortonSupersetTrees<W> uhst;
00348             using base_type::C;
00349             using base_type::S;
00350     };
00351 
00352 
00353 
00370 
00399     template<class Container>
00400         int UMCB_SVA( const graph& g,
00401                 array< Container >& mcb,
00402                 array< Container >& proof,
00403                 const mcb::edge_num& enumb
00404                 ) 
00405         {
00406         UnweightedSignedSupportMCB<Container> tmp( g, mcb, proof, enumb );
00407         return tmp.run();
00408         }
00409 
00434     template<class Container>
00435     int UMCB_SVA( const graph& g, 
00436         array< Container >& mcb, 
00437         const mcb::edge_num& enumb
00438         )
00439     {
00440         array< Container > proof;
00441         return UMCB_SVA( g, mcb, proof, enumb );
00442     }
00443 
00476     template<class W, class Container>
00477         W UMCB_SVA( const graph& g,
00478                 const edge_array<W>& len,
00479                 array< Container >& mcb,
00480                 array< Container >& proof,
00481                 const mcb::edge_num& enumb
00482                 ) 
00483         { 
00484         WeightedSignedSupportMCB<W,Container> tmp( g, len, mcb, proof, enumb );
00485         return tmp.run();
00486     }
00487 
00516     template<class W, class Container>
00517         W UMCB_SVA( const graph& g,
00518                 const edge_array<W>& len,
00519                 array< Container >& mcb,
00520                 const mcb::edge_num& enumb
00521                 ) 
00522         { 
00523                 array< Container > proof;
00524         WeightedSignedSupportMCB<W,Container> tmp( g, len, mcb, proof, enumb );
00525         return tmp.run();
00526     }
00527 
00555     extern int UMCB_HYBRID( const leda::graph& g,
00556             leda::array< leda::d_int_set >& mcb,
00557             leda::array< leda::d_int_set >& proof,
00558             const mcb::edge_num& enumb
00559             );
00560 
00582     extern int UMCB_HYBRID( const leda::graph& g,
00583             leda::array< leda::d_int_set >& mcb,
00584             const mcb::edge_num& enumb
00585             );
00586 
00587 
00617     template<class W>
00618         W UMCB_HYBRID( const graph& g,
00619                 const edge_array<W>& len,
00620                 array< d_int_set >& mcb,
00621                 array< d_int_set >& proof,
00622                 const mcb::edge_num& enumb
00623                 ) 
00624         { 
00625             WeightedHortonSupportMCB<W, d_int_set> tmp( g, len, mcb, proof, enumb );  
00626             return tmp.run();
00627         }
00628 
00629 
00653     template<class W>
00654         W UMCB_HYBRID( const graph& g,
00655                 const edge_array<W>& len,
00656                 array< d_int_set >& mcb,
00657                 const mcb::edge_num& enumb
00658                 )
00659         {
00660             array< d_int_set > proof_temp;
00661             return UMCB_HYBRID( g, len, mcb, proof_temp, enumb );
00662         }
00663 
00694     template<class W>
00695     W UMCB_FH( const graph& g, 
00696                 const edge_array<W>& len,
00697                 array< mcb::spvecgf2 >& mcb, 
00698                 array< mcb::spvecgf2 >& proof, 
00699                 const mcb::edge_num& enumb ) 
00700     { 
00701         WeightedSPTreesSupportMCB<W,mcb::spvecgf2> tmp( g, len, mcb, proof, enumb );
00702         return tmp.run();
00703     }
00704 
00731     template<class W>
00732     W UMCB_FH( const graph& g, 
00733                 const edge_array<W>& len,
00734                 array< mcb::spvecgf2 >& mcb, 
00735                 const mcb::edge_num& enumb ) 
00736     { 
00737         array< mcb::spvecgf2 > proof;
00738         WeightedSPTreesSupportMCB<W,mcb::spvecgf2> tmp( g, len, mcb, proof, enumb );
00739         return tmp.run();
00740     }
00741 
00743 
00744 } // namespace mcb end
00745 
00746 #endif  // UMCB_H
00747 
00748 /* ex: set ts=4 sw=4 sts=4 et: */
00749 
00750 

Generated on Tue Apr 22 13:40:09 2008 for mcb LEDA Extension Package by  doxygen 1.4.6