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 #include <sofa/component/topology/EdgeSetTopologyModifier.h>
00026 #include <sofa/component/topology/EdgeSetTopologyChange.h>
00027 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00028 #include <algorithm>
00029 #include <functional>
00030 #include <iostream>
00031 #include <sofa/core/ObjectFactory.h>
00032
00033
00034
00035
00036 #include <boost/config.hpp>
00037 #include <iostream>
00038 #include <vector>
00039 #include <utility>
00040
00041 #include <boost/graph/adjacency_list.hpp>
00042 #include <boost/graph/connected_components.hpp>
00043
00044 #include <boost/graph/cuthill_mckee_ordering.hpp>
00045 #include <boost/graph/bandwidth.hpp>
00046
00047 namespace sofa
00048 {
00049
00050 namespace component
00051 {
00052
00053 namespace topology
00054 {
00055 using namespace sofa::defaulttype;
00056 SOFA_DECL_CLASS(EdgeSetTopologyModifier)
00057 int EdgeSetTopologyModifierClass = core::RegisterObject("Edge set topology modifier")
00058 .add< EdgeSetTopologyModifier >();
00059
00060 using namespace std;
00061 using namespace sofa::defaulttype;
00062 using namespace sofa::core::componentmodel::behavior;
00063
00064 void EdgeSetTopologyModifier::init()
00065 {
00066 PointSetTopologyModifier::init();
00067 getContext()->get(m_container);
00068 }
00069
00070 void EdgeSetTopologyModifier::addEdgeProcess(Edge e)
00071 {
00072 #ifndef NDEBUG
00073
00074 if(e[0] == e[1])
00075 {
00076 cout << "Error: [EdgeSetTopologyModifier::addEdge] : invalid edge: "
00077 << e[0] << ", " << e[1] << endl;
00078
00079 return;
00080 }
00081
00082
00083
00084 if(m_container->hasEdgeVertexShell())
00085 {
00086 if(m_container->getEdgeIndex(e[0],e[1]) != -1)
00087 {
00088 cout << "Error: [EdgeSetTopologyModifier::addEdgesProcess] : Edge "
00089 << e[0] << ", " << e[1] << " already exists." << endl;
00090 return;
00091 }
00092 }
00093 #endif
00094 if (m_container->hasEdgeVertexShell())
00095 {
00096 const unsigned int edgeId = m_container->getNumberOfEdges();
00097
00098 sofa::helper::vector< unsigned int > &shell0 = m_container->getEdgeVertexShellForModification( e[0] );
00099 shell0.push_back(edgeId);
00100
00101 sofa::helper::vector< unsigned int > &shell1 = m_container->getEdgeVertexShellForModification( e[1] );
00102 shell1.push_back(edgeId);
00103 }
00104
00105 m_container->m_edge.push_back(e);
00106 }
00107
00108
00109 void EdgeSetTopologyModifier::addEdgesProcess(const sofa::helper::vector< Edge > &edges)
00110 {
00111 for (unsigned int i=0; i<edges.size(); ++i)
00112 {
00113 addEdgeProcess(edges[i]);
00114 }
00115 }
00116
00117
00118 void EdgeSetTopologyModifier::addEdgesWarning(const unsigned int nEdges)
00119 {
00120
00121 EdgesAdded *e = new EdgesAdded(nEdges);
00122 addTopologyChange(e);
00123 }
00124
00125
00126 void EdgeSetTopologyModifier::addEdgesWarning(const unsigned int nEdges,
00127 const sofa::helper::vector< Edge >& edgesList,
00128 const sofa::helper::vector< unsigned int >& edgesIndexList)
00129 {
00130
00131 EdgesAdded *e = new EdgesAdded(nEdges, edgesList, edgesIndexList);
00132 addTopologyChange(e);
00133 }
00134
00135
00136 void EdgeSetTopologyModifier::addEdgesWarning(const unsigned int nEdges,
00137 const sofa::helper::vector< Edge >& edgesList,
00138 const sofa::helper::vector< unsigned int >& edgesIndexList,
00139 const sofa::helper::vector< sofa::helper::vector< unsigned int > > & ancestors)
00140 {
00141
00142 EdgesAdded *e = new EdgesAdded(nEdges, edgesList, edgesIndexList, ancestors);
00143 addTopologyChange(e);
00144 }
00145
00146
00147 void EdgeSetTopologyModifier::addEdgesWarning(const unsigned int nEdges,
00148 const sofa::helper::vector< Edge >& edgesList,
00149 const sofa::helper::vector< unsigned int >& edgesIndexList,
00150 const sofa::helper::vector< sofa::helper::vector< unsigned int > > & ancestors,
00151 const sofa::helper::vector< sofa::helper::vector< double > >& baryCoefs)
00152 {
00153
00154 EdgesAdded *e = new EdgesAdded(nEdges, edgesList, edgesIndexList, ancestors, baryCoefs);
00155 addTopologyChange(e);
00156 }
00157
00158
00159 void EdgeSetTopologyModifier::removeEdgesWarning(sofa::helper::vector<unsigned int> &edges )
00160 {
00161
00162 std::sort( edges.begin(), edges.end(), std::greater<unsigned int>() );
00163
00164
00165 EdgesRemoved *e = new EdgesRemoved(edges);
00166 addTopologyChange(e);
00167 }
00168
00169
00170 void EdgeSetTopologyModifier::removeEdgesProcess(const sofa::helper::vector<unsigned int> &indices,
00171 const bool removeIsolatedItems)
00172 {
00173 if(!m_container->hasEdges())
00174 {
00175 cout << "Warning. [EdgeSetTopologyModifier::removeEdgesProcess] edge array is empty." << endl;
00176 return;
00177 }
00178
00179 if(removeIsolatedItems && !m_container->hasEdgeVertexShell())
00180 {
00181 m_container->createEdgeVertexShellArray();
00182 }
00183
00184 sofa::helper::vector<unsigned int> vertexToBeRemoved;
00185
00186 unsigned int lastEdgeIndex = m_container->getNumberOfEdges() - 1;
00187 for (unsigned int i=0; i<indices.size(); ++i, --lastEdgeIndex)
00188 {
00189
00190 if(m_container->hasEdgeVertexShell())
00191 {
00192 const Edge &e = m_container->m_edge[ indices[i] ];
00193 const Edge &q = m_container->m_edge[ lastEdgeIndex ];
00194 const unsigned int point0 = e[0], point1 = e[1];
00195 const unsigned int point2 = q[0], point3 = q[1];
00196
00197 sofa::helper::vector< unsigned int > &shell0 = m_container->m_edgeVertexShell[ point0 ];
00198 shell0.erase( std::remove( shell0.begin(), shell0.end(), indices[i] ), shell0.end() );
00199 if(removeIsolatedItems && shell0.empty())
00200 {
00201 vertexToBeRemoved.push_back(point0);
00202 }
00203
00204 sofa::helper::vector< unsigned int > &shell1 = m_container->m_edgeVertexShell[ point1 ];
00205 shell1.erase( std::remove( shell1.begin(), shell1.end(), indices[i] ), shell1.end() );
00206 if(removeIsolatedItems && shell1.empty())
00207 {
00208 vertexToBeRemoved.push_back(point1);
00209 }
00210
00211 if(indices[i] < lastEdgeIndex)
00212 {
00213
00214 sofa::helper::vector< unsigned int > &shell2 = m_container->m_edgeVertexShell[ point2 ];
00215 replace(shell2.begin(), shell2.end(), lastEdgeIndex, indices[i]);
00216
00217
00218 sofa::helper::vector< unsigned int > &shell3 = m_container->m_edgeVertexShell[ point3 ];
00219 replace(shell3.begin(), shell3.end(), lastEdgeIndex, indices[i]);
00220 }
00221 }
00222
00223
00224 m_container->m_edge[ indices[i] ] = m_container->m_edge[ lastEdgeIndex ];
00225 m_container->m_edge.resize( lastEdgeIndex );
00226 }
00227
00228 if (! vertexToBeRemoved.empty())
00229 {
00230 removePointsWarning(vertexToBeRemoved);
00231
00232 propagateTopologicalChanges();
00233 removePointsProcess(vertexToBeRemoved);
00234 }
00235 }
00236
00237 void EdgeSetTopologyModifier::addPointsProcess(const unsigned int nPoints)
00238 {
00239
00240 PointSetTopologyModifier::addPointsProcess( nPoints );
00241
00242 if(m_container->hasEdgeVertexShell())
00243 m_container->m_edgeVertexShell.resize( m_container->getNbPoints() );
00244 }
00245
00246 void EdgeSetTopologyModifier::removePointsProcess(sofa::helper::vector<unsigned int> &indices,
00247 const bool removeDOF)
00248 {
00249
00250
00251 if(m_container->hasEdges())
00252 {
00253
00254 if(!m_container->hasEdgeVertexShell())
00255 m_container->createEdgeVertexShellArray();
00256
00257 unsigned int lastPoint = m_container->getNbPoints() - 1;
00258 for (unsigned int i=0; i<indices.size(); ++i, --lastPoint)
00259 {
00260
00261
00262 for (unsigned int j=0; j<m_container->m_edgeVertexShell[lastPoint].size(); ++j)
00263 {
00264 const int edgeId = m_container->m_edgeVertexShell[lastPoint][j];
00265
00266 if ( m_container->m_edge[ edgeId ][0] == lastPoint )
00267 m_container->m_edge[ edgeId ][0] = indices[i];
00268 else
00269 m_container->m_edge[ edgeId ][1] = indices[i];
00270 }
00271
00272
00273 m_container->m_edgeVertexShell[ indices[i] ] = m_container->m_edgeVertexShell[ lastPoint ];
00274 }
00275
00276 m_container->m_edgeVertexShell.resize( m_container->m_edgeVertexShell.size() - indices.size() );
00277 }
00278
00279
00280
00281 PointSetTopologyModifier::removePointsProcess( indices, removeDOF );
00282 }
00283
00284 void EdgeSetTopologyModifier::renumberPointsProcess( const sofa::helper::vector<unsigned int> &index,
00285 const sofa::helper::vector<unsigned int> &inv_index,
00286 const bool renumberDOF)
00287 {
00288 if(m_container->hasEdges())
00289 {
00290 if(m_container->hasEdgeVertexShell())
00291 {
00292
00293 sofa::helper::vector< sofa::helper::vector< unsigned int > > edgeVertexShell_cp = m_container->getEdgeVertexShellArray();
00294
00295 for (unsigned int i=0; i<index.size(); ++i)
00296 {
00297 m_container->m_edgeVertexShell[i] = edgeVertexShell_cp[ index[i] ];
00298 }
00299 }
00300
00301 for (unsigned int i=0; i<m_container->m_edge.size(); ++i)
00302 {
00303 const unsigned int p0 = inv_index[ m_container->m_edge[i][0] ];
00304 const unsigned int p1 = inv_index[ m_container->m_edge[i][1] ];
00305
00306 if(p0<p1)
00307 {
00308 m_container->m_edge[i][0] = p0;
00309 m_container->m_edge[i][1] = p1;
00310 }
00311 else
00312 {
00313 m_container->m_edge[i][0] = p1;
00314 m_container->m_edge[i][1] = p0;
00315 }
00316 }
00317 }
00318
00319
00320 PointSetTopologyModifier::renumberPointsProcess( index, inv_index, renumberDOF );
00321 }
00322
00323
00324 void EdgeSetTopologyModifier::swapEdgesProcess(const sofa::helper::vector< sofa::helper::vector< unsigned int > >& edgesPairs)
00325 {
00326 if(!m_container->hasEdges())
00327 return;
00328
00329
00330 sofa::helper::vector< Edge > v;
00331 v.reserve(2*edgesPairs.size());
00332
00333 sofa::helper::vector< unsigned int > edgeIndexList;
00334 edgeIndexList.reserve(2*edgesPairs.size());
00335
00336 sofa::helper::vector<sofa::helper::vector<unsigned int> > ancestorsArray;
00337 ancestorsArray.reserve(edgesPairs.size());
00338
00339 unsigned int nbEdges = m_container->getNumberOfEdges();
00340
00341 for (unsigned int i=0; i<edgesPairs.size(); ++i)
00342 {
00343 const unsigned int i1 = edgesPairs[i][0];
00344 const unsigned int i2 = edgesPairs[i][1];
00345
00346 const unsigned int p11 = m_container->getEdge(i1)[0];
00347 const unsigned int p12 = m_container->getEdge(i1)[1];
00348 const unsigned int p21 = m_container->getEdge(i2)[0];
00349 const unsigned int p22 = m_container->getEdge(i2)[1];
00350
00351 const Edge e1(p11, p21), e2(p12, p22);
00352
00353 v.push_back(e1);
00354 v.push_back(e2);
00355 edgeIndexList.push_back(nbEdges);
00356 edgeIndexList.push_back(nbEdges+1);
00357 nbEdges += 2;
00358
00359 sofa::helper::vector<unsigned int> ancestors(2);
00360 ancestors[0] = i1;
00361 ancestors[1] = i2;
00362 ancestorsArray.push_back(ancestors);
00363 }
00364
00365 addEdgesProcess( v );
00366
00367
00368 addEdgesWarning( v.size(), v, edgeIndexList, ancestorsArray);
00369
00370
00371 sofa::helper::vector< unsigned int > indices;
00372 indices.reserve(2*edgesPairs.size());
00373 for (unsigned int i=0; i<edgesPairs.size(); ++i)
00374 {
00375 indices.push_back( edgesPairs[i][0] );
00376 indices.push_back( edgesPairs[i][1] );
00377 }
00378 removeEdgesWarning(indices );
00379
00380
00381 propagateTopologicalChanges();
00382
00383
00384 removeEdgesProcess( indices );
00385 }
00386
00387
00388 void EdgeSetTopologyModifier::fuseEdgesProcess(const sofa::helper::vector< sofa::helper::vector< unsigned int > >& edgesPairs,
00389 const bool removeIsolatedPoints)
00390 {
00391 if(!m_container->hasEdges())
00392 return;
00393
00394
00395 sofa::helper::vector< Edge > v;
00396 v.reserve(edgesPairs.size());
00397
00398 sofa::helper::vector< unsigned int > edgeIndexList;
00399 edgeIndexList.reserve(edgesPairs.size());
00400
00401 sofa::helper::vector<sofa::helper::vector<unsigned int> > ancestorsArray;
00402 ancestorsArray.reserve(edgesPairs.size());
00403
00404 unsigned int nbEdges=m_container->getNumberOfEdges();
00405
00406 for (unsigned int i=0; i<edgesPairs.size(); ++i)
00407 {
00408 const unsigned int i1 = edgesPairs[i][0];
00409 const unsigned int i2 = edgesPairs[i][1];
00410
00411 unsigned int p11 = m_container->getEdge(i1)[0];
00412 unsigned int p22 = m_container->getEdge(i2)[1];
00413
00414 if(p11 == p22)
00415 {
00416 p11 = m_container->getEdge(i2)[0];
00417 p22 = m_container->getEdge(i1)[1];
00418 }
00419
00420 const Edge e (p11, p22);
00421 v.push_back(e);
00422
00423 edgeIndexList.push_back(nbEdges);
00424 nbEdges += 1;
00425
00426 sofa::helper::vector<unsigned int> ancestors(2);
00427 ancestors[0] = i1;
00428 ancestors[1] = i2;
00429 ancestorsArray.push_back(ancestors);
00430 }
00431
00432 addEdgesProcess( v );
00433
00434
00435 addEdgesWarning( v.size(), v, edgeIndexList, ancestorsArray);
00436
00437
00438 sofa::helper::vector< unsigned int > indices;
00439 indices.reserve(2*edgesPairs.size());
00440 for (unsigned int i=0; i<edgesPairs.size(); ++i)
00441 {
00442 indices.push_back( edgesPairs[i][0] );
00443 indices.push_back( edgesPairs[i][1] );
00444 }
00445
00446 removeEdgesWarning( indices );
00447
00448
00449 propagateTopologicalChanges();
00450
00451
00452 removeEdgesProcess( indices, removeIsolatedPoints );
00453 }
00454
00455
00456 void EdgeSetTopologyModifier::splitEdgesProcess(sofa::helper::vector<unsigned int> &indices,
00457 const bool removeIsolatedPoints)
00458 {
00459 if(!m_container->hasEdges())
00460 return;
00461
00462 sofa::helper::vector< sofa::helper::vector< double > > defaultBaryCoefs(indices.size());
00463
00464 sofa::helper::vector< sofa::helper::vector< unsigned int > > v(indices.size());
00465
00466 sofa::helper::vector< Edge > edges;
00467 edges.reserve(2*indices.size());
00468
00469 sofa::helper::vector< unsigned int > edgesIndex;
00470 edgesIndex.reserve(2*indices.size());
00471
00472 unsigned int nbEdges = m_container->getNumberOfEdges();
00473
00474 for (unsigned int i=0; i<indices.size(); ++i)
00475 {
00476 const unsigned int p1 = m_container->getEdge( indices[i] )[0];
00477 const unsigned int p2 = m_container->getEdge( indices[i] )[1];
00478
00479
00480 v[i].resize(2);
00481 v[i][0] = p1;
00482 v[i][1] = p2;
00483
00484
00485 const Edge e1( p1, m_container->getNbPoints() + i );
00486 const Edge e2( m_container->getNbPoints() + i, p2 );
00487 edges.push_back( e1 );
00488 edges.push_back( e2 );
00489 edgesIndex.push_back(nbEdges++);
00490 edgesIndex.push_back(nbEdges++);
00491
00492 defaultBaryCoefs[i].resize(2, 0.5f);
00493 }
00494
00495 addPointsProcess( indices.size());
00496
00497 addEdgesProcess( edges );
00498
00499
00500 addPointsWarning( indices.size(), v, defaultBaryCoefs);
00501
00502 addEdgesWarning( edges.size(), edges, edgesIndex);
00503
00504
00505 removeEdgesWarning( indices );
00506
00507 propagateTopologicalChanges();
00508
00509
00510 removeEdgesProcess( indices, removeIsolatedPoints );
00511 }
00512
00513
00514 void EdgeSetTopologyModifier::splitEdgesProcess(sofa::helper::vector<unsigned int> &indices,
00515 const sofa::helper::vector< sofa::helper::vector< double > >& baryCoefs,
00516 const bool removeIsolatedPoints)
00517 {
00518 if(!m_container->hasEdges())
00519 return;
00520
00521 sofa::helper::vector< sofa::helper::vector< unsigned int > > v(indices.size());
00522
00523 sofa::helper::vector< Edge > edges;
00524 edges.reserve(2*indices.size());
00525
00526 sofa::helper::vector< unsigned int > edgesIndex;
00527 edgesIndex.reserve(2*indices.size());
00528
00529 unsigned int nbEdges = m_container->getNumberOfEdges();
00530
00531 for (unsigned int i=0; i<indices.size(); ++i)
00532 {
00533 const unsigned int p1 = m_container->getEdge( indices[i] )[0];
00534 const unsigned int p2 = m_container->getEdge( indices[i] )[1];
00535
00536
00537 v[i].resize(2);
00538 v[i][0] = p1;
00539 v[i][1] = p2;
00540
00541
00542 const Edge e1( p1, m_container->getNbPoints() + i );
00543 const Edge e2( m_container->getNbPoints() + i, p2 );
00544 edges.push_back( e1 );
00545 edges.push_back( e2 );
00546 edgesIndex.push_back(nbEdges++);
00547 edgesIndex.push_back(nbEdges++);
00548 }
00549
00550 addPointsProcess( indices.size());
00551
00552 addEdgesProcess( edges );
00553
00554
00555 addPointsWarning( indices.size(), v, baryCoefs);
00556
00557 addEdgesWarning( edges.size(), edges, edgesIndex);
00558
00559
00560 removeEdgesWarning( indices );
00561
00562 propagateTopologicalChanges();
00563
00564
00565 removeEdgesProcess( indices, removeIsolatedPoints );
00566 }
00567
00568 void EdgeSetTopologyModifier::removeEdges(sofa::helper::vector< unsigned int >& edges,
00569 const bool removeIsolatedPoints)
00570 {
00572 removeEdgesWarning(edges);
00573
00574 propagateTopologicalChanges();
00575
00576 removeEdgesProcess( edges, removeIsolatedPoints );
00577
00578 m_container->checkTopology();
00579 }
00580
00581 void EdgeSetTopologyModifier::removeItems(sofa::helper::vector< unsigned int >& items)
00582 {
00583 removeEdges(items);
00584 }
00585
00586 void EdgeSetTopologyModifier::renumberPoints( const sofa::helper::vector<unsigned int> &index,
00587 const sofa::helper::vector<unsigned int> &inv_index)
00588 {
00590 renumberPointsWarning(index, inv_index);
00591
00592 propagateTopologicalChanges();
00593
00594 renumberPointsProcess(index, inv_index);
00595
00596 m_container->checkTopology();
00597 }
00598
00599 void EdgeSetTopologyModifier::addEdges(const sofa::helper::vector< Edge >& edges)
00600 {
00601 unsigned int nEdges = m_container->getNumberOfEdges();
00602
00604 addEdgesProcess(edges);
00605
00606 sofa::helper::vector<unsigned int> edgesIndex;
00607 edgesIndex.reserve(edges.size());
00608
00609 for (unsigned int i=0; i<edges.size(); ++i)
00610 {
00611 edgesIndex.push_back(nEdges+i);
00612 }
00613
00614
00615 addEdgesWarning( edges.size(), edges, edgesIndex);
00616
00617
00618 propagateTopologicalChanges();
00619 }
00620
00621 void EdgeSetTopologyModifier::addEdges(const sofa::helper::vector< Edge >& edges,
00622 const sofa::helper::vector< sofa::helper::vector< unsigned int > > & ancestors,
00623 const sofa::helper::vector< sofa::helper::vector< double > >& baryCoefs)
00624 {
00625 unsigned int nEdges = m_container->getNumberOfEdges();
00626
00628 addEdgesProcess(edges);
00629
00630 sofa::helper::vector<unsigned int> edgesIndex;
00631 edgesIndex.reserve(edges.size());
00632
00633 for (unsigned int i=0; i<edges.size(); ++i)
00634 {
00635 edgesIndex.push_back(nEdges+i);
00636 }
00637
00638
00639 addEdgesWarning( edges.size(), edges, edgesIndex, ancestors, baryCoefs);
00640
00641
00642 propagateTopologicalChanges();
00643 }
00644
00645 void EdgeSetTopologyModifier::swapEdges(const sofa::helper::vector< sofa::helper::vector< unsigned int > >& edgesPairs)
00646 {
00647 swapEdgesProcess(edgesPairs);
00648 m_container->checkTopology();
00649 }
00650
00651 void EdgeSetTopologyModifier::fuseEdges(const sofa::helper::vector< sofa::helper::vector< unsigned int > >& edgesPairs, const bool removeIsolatedPoints)
00652 {
00653 fuseEdgesProcess(edgesPairs, removeIsolatedPoints);
00654 m_container->checkTopology();
00655 }
00656
00657 void EdgeSetTopologyModifier::splitEdges( sofa::helper::vector<unsigned int> &indices,
00658 const bool removeIsolatedPoints)
00659 {
00660 splitEdgesProcess(indices, removeIsolatedPoints);
00661 m_container->checkTopology();
00662 }
00663
00664 void EdgeSetTopologyModifier::splitEdges( sofa::helper::vector<unsigned int> &indices,
00665 const sofa::helper::vector< sofa::helper::vector< double > >& baryCoefs,
00666 const bool removeIsolatedPoints)
00667 {
00668 splitEdgesProcess(indices, baryCoefs, removeIsolatedPoints);
00669 m_container->checkTopology();
00670 }
00671
00672
00673 void EdgeSetTopologyModifier::resortCuthillMckee(sofa::helper::vector<int>& inverse_permutation)
00674 {
00675 using namespace boost;
00676 using namespace std;
00677 typedef adjacency_list<vecS, vecS, undirectedS,
00678 property<vertex_color_t, default_color_type,
00679 property<vertex_degree_t,int> > > Graph;
00680 typedef graph_traits<Graph>::vertex_descriptor Vertex;
00681 typedef graph_traits<Graph>::vertices_size_type size_type;
00682
00683 Graph G;
00684
00685 const sofa::helper::vector<Edge> &ea=m_container->getEdgeArray();
00686
00687 for (unsigned int k=0; k<ea.size(); ++k)
00688 {
00689 add_edge(ea[k][0], ea[k][1], G);
00690 }
00691
00692 inverse_permutation.resize(num_vertices(G));
00693
00694 property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G);
00695
00696 std::cout << "original bandwidth: " << bandwidth(G) << std::endl;
00697
00698 std::vector<Vertex> inv_perm(num_vertices(G));
00699 std::vector<size_type> perm(num_vertices(G));
00700
00701
00702 cuthill_mckee_ordering(G, inv_perm.rbegin());
00703
00704
00705
00706 unsigned int ind_i = 0;
00707 for (std::vector<Vertex>::const_iterator it = inv_perm.begin();
00708 it != inv_perm.end(); ++it)
00709 {
00710
00711 inverse_permutation[ind_i++]=index_map[*it];
00712 }
00713
00714
00715 for (size_type c=0; c!=inv_perm.size(); ++c)
00716 perm[index_map[inv_perm[c]]] = c;
00717
00718 std::cout << " bandwidth: "
00719 << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
00720 << std::endl;
00721 }
00722
00723
00724 }
00725
00726 }
00727
00728 }
00729