graph/example/minimum_degree_ordering.cpp

185 lines
4.6 KiB
C++

//-*-c++-*-
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Lie-Quan Lee
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
/*
This file is to demo how to use minimum_degree_ordering algorithm.
Important Note: This implementation requires the BGL graph to be
directed. Therefore, nonzero entry (i, j) in a symmetrical matrix
A coresponds to two directed edges (i->j and j->i).
The bcsstk01.rsa is an example graph in Harwell-Boeing format,
and bcsstk01 is the ordering produced by Liu's MMD implementation.
Link this file with iohb.c to get the harwell-boeing I/O functions.
To run this example, type:
./minimum_degree_ordering bcsstk01.rsa bcsstk01
*/
#include <boost/config.hpp>
#include <fstream>
#include <iostream>
#include "boost/graph/adjacency_list.hpp"
#include "boost/graph/graph_utility.hpp"
#include "boost/graph/minimum_degree_ordering.hpp"
void terminate(const char* msg)
{
std::cerr << msg << std::endl;
abort();
}
//copy and modify from mtl harwell boeing stream
struct harwell_boeing
{
harwell_boeing(char* filename) {
int Nrhs;
char* Type;
Type = new char[4];
isComplex = false;
// Never called:
//readHB_info(filename, &M, &N, &nonzeros, &Type, &Nrhs);
colptr = (int *)malloc((N+1)*sizeof(int));
if ( colptr == NULL ) terminate("Insufficient memory for colptr.\n");
rowind = (int *)malloc(nonzeros*sizeof(int));
if ( rowind == NULL ) terminate("Insufficient memory for rowind.\n");
if ( Type[0] == 'C' ) {
isComplex = true;
val = (double *)malloc(nonzeros*sizeof(double)*2);
if ( val == NULL ) terminate("Insufficient memory for val.\n");
} else {
if ( Type[0] != 'P' ) {
val = (double *)malloc(nonzeros*sizeof(double));
if ( val == NULL ) terminate("Insufficient memory for val.\n");
}
}
// Never called:
//readHB_mat_double(filename, colptr, rowind, val);
cnt = 0;
col = 0;
delete [] Type;
}
~harwell_boeing() {
free(colptr);
free(rowind);
free(val);
}
inline int nrows() const { return M; }
int cnt;
int col;
int* colptr;
bool isComplex;
int M;
int N;
int nonzeros;
int* rowind;
double* val;
};
int main(int argc, char* argv[])
{
using namespace std;
using namespace boost;
if (argc < 2) {
cout << argv[0] << " HB file" << endl;
return -1;
}
int delta = 0;
if ( argc >= 4 )
delta = atoi(argv[3]);
harwell_boeing hbs(argv[1]);
//must be BGL directed graph now
typedef adjacency_list<vecS, vecS, directedS> Graph;
int n = hbs.nrows();
cout << "n is " << n << endl;
Graph G(n);
int num_edge = 0;
for (int i = 0; i < n; ++i)
for (int j = hbs.colptr[i]; j < hbs.colptr[i+1]; ++j)
if ( (hbs.rowind[j - 1] - 1 ) > i ) {
add_edge(hbs.rowind[j - 1] - 1, i, G);
add_edge(i, hbs.rowind[j - 1] - 1, G);
num_edge++;
}
cout << "number of off-diagnal elements: " << num_edge << endl;
typedef std::vector<int> Vector;
Vector inverse_perm(n, 0);
Vector perm(n, 0);
Vector supernode_sizes(n, 1); // init has to be 1
boost::property_map<Graph, vertex_index_t>::type
id = get(vertex_index, G);
Vector degree(n, 0);
minimum_degree_ordering
(G,
make_iterator_property_map(&degree[0], id, degree[0]),
&inverse_perm[0],
&perm[0],
make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]),
delta, id);
if ( argc >= 3 ) {
ifstream input(argv[2]);
if ( input.fail() ) {
cout << argv[3] << " is failed to open!. " << endl;
return -1;
}
int comp;
bool is_correct = true;
int i;
for ( i=0; i<n; i++ ) {
input >> comp;
if ( comp != inverse_perm[i]+1 ) {
cout << "at i= " << i << ": " << comp
<< " ***is NOT EQUAL to*** " << inverse_perm[i]+1 << endl;
is_correct = false;
}
}
for ( i=0; i<n; i++ ) {
input >> comp;
if ( comp != perm[i]+1 ) {
cout << "at i= " << i << ": " << comp
<< " ***is NOT EQUAL to*** " << perm[i]+1 << endl;
is_correct = false;
}
}
if ( is_correct )
cout << "Permutation and inverse permutation are correct. "<< endl;
else
cout << "WARNING -- Permutation or inverse permutation is not the "
<< "same ones generated by Liu's " << endl;
}
return 0;
}