/* expand.c */
#include "../Graph.h"
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------------------------
purpose -- take a Graph object and a map to expand it, create and
return a bigger unit weight Graph object. this is useful
for expanding a compressed graph into a unit weight graph.
created -- 96mar02, cca
---------------------------------------------------------------------
*/
Graph *
Graph_expand2 (
Graph *g,
IV *mapIV
) {
/*
---------------
check the input
---------------
*/
if ( g == NULL
|| g->nvtx <= 0
|| mapIV == NULL
|| IV_entries(mapIV) == NULL ) {
fprintf(stderr, "\n fatal error in Graph_expand2(%p,%p)"
"\n bad input\n", g, mapIV) ;
exit(-1) ;
}
return(Graph_expand(g, IV_size(mapIV), IV_entries(mapIV))) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------------------------
purpose -- take a Graph object and a map to expand it, create and
return a bigger unit weight Graph object. this is useful
for expanding a compressed graph into a unit weight graph.
created -- 96mar02, cca
---------------------------------------------------------------------
*/
Graph *
Graph_expand (
Graph *g,
int nvtxbig,
int map[]
) {
Graph *gbig ;
int count, ii, nedge, nvtx, v, vbig, vsize, w ;
int *head, *indices, *link, *mark, *vadj ;
IVL *adjIVL, *adjbigIVL ;
/*
---------------
check the input
---------------
*/
if ( g == NULL || nvtxbig <= 0 || map == NULL ) {
fprintf(stderr, "\n fatal error in Graph_expand(%p,%d,%p)"
"\n bad input\n", g, nvtxbig, map) ;
exit(-1) ;
}
nvtx = g->nvtx ;
adjIVL = g->adjIVL ;
/*
----------------------------------------
set up the linked lists for the vertices
----------------------------------------
*/
head = IVinit(nvtx, -1) ;
link = IVinit(nvtxbig, -1) ;
for ( vbig = 0 ; vbig < nvtxbig ; vbig++ ) {
v = map[vbig] ;
link[vbig] = head[v] ;
head[v] = vbig ;
}
/*
--------------------------------
create the expanded Graph object
--------------------------------
*/
gbig = Graph_new() ;
Graph_init1(gbig, 0, nvtxbig, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjbigIVL = gbig->adjIVL ;
/*
-------------------------------------------
fill the lists in the expanded Graph object
-------------------------------------------
*/
indices = IVinit(nvtxbig, -1) ;
mark = IVinit(nvtx, -1) ;
nedge = 0 ;
for ( v = 0 ; v < nvtx ; v++ ) {
if ( head[v] != -1 ) {
/*
------------------------------
load the indices that map to v
------------------------------
*/
mark[v] = v ;
count = 0 ;
for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
indices[count++] = vbig ;
}
/*
---------------------------------------------------
load the indices that map to vertices adjacent to v
---------------------------------------------------
*/
IVL_listAndSize(adjIVL, v, &vsize, &vadj) ;
for ( ii = 0 ; ii < vsize ; ii++ ) {
w = vadj[ii] ;
if ( w < nvtx && mark[w] != v ) {
mark[w] = v ;
for ( vbig = head[w] ; vbig != -1 ; vbig = link[vbig] ) {
indices[count++] = vbig ;
}
}
}
/*
--------------------------------------
sort the index list in ascending order
--------------------------------------
*/
IVqsortUp(count, indices) ;
/*
-------------------------------------------------------
each vertex in the big IVL object has its own list.
-------------------------------------------------------
*/
for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
IVL_setList(adjbigIVL, vbig, count, indices) ;
nedge += count ;
}
}
}
gbig->nedges = nedge ;
/*
------------------------
free the working storage
------------------------
*/
IVfree(head) ;
IVfree(link) ;
IVfree(indices) ;
IVfree(mark) ;
return(gbig) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1