dir_min_cycle_basis.h

Go to the documentation of this file.
00001 #line 6220 "MIN_CYCLE_BASIS.lw"
00002 //---------------------------------------------------------------------
00003 // File automatically generated using notangle from DMIN_CYCLE_BASIS.lw
00004 //
00005 // emails and bugs: Dimitris Michail <michail@mpi-inf.mpg.de>
00006 //---------------------------------------------------------------------
00007 //
00008 // This program can be freely used in an academic environment
00009 // ONLY for research purposes, subject to the following restrictions:
00010 //
00011 // 1. The origin of this software must not be misrepresented; you must not
00012 //    claim that you wrote the original software. If you use this software
00013 //    an acknowledgment in the product documentation is required.
00014 // 2. Altered source versions must be plainly marked as such, and must not be
00015 //    misrepresented as being the original software.
00016 // 3. This notice may not be removed or altered from any source distribution.
00017 //
00018 // Any other use is strictly prohibited by the author, without an explicit 
00019 // permission.
00020 //
00021 // Note that this program uses the LEDA library, which is NOT free. For more 
00022 // details visit Algorithmic Solutions at http://www.algorithmic-solutions.com/
00023 //
00024 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00025 // ! Any commercial use of this software is strictly !
00026 // ! prohibited without explicit permission by the   !
00027 // ! author.                                         !
00028 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00029 //
00030 // This software is distributed in the hope that it will be useful,
00031 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00032 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00033 //
00034 // Copyright (C) 2004-2005 - Dimitris Michail <michail@mpi-inf.mpg.de>
00035 
00036 
00037 #line 6081 "MIN_CYCLE_BASIS.lw"
00038 
00079 #ifndef DIR_MIN_CYCLE_BASIS_H
00080 #define DIR_MIN_CYCLE_BASIS_H
00081 
00082 #ifdef LEDA_GE_V5
00083 #include <LEDA/graph/graph.h>
00084 #include <LEDA/graph/edge_array.h>
00085 #include <LEDA/core/array.h>
00086 #include <LEDA/core/list.h>
00087 #include <LEDA/core/p_queue.h>
00088 #include <LEDA/core/random_source.h>
00089 #include <LEDA/core/sortseq.h>
00090 #include <LEDA/core/tuple.h>
00091 #include <LEDA/numbers/integer.h>
00092 #else
00093 #include <LEDA/graph.h>
00094 #include <LEDA/array.h>
00095 #include <LEDA/edge_array.h>
00096 #include <LEDA/list.h>
00097 #include <LEDA/integer.h>
00098 #include <LEDA/p_queue.h>
00099 #include <LEDA/random_source.h>
00100 #include <LEDA/sortseq.h>
00101 #include <LEDA/tuple.h>
00102 #endif
00103 
00104 #include <LEP/mcb/edge_num.h>
00105 #include <LEP/mcb/fp.h>
00106 #include <LEP/mcb/arithm.h>
00107 
00108 namespace mcb { 
00109 
00110 #if defined(LEDA_NAMESPACE)
00111 using leda::graph;
00112 using leda::edge;
00113 using leda::edge_array;
00114 using leda::node;
00115 using leda::node_array;
00116 using leda::array;
00117 using leda::list;
00118 using leda::node_list;
00119 using leda::integer;
00120 using leda::random_source;
00121 using leda::p_queue;
00122 using leda::pq_item;
00123 using leda::sortseq;
00124 using leda::seq_item;
00125 using leda::three_tuple;
00126 using leda::four_tuple;
00127 #endif
00128 
00129 
00130 #line 6256 "MIN_CYCLE_BASIS.lw"
00131 // from sparse vector to list of edges
00132 void spvecfp_to_list_edges( const graph& g, const edge_num& enumb, 
00133         const spvecfp& in, list<edge>& out ); 
00134 
00135 // from sparse vector to array of integers
00136 void spvecfp_to_array_ints( const graph& g, const edge_num& enumb,
00137         const ptype& p, const spvecfp& in, array<etype>& out );
00138 
00139 // verify that a sparse vector represents a cycle
00140 bool DMCB_verify_cycle( const graph& g, 
00141         const edge_num& enumb,
00142         const spvecfp& cycle );
00143 
00144 // check that all cycles of an array are indeed cycles
00145 // precondition, cycles array is C style [0..size-1]
00146 bool DMCB_verify_cycles( const graph& g,
00147         const edge_num& enumb,
00148         const array< spvecfp >& cycles );
00149 
00150 // check that set of cycles are really a Basis
00151 bool DMCB_verify_basis( const graph& g,
00152         const edge_num& enumb,
00153         const array< spvecfp >& B,
00154         const array< spvecfp >& X ); 
00155 
00156 
00157 
00158 #line 6723 "MIN_CYCLE_BASIS.lw"
00159 // defines for SSitem
00160 #define mcb_revi() first()
00161 #define mcb_dist() second()
00162 #define mcb_num_edges() third()
00163 #define mcb_pred() fourth()
00164 
00165 // defines for preditem
00166 #define mcb_edge() first()
00167 #define mcb_other_node_index() second()
00168 #define mcb_other_node() third()
00169 
00170 
00171 // T = weight
00172 // PT = type of prime p
00173 template<class T, class PT> 
00174 class dirsp { 
00175 
00176     typedef three_tuple< edge, PT, node > preditem;
00177     typedef four_tuple< pq_item, T, indextype, preditem > SSitem;
00178     typedef two_tuple< node, PT > pnode;
00179 
00180     public:
00181 
00182 
00183 #line 6755 "MIN_CYCLE_BASIS.lw"
00184     // constructor
00185     dirsp( const graph& g, const edge_array<T>& length , 
00186             const PT& pin, const edge_num& en ) : 
00187         n(g.number_of_nodes()), 
00188         m(g.number_of_edges()), 
00189         p( pin ), 
00190         G( g ),
00191         len ( length ),
00192         enumb( en ),
00193         SS( mcb::compare ),
00194         cycle ( m ),
00195         nodeid( g ), 
00196         marked( g, 0 ),
00197         Xe( g )
00198     {   
00199         // give a numbering to the nodes
00200         indextype i = 0; 
00201         node v;
00202         forall_nodes( v, g ) { 
00203             nodeid[ v ] = i;
00204             i++;
00205         }
00206     }
00207 
00208     // reinitialize with different p
00209     // used for execution on same graph but different p
00210     // in order to reduce error probability
00211     void reinit( const PT& pin ) { 
00212         p = pin;
00213     }
00214 
00215     // destructor
00216     ~dirsp() { 
00217     }
00218 
00219 
00220 #line 6807 "MIN_CYCLE_BASIS.lw"
00221     // compute shortest cycle
00222     spvecfp get_shortest_cycle( const spvecfp& X , T& weight ) { 
00223 
00224         // create X, on edge index
00225         fill_X( X );
00226 
00227         // run shortest paths
00228         weight = run_shortest_paths();
00229 
00230         // construct sparse vector from cycle
00231         spvecfp ret( m, p );
00232         for( indextype i = 0; i < m; i++ ) { 
00233             if ( cycle[ i ] != 0 ) { 
00234                 ret.append( i + 1 , cycle[i] ); 
00235             }
00236         }
00237 
00238         return ret;
00239     }
00240 
00241     private:
00242 
00243     // get X on edge index, by spvecfp
00244     void fill_X( const spvecfp& X ) { 
00245         edge e;
00246         forall_edges( e, G ) 
00247             Xe[ e ] = 0;
00248 
00249         list_item li = X.first();
00250         while( li != nil ) { 
00251             // note: spvecfp is indexed on 1..m
00252             //       but enumb on 0..m-1
00253             Xe[ enumb( X.index( li ) - 1 ) ] = X.inf( li ) ;
00254             li = X.succ( li );
00255         }
00256     }
00257 
00258 
00259 #line 6851 "MIN_CYCLE_BASIS.lw"
00260     // record a cycle, by traversing pred array
00261     void record_cycle( const PT& t, array< etype >& cyc ) { 
00262         cyc.init( 0 );
00263 
00264         PT cur = t;
00265         seq_item sicur = SS.lookup( cur );
00266         node u;
00267         edge e;
00268         while( SS[ sicur ].mcb_pred().mcb_edge() != nil ) { 
00269 
00270             u = SS[ sicur ].mcb_pred().mcb_other_node();
00271             e = SS[ sicur ].mcb_pred().mcb_edge();
00272             if ( u == G.target( e ) ) { // give + direction
00273                 cyc[ enumb( e ) ] = 1;
00274             }
00275             else { // give - direction
00276                 cyc[ enumb( e ) ] = -1;
00277             }
00278 
00279             cur = SS[ sicur ].mcb_pred().mcb_other_node_index();
00280             sicur = SS.lookup( cur );
00281         }
00282     }
00283 
00284 
00285 #line 6883 "MIN_CYCLE_BASIS.lw"
00286     // get the index of a node in the reverse index of the PQ
00287     inline PT get_revi_index( const node& v, const PT& level ) { 
00288         return level * n + nodeid[ v ];
00289     }
00290 
00291 
00292 #line 6899 "MIN_CYCLE_BASIS.lw"
00293     // init used data structures
00294     void init_used_dijkstra() { 
00295         // init marked
00296         while( marked_touched.empty() == false ) 
00297             marked[ marked_touched.pop() ] = 0;
00298 
00299         // init all nodes reached by SP
00300         SS.clear();
00301 
00302         // clear priority queue
00303         PQ.clear();
00304     }
00305 
00306 
00307 #line 6972 "MIN_CYCLE_BASIS.lw"
00308     // execute the shortest paths
00309     T run_shortest_paths( ) { 
00310 
00311         T minall = T(0);
00312         indextype minall_num_edges = 0;
00313         bool is_minall_inf = true;
00314 
00315 
00316 #line 6991 "MIN_CYCLE_BASIS.lw"
00317         node v; 
00318         forall_nodes( v, G ) { // do n shortest paths
00319 
00320             T min = T(0);
00321             indextype min_num_edges = 0;
00322             bool is_min_inf = true;
00323 
00324             // add source vertex to PQ
00325             PT vi = get_revi_index( v, 0 );
00326             SS.insert( vi , 
00327                     SSitem( PQ.insert( T(0) , pnode( v, 0 ) ),
00328                         T( 0 ),
00329                         0,
00330                         preditem( nil, 0 , nil )
00331                         ) 
00332                     );
00333 
00334 
00335 #line 7021 "MIN_CYCLE_BASIS.lw"
00336             // do shortest path
00337             pq_item pqi;
00338             node u, w; // nodes
00339             PT ul, wl; // levels
00340             PT uindex, windex; // index on arrays
00341             seq_item siu, siw;
00342             edge e;
00343             while( PQ.empty() == false ) { 
00344                 // extract min
00345                 pqi = PQ.find_min(); 
00346                 u = PQ[ pqi ].first(); // get vertex
00347                 ul = PQ[ pqi ].second(); // get level
00348                 PQ.del_item( pqi );
00349 
00350                 // find index of u in level graph
00351                 uindex = get_revi_index( u, ul );
00352                 siu = SS.lookup( uindex );
00353 
00354                 // check if we are done
00355                 if ( u == v && ul != 0 ) { 
00356                     min = SS[ siu ].mcb_dist();
00357                     min_num_edges = SS[ siu ].mcb_num_edges();
00358                     is_min_inf = false;
00359                     break;
00360                 }
00361 
00362 
00363 #line 7059 "MIN_CYCLE_BASIS.lw"
00364                 // check if vertex is too far
00365                 if ( marked[ u ] >= 2 ) continue;
00366 
00367                 // increment marked
00368                 marked[ u ] = marked[ u ] + 1;
00369                 if ( marked[ u ] == 1 ) marked_touched.append( u );
00370 
00371 
00372 
00373 #line 7086 "MIN_CYCLE_BASIS.lw"
00374                 // find neighbors
00375                 forall_inout_edges( e, u ) { 
00376 
00377                     w = G.opposite( e, u );
00378 
00379                     // find level of w
00380                     if ( w == G.target( e ) ) {  // e = u -> w
00381                         wl = ( ul + Xe[ e ] ) % p;
00382                     }
00383                     else { // e = w -> u
00384                         wl = ( ul - Xe[ e ] ) % p;
00385                     }
00386                     while ( wl < 0 ) wl += p; // [-i]_p = [p-i]_p
00387 
00388 
00389 #line 7110 "MIN_CYCLE_BASIS.lw"
00390                     // find index in level graph
00391                     windex = get_revi_index( w, wl );
00392                     siw = SS.lookup( windex );
00393 
00394                     // now update if necessary
00395                     T c = SS[ siu ].mcb_dist() + len [ e ];
00396                     if ( siw == nil ) { 
00397                         // don't insert if more than current minimum
00398                         if ( is_minall_inf == false && c > minall )
00399                             continue;
00400                         // insert ( for now, with some info undetermined )
00401                         siw = SS.insert( windex, 
00402                                          SSitem( PQ.insert( c, pnode( w , wl ) ), 
00403                                          c , 
00404                                          0 , 
00405                                          preditem( nil, 0, nil ) ) );   
00406                     }
00407                     else if ( c < SS[ siw ].mcb_dist() ) { 
00408                         PQ.decrease_p( SS[ siw ].mcb_revi() , c );
00409                     }
00410                     else continue;
00411 
00412                     // record changes
00413                     SS[ siw ].mcb_dist() = c;
00414                     SS[ siw ].mcb_num_edges() = SS[ siu ].mcb_num_edges() + 1;
00415                     SS[ siw ].mcb_pred().mcb_edge() = e;
00416                     SS[ siw ].mcb_pred().mcb_other_node_index() = uindex;
00417                     SS[ siw ].mcb_pred().mcb_other_node() = u;
00418                 }
00419 
00420             }
00421 
00422 
00423 
00424 #line 7163 "MIN_CYCLE_BASIS.lw"
00425             // possible record path
00426             if ( is_min_inf == false ) {
00427                 if ( ( is_minall_inf == true ) ||
00428                         ( min < minall ) || 
00429                         ( ( min == minall ) && ( min_num_edges < minall_num_edges ) ) 
00430                    ) { 
00431                     // record new path as better either if it has less weight
00432                     // or if the weight is equal and it has less number of edges
00433 
00434                     // record path to a cycle
00435                     record_cycle( get_revi_index( u, ul ), cycle );
00436                     minall = min;
00437                     minall_num_edges = min_num_edges;
00438                     is_minall_inf = false;
00439                 }
00440             }
00441 
00442             // init touched data
00443             init_used_dijkstra();
00444         }
00445 
00446         // now return path found
00447         if ( is_minall_inf == true ) 
00448             leda::error_handler(999,"MIN_CYCLE_BASIS: no cycle found :(");
00449 
00450         return minall;
00451     }
00452 
00453 
00454 
00455 #line 7198 "MIN_CYCLE_BASIS.lw"
00456     // data structures
00457     int n,m;
00458     PT p;
00459     const graph& G;
00460     const edge_array< T > &len; // edge lengths
00461     const edge_num& enumb;      // edge numbering
00462     p_queue<T,pnode> PQ;        // priority queue
00463 
00464     // sortseq keys on node id of a node in levelg
00465     // SSitem
00466     // contains first()  = reverse index on priority queue, 
00467     //                     node(in levelg) -> pq_item
00468     //          second() = distance of shortest path in 
00469     //                     levelg to this node
00470     //          third()  = number of edges of shortest path in 
00471     //                     levelg to this node
00472     //          fourth() = predecessor as three_tuple in levelg 
00473     //                     to this node
00474     //                     preditem
00475     //                     contains first()  = edge e of g
00476     //                              second() = node id of other 
00477     //                                         end in levelg
00478     //                              third()  = node in g on other end
00479     sortseq< PT, SSitem > SS;
00480 
00481     array< etype > cycle;                // incident vector of cycles, indexed on 
00482                                          // numbering of edges (enumb(e))
00483     node_array< PT > nodeid;             // nodes' ids   of g
00484     node_array< unsigned short > marked; // marked nodes of g 
00485     node_list marked_touched;            // touched marked nodes 
00486     edge_array< PT > Xe;                 // help set to construct the cycle
00487 };
00488 
00489 // now undefine, all defined stuff for SSitem and preditem
00490 #undef mcb_revi
00491 #undef mcb_dist
00492 #undef mcb_num_edges
00493 #undef mcb_pred
00494 #undef mcb_edge
00495 #undef mcb_other_node_index
00496 #undef mcb_other_node
00497 
00498 #line 6294 "MIN_CYCLE_BASIS.lw"
00499 // W = weight type
00500 // ptype = type of prime p
00501 
00535 template<class W>
00536 W DIR_MIN_CYCLE_BASIS( const graph& g, 
00537     const edge_array<W>& len,
00538     array< spvecfp >& mcb,
00539     array< spvecfp >& proof,
00540     const edge_num& enumb,
00541     double error = 0.375
00542     )
00543 { 
00544 
00545 #line 6348 "MIN_CYCLE_BASIS.lw"
00546 #if ! defined(LEDA_CHECKING_OFF)
00547     if ( Is_Simple( g ) == false ) 
00548         error_handler(999,"MIN_CYCLE_BASIS: illegal graph (non-simple?)");
00549     if ( Is_Loopfree( g ) == false ) 
00550         error_handler(999,"MIN_CYCLE_BASIS: illegal graph (has loops?)");
00551     if ( error <= 0 || error >= 1 ) 
00552         error_handler(999,"MIN_CYCLE_BASIS: error probability is out of range");
00553 
00554     edge e1;
00555     forall_edges( e1 , g ) {
00556         if ( len[e1] <= 0 )
00557             error_handler(999,"MIN_CYCLE_BASIS: illegal edge (non-positive weight)");
00558     }
00559 #endif
00560 
00561 #line 6373 "MIN_CYCLE_BASIS.lw"
00562     int d = enumb.dim_cycle_space();
00563 
00564     // nothing to compute
00565     if ( d <= 0 ) return W(0);
00566 
00567     mcb.resize( d );
00568     proof.resize( d );
00569 
00570     int m = g.number_of_edges();
00571     //int n = g.number_of_nodes();
00572 
00573 
00574 #line 6409 "MIN_CYCLE_BASIS.lw"
00575     // decide how many times to execute the algorithm ( perror <= 3/8 = 0.375 )
00576     int times = (int) ceil(  log(error)/log(0.375) );
00577 
00578 #if  defined(LEP_DEBUG_OUTPUT)
00579     std::cout << "Executing " << times; 
00580     std::cout << " number of times to achieve error probability ";
00581     std::cout << error << std::endl;
00582 #endif
00583 
00584     // create X and B matrices
00585     array< spvecfp > X ( d );
00586     array< spvecfp > B ( d );
00587     W min_so_far = W(0);
00588     bool min_so_far_inf = true;
00589 
00590     // initialize shortest paths
00591     // for now use any prime number = 7
00592     dirsp<W,ptype> SP( g, len, 7, enumb );
00593 
00594     // loop necessary times, for error probability to be correct
00595     while( times-- > 0 ) { 
00596 
00597         // pick random prime
00598         ptype p;
00599         {
00600             int logd = log( integer( d + 1 ) );
00601             int loglogd = log( integer( logd + 1 ) );
00602             int randbits = 7 + 2 * logd + loglogd;
00603             int failsafe = 50 * randbits;
00604             int count = 0;
00605 
00606             while( true ) { 
00607                 // loop failsafe, increase random bits
00608                 if ( count++ > failsafe ) { 
00609                     randbits++;
00610                     failsafe += 50;
00611                     count = 0;
00612                 }
00613 
00614                 // get random number
00615                 p = ptype::random( randbits );
00616                 p += d*d;
00617                 //std::cout << "testing p = " << p << std::endl;
00618             
00619                 // if is > 1 and prime break
00620                 if ( p > 1 && primes<ptype>::is_prime( p ) ) break;
00621             }
00622         }
00623 
00624 #if  defined(LEP_DEBUG_OUTPUT)
00625         std::cout << "executing with prime p = " << p << std::endl;
00626 #endif
00627 
00628         // initialize shortest path class for this particular prime
00629         SP.reinit( p );
00630 
00631 #line 6479 "MIN_CYCLE_BASIS.lw"
00632         // initialize X_i's and $B_i$'s
00633         // assume that $p$ fits in ptype
00634         // and $d$ in indextype
00635         indextype i,j;
00636         for( i = 0; i < d; i++ ) { 
00637             X[i] = spvecfp( m , p );
00638             X[i] = i + 1;
00639             B[i] = spvecfp( m , p );
00640             B[i] = 0;
00641         }
00642 
00643 
00644 #line 6510 "MIN_CYCLE_BASIS.lw"
00645         // now execute main loop
00646         spvecfp tmp = spvecfp( m, p );
00647         ptype tmpi;
00648         W min = W(0);
00649         for( i = 0; i < d; i++ ) { 
00650 
00651             // compute B_i
00652             W mini;
00653             B[i] = SP.get_shortest_cycle( X[i], mini );
00654             min += mini;
00655 
00656             // precompute part
00657             // NOTE: we do not precompute inverses, since we don't want
00658             //       to have a dependency on the maximum size of an 
00659             //       array that will store these values
00660             //       p is O(d^2 logd) and thus O(logd) to compute inverse
00661             //       at most d times, thus O(d logd) = O(m logm) in total
00662             tmpi = X[i]*B[i];
00663             while( tmpi < 0 ) tmpi += p; // make [-i]_p = [p-i]_p
00664             while( tmpi >= p ) tmpi -= p; // make [i+p]_p = [i]_p
00665             tmp = X[i] * fp<ptype>::get_mult_inverse( tmpi, p );
00666 
00667             // update sets X_j, j > i
00668             for( j = i+1; j < d; j++ ) 
00669                 X[j] -=  tmp * (B[i] * X[j]) ;
00670         }
00671 
00672 
00673 #line 6545 "MIN_CYCLE_BASIS.lw"
00674         // if found better, update
00675         if ( ( min_so_far_inf == true ) || 
00676                 ( min_so_far_inf == false && min < min_so_far ) ) { 
00677 #if  defined(LEP_DEBUG_OUTPUT)
00678             if ( min_so_far_inf == false )
00679                 std::cout << "found better solution with weight " << min << std::endl;
00680 #endif
00681             mcb = B;
00682             proof = X;
00683             min_so_far_inf = false;
00684             min_so_far = min;
00685         }
00686 
00687     }
00688 
00689 
00690     return min_so_far;
00691 } // end of DIR_MIN_CYCLE_BASIS
00692 
00693 
00694 #line 6574 "MIN_CYCLE_BASIS.lw"
00695 
00723 template<class W>
00724 W DIR_MIN_CYCLE_BASIS( const graph& g, 
00725     const edge_array<W>& len,
00726     array< array<etype> >& mcb,
00727     const edge_num& enumb,
00728     double error = 0.375
00729     )
00730 {
00731     array< spvecfp > mcb_tmp;
00732     array< spvecfp > proof_tmp;
00733 
00734     int d = enumb.dim_cycle_space();
00735 
00736     // run the general version
00737     W min = DIR_MIN_CYCLE_BASIS<W>( g, len, mcb_tmp, \
00738             proof_tmp, enumb, error );
00739 
00740     // get p used
00741     ptype p = proof_tmp[0].pvalue(); 
00742 
00743     // transform
00744     mcb.resize( d );
00745     for ( int i = 0; i < d; i++ )
00746         spvecfp_to_array_ints( g, enumb, p, mcb_tmp[i], mcb[i] );       
00747 
00748     return min;
00749 }
00750 
00751 
00752 #line 6638 "MIN_CYCLE_BASIS.lw"
00753 
00776 template<class W>
00777 W DIR_MIN_CYCLE_BASIS( const graph& g, 
00778     const edge_array<W>& len,
00779     array< list<edge> >& mcb,
00780     double error = 0.375
00781     )
00782 {
00783     edge_num enumb( g );
00784     array< spvecfp > mcb_tmp;
00785     array< spvecfp > proof_tmp;
00786 
00787     int d = enumb.dim_cycle_space();
00788 
00789     // run the general version
00790     W min = DIR_MIN_CYCLE_BASIS<W>( g, len, mcb_tmp, \
00791             proof_tmp, enumb, error );
00792 
00793     // transform
00794     mcb.resize( d );
00795     for( int i = 0; i < d; i++ ) 
00796         spvecfp_to_list_edges( g, enumb, mcb_tmp[i], mcb[i] );
00797 
00798     return min;
00799 }
00800 
00801 
00802 #line 8037 "MIN_CYCLE_BASIS.lw"
00803 // from array of integers to sparse vectors
00804 void array_ints_to_spvecfp( const graph& g, const edge_num& enumb, const ptype &p,
00805     const array<etype>& in, spvecfp& out ) 
00806 { 
00807     int m = g.number_of_edges();
00808     out.reset( m, p );
00809 
00810     indextype i;
00811     for( i = 0; i < m; i++ ) { 
00812         if ( in[ i ] != 0 ) { 
00813             out.append( i+1, ptype(in[i]) );
00814         }
00815     }
00816 }
00817 
00818 
00819 
00820 
00821 #line 6180 "MIN_CYCLE_BASIS.lw"
00822 } // end of mcb namespace
00823 
00824 #endif // DIR_MIN_CYCLE_BASIS_H
00825 
00826 #line 6217 "MIN_CYCLE_BASIS.lw"
00827 /* ex: set ts=8 sw=4 sts=4 noet: */
00828 
00829 

Generated on Thu Mar 30 16:45:43 2006 for mcb LEDA Extension Package by  doxygen 1.4.6