number
C NUMBER SOURCE CHAT 05/01/13 02:03:05 5004
SUBROUTINE NUMBER(N,NC,SNODE,LSTNUM,E2,ADJ,XADJ,
$ S,
$ Q,P,
$ IMPR,IRET)
IMPLICIT INTEGER(I-N)
IMPLICIT REAL*8 (A-H,O-Z)
C***********************************************************************
C NOM : NUMBER
C DESCRIPTION : Number nodes in component of graph for small profile
C and rms wavefront
C
C LANGAGE : FORTRAN 77 (sauf E/S)
C
C AUTEUR : Scott Sloan
C
C BIBLIO : @Article{,
C author = {S. W. Sloan},
C title = {A Fortran Program for Profile and Wavefront Reduction},
C journal = {International Journal for Numerical Methods in Engineering},
C year = {1989},
C volume = {28},
C pages = {2651-2679}
C}
C
C***********************************************************************
C APPELE PAR : LABEL
C***********************************************************************
C ENTREES :
C N - Number of nodes in graph
C NC - Number of nodes in component of graph
C SNODE - Node at which numbering starts
C E2 - Twice the number of edges in the graph = XADJ(N+1)-1
C ADJ - Adjacency list for all nodes in graph
C - List of length 2E where E is the number of edges in
C the graph and 2E = XADJ(N+1)-1
C XADJ - Index vector for ADJ
C - Nodes adjacent to node I are found in ADJ(J), where
C J = XADJ(I),...,XADJ(I+1)-1
C - Degree of node I given by XADJ(I+1)-XADJ(I)
C Q - List of nodes which are in this component
C - Also used to store queue of active or preactive nodes
C ENTREES-SORTIES :
C (E) LSTNUM - Count of nodes which have already been numbered
C (S) LSTNUM - Count of numbered nodes (input value incremented by NC)
C (E) S - List giving the distance of each node in this
C component from the end node
C (S) S - List of new node numbers
C - New number for node I is S(I)
C TABLEAU DE TRAVAIL :
C P -
C
C NOTES :
C
C S also serves as a list giving the status of the nodes
C during the numbering process:
C S(I) gt 0 indicates node I is postactive
C S(I) = 0 indicates node I is active
C S(I) = -1 indicates node I is preactive
C S(I) = -2 indicates node I is inactive
C P is used to hold the priorities for each node
C
C CODE RETOUR (IRET) : = 0 si tout s'est bien passé
C***********************************************************************
C VERSION : v1, 05/11/99, version initiale
C HISTORIQUE : v1, 10/03/89, création
C HISTORIQUE :
C HISTORIQUE :
C***********************************************************************
C Prière de PRENDRE LE TEMPS de compléter les commentaires
C en cas de modification de ce sous-programme afin de faciliter
C la maintenance !
C***********************************************************************
-INC PPARAM
-INC CCOPTIO
INTEGER NC,LSTNUM,JSTRT,JSTOP,ISTRT,ISTOP,NBR,NABOR,I,J
INTEGER NEXT,ADDRES,NN,NODE,SNODE,MAXPRT,PRTY,N,W1,W2,E2
INTEGER Q(NC),XADJ(N+1),ADJ(E2),P(N),S(N)
INTEGER IMPR,IRET
*
PARAMETER(W1=1,
$ W2=2)
*
*
* Executable statements
*
IF (IMPR.GT.1) WRITE(IOIMP,*) 'Entrée dans number'
*
* Initialise priorities and status for each node in this component
* Initial priority = W1*DIST - W2*DEGREE where:
* W1 = a positive weight
* W2 = a positive weight
* DEGREE = initial current degree for node
* DIST = distance of node from end node
*
DO 10 I=1,NC
NODE=Q(I)
P(NODE)=W1*S(NODE)-W2*(XADJ(NODE+1)-XADJ(NODE)+1)
S(NODE)=-2
10 CONTINUE
*
* Insert starting node in queue and assign it a preactive status
* NN is the size of queue
*
NN=1
Q(NN)=SNODE
S(SNODE)=-1
*
* Loop while queue is not empty
*
30 CONTINUE
IF (NN.GT.0) THEN
*
* Scan queue for node with max priority
*
ADDRES=1
MAXPRT=P(Q(1))
DO 35 I=2,NN
PRTY=P(Q(I))
IF (PRTY.GT.MAXPRT) THEN
ADDRES=I
MAXPRT=PRTY
ENDIF
35 CONTINUE
*
* NEXT is the node to be numbered next
*
NEXT=Q(ADDRES)
*
* Delete node NEXT from queue
*
Q(ADDRES)=Q(NN)
NN=NN-1
ISTRT=XADJ(NEXT)
ISTOP=XADJ(NEXT+1)-1
IF (S(NEXT).EQ.-1) THEN
*
* Node NEXT is preactive, examine its neighbours
*
DO 50 I=ISTRT,ISTOP
*
* Decrease current degree of neighbour by -1
*
NBR=ADJ(I)
P(NBR)=P(NBR)+W2
*
* Add neighbour to queue if it is inactive
* assign it a preactive status
*
IF (S(NBR).EQ.-2) THEN
NN=NN+1
Q(NN)=NBR
S(NBR)=-1
ENDIF
50 CONTINUE
ENDIF
*
* Store new node number for node NEXT
* Status for node NEXT is now postactive
*
LSTNUM=LSTNUM+1
S(NEXT)=LSTNUM
*
* Search for preactive neighbours of node NEXT
*
DO 80 I=ISTRT,ISTOP
NBR=ADJ(I)
IF (S(NBR).EQ.-1) THEN
*
* Decrease current degree of preactive neighbour by -1
* assign neighbour an active status
*
P(NBR)=P(NBR)+W2
S(NBR)=0
*
* Loop over nodes adjacent to preactive neighbour
*
JSTRT=XADJ(NBR)
JSTOP=XADJ(NBR+1)-1
DO 60 J=JSTRT,JSTOP
NABOR=ADJ(J)
*
* Decrease current degree of adjacent node by -1
*
P(NABOR)=P(NABOR)+W2
IF (S(NABOR).EQ.-2) THEN
*
* Insert inactive node in queue with a preactive status
*
NN=NN+1
Q(NN)=NABOR
S(NABOR)=-1
ENDIF
60 CONTINUE
ENDIF
80 CONTINUE
GOTO 30
ENDIF
*
* Normal termination
*
IRET=0
RETURN
*
* Format handling
*
*
* Error handling
*
9999 CONTINUE
IRET=1
WRITE(IOIMP,*) 'An error was detected in subroutine number'
RETURN
*
* End of subroutine NUMBER
*
END
					© Cast3M 2003 - Tous droits réservés.
					Mentions légales