blob: 6b84a60bc8fc4f3c21f60f13fb44f9c71cdb9e6f [file] [log] [blame]
/* #define DEBUG1 */
/* #define DEBUG2 */
#include "route.h"
#include "23tree.h"
extern TNODEPTR netRoot ;
TNODEPTR indexRoot ;
int treeSize ;
int pathIndex ;
extern int bareMinimum ;
extern void tinsert( TNODEPTR *root , int value , int property );
extern void recursePath( int dsptr , int atptr , int attachPt, int addEquivs);
extern void tpop( TNODEPTR *root , TNODEPTR *node , int *value ,
int *property);
extern int mshortest( int source , int soleTarget );
extern void tdelete( TNODEPTR *root , int value , int property );
extern void tmax( TNODEPTR *root , TNODEPTR *node , int *value ,
int *property);
void routenet( int segments , int numpnodes )
{
int i , j , savei , min , count , node , node1 , bareflag ;
GNODEPTR gptr , gptr1 ;
NNODEPTR nptr ;
LIST2PTR lptr ;
TNODEPTR tptr ;
if( segments > 2 ) {
i = MAXPATHS / (segments - 1) ;
Mpaths = ( i > 1 ) ? i : 1 ;
while( (pow( (double) Mpaths , (double)(segments - 1) ) >
80.0 * (double) MAXPATHS ) && (Mpaths > 1) ) {
Mpaths-- ;
}
} else {
Mpaths = 1 ;
}
bareflag = 0 ;
if( Mpaths == 1 && segments > 19 ) {
if( bareMinimum == 0 ) {
bareMinimum = 1 ;
bareflag = 1 ;
}
}
indexRoot = (TNODEPTR) NULL ;
treeSize = 0 ;
for( i = 1 ; i <= 2 * MAXPATHS ; i++ ) {
tinsert( &indexRoot , i , 0 ) ;
}
for( i = 1 ; i <= numpnodes ; i++ ) {
sourceList[i] = i + numnodes ;
delSourceList[i] = 0 ;
}
sourcePtr = numpnodes ;
for( i = 1 ; i <= numnodes + numpnodes ; i++ ) {
targetList[i] = 0 ;
addTargetList[i] = 0 ;
}
targetPtr = 0 ;
segPtr = 0 ;
min = VLARGE ;
for( i = 1 + numnodes ; i <= numpnodes + numnodes ; i++ ) {
nptr = pnodeArray[ i - numnodes ].nodeList ;
for( j = 1 + numnodes ; j <= numpnodes + numnodes ; j++ ) {
if( i == j ) {
continue ;
}
if( (pnodeArray[i - numnodes].eptr != 0) &&
(pnodeArray[j - numnodes].eptr != 0) ) {
if( pnodeArray[i - numnodes].eptr ==
pnodeArray[j - numnodes].eptr ) {
continue ;
}
} else if( (pnodeArray[i - numnodes].eptr == 0) &&
(pnodeArray[j - numnodes].eptr == 0) ) {
} else {
if( pnodeArray[i - numnodes].eptr != 0 ) {
if( pnodeArray[i - numnodes].eptr == j - numnodes ) {
continue ;
}
} else {
if( pnodeArray[j - numnodes].eptr == i - numnodes ) {
continue ;
}
}
}
if( nptr[j].distance < min ) {
min = nptr[j].distance ;
savei = i ;
}
}
}
pathLength = 0 ;
pathIndex = 0 ;
delSourceList[1] = savei ;
addTargetList[1] = savei ;
count = 0 ;
if( pnodeArray[ savei - numnodes ].eptr != 0 ) {
count = 1 ;
node = pnodeArray[ savei - numnodes ].eptr + numnodes ;
delSourceList[2] = node ;
addTargetList[2] = node ;
lptr = pnodeArray[ pnodeArray[ savei - numnodes ].eptr ].equiv ;
while( lptr != (LIST2PTR) NULL ) {
node = lptr->node + numnodes ;
if( node == savei ) {
lptr = lptr->next ;
continue ;
}
delSourceList[ ++count + 1 ] = node ;
addTargetList[ count + 1 ] = node ;
lptr = lptr->next ;
}
} else {
lptr = pnodeArray[ savei - numnodes ].equiv ;
while( lptr != (LIST2PTR) NULL ) {
node = lptr->node + numnodes ;
delSourceList[ ++count + 1 ] = node ;
addTargetList[ count + 1 ] = node ;
lptr = lptr->next ;
}
}
for( i = 1 ; i <= count + 1 ; i++ ) {
node = addTargetList[i] ;
gptr = gnodeArray[node] ;
for( ; gptr != (GNODEPTR) NULL ; gptr = gptr->next ) {
node1 = gptr->node ;
gptr1 = gnodeArray[node1] ;
for( ; ; ) {
if( gptr1->node == node ) {
gptr1->einactive = 1 ;
break ;
}
gptr1 = gptr1->next ;
}
}
}
recursePath( count + 1 , 0 , 0 , count + 1 ) ;
for( i = 1 ; i <= count + 1 ; i++ ) {
node = addTargetList[i] ;
gptr = gnodeArray[node] ;
for( ; gptr != (GNODEPTR) NULL ; gptr = gptr->next ) {
node1 = gptr->node ;
gptr1 = gnodeArray[node1] ;
for( ; ; ) {
if( gptr1->node == node ) {
gptr1->einactive = 0 ;
break ;
}
gptr1 = gptr1->next ;
}
}
}
if( indexRoot != (TNODEPTR) NULL ) {
for( ; ; ) {
tpop( &indexRoot , &tptr , &i , &j ) ;
if( tptr == (TNODEPTR) NULL ) {
break ;
}
}
}
if( bareflag == 1 ) {
bareMinimum = 0 ;
}
return ;
}
void recursePath( int dsptr , int atptr , int attachPt, int addEquivs )
{
int i , j , k , l , min , dnode , savei , node , node1 , node2 , t ;
int numberPaths , count , numadd ;
int numdelete , junk , c , value , index , found , savej ;
int extraS , numExtra , s , *extraSlist , x ;
short int *dslist , *atlist ;
int **tempPL , pathExists , targ , from ;
NNODEPTR nptr ;
TNODEPTR junkptr , extraRoot ;
GNODEPTR gptr , g1ptr , gptr1 , gptr2 ;
LIST2PTR lptr ;
#ifdef DEBUG1
printf("\n\nTarget List:\n");
for( i = 1 ; i <= targetPtr ; i++ ) {
printf(" %d ", targetList[i] ) ;
}
printf("\n");
printf("add to targets:\n");
for( i = 1 ; i <= atptr + addEquivs ; i++ ) {
printf(" %d ", addTargetList[i] ) ;
}
printf("\n");
fflush(stdout);
#endif
if( sourcePtr - dsptr == 0 ) {
tpop( &indexRoot , &junkptr , &pathIndex , &junk ) ;
savePaths[pathIndex][0] = segPtr ;
for( i = 1 ; i <= segPtr ; i++ ) {
savePaths[pathIndex][i] = segList[i] ;
}
#ifdef DEBUG1
printf("pathLength:%d pathIndex:%d\n", pathLength, pathIndex);
for( i = 1 ; i <= segPtr ; i++ ) {
printf(" %d ", savePaths[pathIndex][i] );
}
printf("\n");
fflush(stdout);
#endif
tinsert( &netRoot , pathLength , pathIndex ) ;
treeSize++ ;
return ;
}
extraRoot = (TNODEPTR) NULL ;
extraSlist = (int *) malloc( (1 + EXTRASOURCES) * sizeof(int) ) ;
tempPL = (int **) malloc((1 + EXTRASOURCES * MAXPATHS) * sizeof(int *));
for( i = 1 ; i <= EXTRASOURCES * MAXPATHS ; i++ ) {
tempPL[i] = (int *) malloc( 21 * sizeof(int));
for( j = 0 ; j <= 20 ; j++ ) {
tempPL[i][j] = 0 ;
}
}
dslist = (short int *) malloc( (1 + dsptr) * sizeof(short int) ) ;
for( i = 1 ; i <= dsptr ; i++ ) {
dslist[i] = delSourceList[i] ;
}
atlist = (short int *) malloc( (1 + atptr + addEquivs) *
sizeof(short int) ) ;
for( i = 1 ; i <= atptr + addEquivs ; i++ ) {
atlist[i] = addTargetList[i] ;
}
#ifdef DEBUG2
printf("Deleted Source Node List:\n");
for( i = 1 ; i <= dsptr ; i++ ) {
printf(" %d ", dslist[i] ) ;
}
printf("\nSource Node List (BEFORE):\n");
for( i = 1 ; i <= sourcePtr ; i++ ) {
printf(" %d ", sourceList[i] ) ;
}
fflush(stdout);
#endif
for( j = 1 ; j <= dsptr ; j++ ) {
dnode = dslist[j] ;
for( i = 1 ; i <= sourcePtr ; i++ ) {
if( sourceList[i] == dnode ) {
sourceList[i] = sourceList[sourcePtr--] ;
break ;
}
}
}
#ifdef DEBUG2
printf("\nSource Node List (AFTER):\n");
for( i = 1 ; i <= sourcePtr ; i++ ) {
printf(" %d ", sourceList[i] ) ;
}
fflush(stdout);
#endif
for( j = 1 ; j <= atptr + addEquivs ; j++ ) {
targetList[++targetPtr] = atlist[j] ;
}
if( attachPt > 0 ) {
for( j = 1 ; j <= atptr ; j++ ) {
node1 = atlist[j] ;
if( j == atptr ) {
node2 = attachPt ;
} else {
node2 = atlist[ j + 1 ] ;
}
gptr1 = gnodeArray[ node1 ] ;
gptr2 = gnodeArray[ node2 ] ;
gptr = gptr1 ;
while( gptr != (GNODEPTR) NULL ) {
if( gptr->node == node2 ) {
gptr->cost = VLARGE ;
break ;
}
gptr = gptr->next ;
}
gptr = gptr2 ;
while( gptr != (GNODEPTR) NULL ) {
if( gptr->node == node1 ) {
gptr->cost = VLARGE ;
break ;
}
gptr = gptr->next ;
}
}
}
/* ************************************************************** */
numExtra = 0 ;
numberPaths = 0 ;
for( extraS = 1 ; extraS <= EXTRASOURCES ; extraS++ ) {
if( extraS > 1 && bareMinimum ) {
break ;
}
min = VLARGE ;
found = 0 ;
for( i = 1 ; i <= sourcePtr ; i++ ) {
for( s = 1 ; s <= numExtra ; s++ ) {
if( extraSlist[s] == sourceList[i] ) {
break ;
}
}
if( s <= numExtra ) {
continue ;
}
found = 1 ;
node = sourceList[i] - numnodes ;
nptr = pnodeArray[node].nodeList ;
for( j = 1 ; j <= targetPtr ; j++ ) {
targ = targetList[j] ;
if( nptr[ targ ].distance < min ) {
from = nptr[targ].from ;
pathExists = 0 ;
g1ptr = gnodeArray[ targ ] ;
for( ; pathExists == 0 && g1ptr != (GNODEPTR) NULL ;
g1ptr = g1ptr->next ){
node = g1ptr->node ;
if( node != from ) {
continue ;
}
gptr = gnodeArray[node] ;
for( ; ; ) {
if( gptr->node == targ ) {
if( gptr->cost < VLARGE ) {
pathExists = 1 ;
}
break ;
}
gptr = gptr->next ;
}
}
if( pathExists ) {
min = nptr[ targ ].distance ;
savei = sourceList[i] ;
savej = j ;
}
}
}
}
if( found == 1 ) {
extraSlist[ ++numExtra ] = savei ;
#ifdef DEBUG2
printf("\nselected source node: %d\n", savei ) ;
fflush(stdout);
#endif
i = numberPaths ;
numberPaths += mshortest( savei , savej ) ;
for( i++, l = 1 ; i <= numberPaths ; i++, l++ ) {
if( pathList[l][0] + 1 > 20 ) {
free( (int *) tempPL[i] ) ;
tempPL[i] = (int *) malloc( (pathList[l][0] + 2) *
sizeof(int));
}
for( j = 0 ; j <= pathList[l][0] + 1 ; j++ ) {
tempPL[i][j] = pathList[l][j] ;
}
tinsert( &extraRoot , tempPL[i][j - 1] , i ) ;
}
}
}
/* ************************************************************** */
s = ( numberPaths >= Mpaths ) ? Mpaths : numberPaths ;
for( l = 1 ; l <= s ; l++ ) {
tpop( &extraRoot , &junkptr , &junk , &j ) ;
k = tempPL[j][0] ;
#ifdef DEBUG2
printf("Spill it: ");
for( i = 1 ; i < k ; i++ ) {
addTargetList[i] = tempPL[j][i] ;
printf(" %d ", tempPL[j][i] ) ;
}
printf("\n");
fflush(stdout);
#else
for( i = 1 ; i < k ; i++ ) {
addTargetList[i] = tempPL[j][i] ;
}
#endif
numdelete = 0 ;
numadd = k - 1 ;
for( i = 1 ; i < k ; i++ ) {
if( addTargetList[i] > numnodes ) {
delSourceList[ ++numdelete ] = addTargetList[i] ;
}
}
count = 0 ;
for( i = 1 ; i <= numdelete ; i++ ) {
savei = delSourceList[i] ;
if( pnodeArray[ savei - numnodes ].eptr != 0 ) {
node = pnodeArray[ savei - numnodes ].eptr + numnodes ;
for( t = 1 ; t <= numdelete + count ; t++ ) {
if( node == delSourceList[t] ) {
break ;
}
}
if( t > numdelete + count ) {
delSourceList[ numdelete + ++count ] = node ;
addTargetList[ numadd + count ] = node ;
}
lptr = pnodeArray[ pnodeArray[savei - numnodes].eptr ].equiv;
} else {
lptr = pnodeArray[savei - numnodes].equiv;
}
while( lptr != (LIST2PTR) NULL ) {
node = lptr->node + numnodes ;
for( t = 1 ; t <= numdelete + count ; t++ ) {
if( node == delSourceList[t] ) {
break ;
}
}
if( t > numdelete + count ) {
delSourceList[ numdelete + ++count ] = node ;
addTargetList[ numadd + count ] = node ;
}
lptr = lptr->next ;
}
}
pathLength += tempPL[j][k + 1] ;
numdelete += count ;
numadd += count ;
for( i = 1 ; i <= k ; i++ ) {
segList[ i + segPtr ] = tempPL[j][i] ;
}
segList[ i + segPtr ] = 0 ;
segPtr += k + 1 ;
for( x = numadd - count + 1 ; x <= numadd ; x++ ) {
node = addTargetList[x] ;
gptr = gnodeArray[node] ;
for( ; gptr != (GNODEPTR) NULL ; gptr = gptr->next ) {
node1 = gptr->node ;
gptr1 = gnodeArray[node1] ;
for( ; ; ) {
if( gptr1->node == node ) {
gptr1->einactive = 1 ;
break ;
}
gptr1 = gptr1->next ;
}
}
}
recursePath( numdelete , numadd - count , tempPL[j][k] , count ) ;
segPtr -= k + 1 ;
pathLength -= tempPL[j][k + 1] ;
for( x = numadd - count + 1 ; x <= numadd ; x++ ) {
node = addTargetList[x] ;
gptr = gnodeArray[node] ;
for( ; gptr != (GNODEPTR) NULL ; gptr = gptr->next ) {
node1 = gptr->node ;
gptr1 = gnodeArray[node1] ;
for( ; ; ) {
if( gptr1->node == node ) {
gptr1->einactive = 0 ;
break ;
}
gptr1 = gptr1->next ;
}
}
}
}
count = treeSize - MAXPATHS ;
if( count > 0 ) {
for( c = 1 ; c <= count ; c++ ) {
tmax( &netRoot , &junkptr , &value , &index ) ;
tdelete( &netRoot , value , index ) ;
tinsert( &indexRoot , index , 0 ) ;
}
treeSize -= count ;
}
if( extraRoot != (TNODEPTR) NULL ) {
for( ; ; ) {
tpop( &extraRoot , &junkptr , &junk, &j ) ;
if( junkptr == (TNODEPTR) NULL ) {
break ;
}
}
}
for( j = 1 ; j <= dsptr ; j++ ) {
sourceList[++sourcePtr] = dslist[j] ;
}
#ifdef DEBUG2
printf("\nSource Node List (AFTER End of Recurse):\n");
for( i = 1 ; i <= sourcePtr ; i++ ) {
printf(" %d ", sourceList[i] ) ;
}
printf("\n");
fflush(stdout);
#endif
targetPtr -= atptr + addEquivs ;
if( attachPt > 0 ) {
for( j = 1 ; j <= atptr ; j++ ) {
node1 = atlist[j] ;
if( j == atptr ) {
node2 = attachPt ;
} else {
node2 = atlist[ j + 1 ] ;
}
gptr1 = gnodeArray[ node1 ] ;
gptr2 = gnodeArray[ node2 ] ;
gptr = gptr1 ;
for( ; ; ) {
if( gptr->node == node2 ) {
gptr->cost = gptr->length ;
break ;
}
gptr = gptr->next ;
}
gptr = gptr2 ;
for( ; ; ) {
if( gptr->node == node1 ) {
gptr->cost = gptr->length ;
break ;
}
gptr = gptr->next ;
}
}
}
free( (short int *) atlist ) ;
free( (short int *) dslist ) ;
free( extraSlist ) ;
for( i = 1 ; i <= EXTRASOURCES * MAXPATHS ; i++ ) {
free( (int *) tempPL[i] ) ;
}
free( (int **) tempPL ) ;
return ;
}