ordonn
C ORDONN SOURCE PV 22/04/22 21:15:10 11344 SUBROUTINE ORDONN ************************************************************************ * * O R D O N N * ----------- * * SOUS-PROGRAMME ASSOCIE A LA DIRECTIVE "ORDONNER" * * FONCTION: * --------- * * L'OPERATEUR ORDONNER RANGE LE CONTENU D'UN OBJET ORDONNABLE. * * * PHRASE D'APPEL (EN GIBIANE): * ---------------------------- * * Tri d'1 objet LISTENTI, LISTREEL ou LISTMOTS : * * OBJ2 = ORDO |('CROI')| ('ABSO') ('NOCA') ('UNIQ' (FLOT1)) OBJ1 ; * |('DECR')| * * ---------- * * Tri de 1 ou plusieurs objets LISTENTI, LISTREEL et/ou LISTMOTS : * * TAB2 = ORDO |('CROI')| ('ABSO') ('NOCA') TAB1 MOT1 ; * |('DECR')| * * RES1 (.. RESN) = ORDO |('CROI')| ('ABSO') ('NOCA') LIS1 (...LISN) ; * |('DECR')| * |('COUT' (|'HONG'|) LIS0)| * |'COMP'| * * ---------- * * Tri d'objets EVOLUTION : * EVOL2 = ORDO |('CROI')| ('ABSO') EVOL1 ; * |('DECR')| * * ---------- * * Tri d'objets MAILLAGE : * * MAIL2 = ORDO MAIL1 ; * * * SOUS-PROGRAMMES APPELES: * ------------------------ * * ORDON1, ORDON2, ORDON3 ,ORDON4 * * * HISTORIQUE: * ----------- * * PASCAL MANIGOT 19 MARS 1985 * * OPTION "ABSOLU" AJOUTEE LE 23 AVRIL 1985 (P. MANIGOT) * * JCARDO 11/09/2012 => ORDO PASSE DE DIRECTIVE A OPERATEUR * * JCARDO 15/12/2014 => ACCEPTE LES LISTMOTS, TRI NOMBRE QCQ OBJETS, * OPTIONS NOCA + FLOT1, MERGE SORT SI N>100 * * BP 24/06/2016 => AJOUT OPTION COUT POUR LE CALCUL DE LA PERMUTATION * ************************************************************************ * IMPLICIT INTEGER(I-N) IMPLICIT REAL*8(A-H,O-Z) -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMTABLE -INC SMLREEL -INC SMLENTI -INC SMLMOTS -INC SMEVOLL -INC SMELEME * PARAMETER (NBRTYP = 5) PARAMETER (NBMOTS = 6) PARAMETER (NBALGO = 2) * CHARACTER*4 LISMOT(NBMOTS),LISALG(NBALGO) CHARACTER*4 CHA4 * SEGMENT MPILO INTEGER ITYOBJ(NBOBJ) INTEGER IPROBJ(NBOBJ) ENDSEGMENT * LOGICAL CROISS,ABSOLU,STRICT,SENCAS,ZCOUT * & 'MAILLAGE'/ DATA LISMOT/'CROI','DECR','ABSO','UNIQ','NOCA','COUT'/ DATA LISALG/'HONG','COMP'/ * CHARACTER*26 MINU,MAJU DATA MINU/'abcdefghijklmnopqrstuvwxyz'/ DATA MAJU/'ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ * * * * +---------------------------------------------------------------+ * | | * | L E C T U R E D E S A R G U M E N T S | * | | * +---------------------------------------------------------------+ * CROISS = .TRUE. ABSOLU = .FALSE. STRICT = .FALSE. SENCAS = .TRUE. ZCOUT = .FALSE. ICRIT = 0 IALGO = 0 ICROI = 0 NBOBJ = 0 100 CONTINUE IF (IERR.NE.0) RETURN IF (IRETOU.EQ.0) GOTO 21 * ========================================================== * MOTS-CLES : 'CROI', 'DECR', 'ABSO', 'UNIQ', 'NOCA', 'COUT' * ========================================================== IF (MONTYP.EQ.'MOT') THEN IF (IERR.NE.0) RETURN * * => 'CROI' IF (NUMMOT.EQ.1) THEN ICROI = 1 CROISS = .TRUE. * * => 'DECR' ELSEIF (NUMMOT.EQ.2) THEN CROISS = .FALSE. * * => 'ABSO' ELSEIF (NUMMOT.EQ.3) THEN ABSOLU = .TRUE. * * => 'UNIQ' (FLOT1) ELSEIF (NUMMOT.EQ.4) THEN STRICT = .TRUE. MONTY2 = ' ' IF (IRETOU.EQ.0) GOTO 21 IF (IERR.NE.0) RETURN * * => 'NOCA' ELSEIF (NUMMOT.EQ.5) THEN SENCAS = .FALSE. * * => 'COUT' (ALGO) LISCOU ELSEIF (NUMMOT.EQ.6) THEN ZCOUT = .TRUE. * * Lecture eventuelle de l'algo : COMPLET, HONGROIS ... * * Lecture du LISTENTI ou LISTREEL des couts obligatoirement * juste apres le mot-cle 'COUT' IF (IRETOU.EQ.0.OR.(COUTYP.NE.'LISTENTI'.AND. & COUTYP.NE.'LISTREEL')) THEN * "On attend un des objets : %M1:8 %M9:16 ..." MOTERR(1:40)='LISTENTI LISTREEL' RETURN ENDIF IF (IERR.NE.0) RETURN ELSE * "Syntaxe incorrecte : on attend %m1:30" MOTERR(1:30)='CROI DECR ABSO UNIQ NOCA COUT' RETURN ENDIF * * * =================================== * LECTURE DU OU DES OBJETS A ORDONNER * =================================== * * ******************************** * Lecture d'un objet de type TABLE * ******************************** ELSEIF (MONTYP.EQ.'TABLE') THEN * IF (NBOBJ.NE.0) THEN * "On ne veut pas d'objet de type %m1:8" MOTERR(1:8)='TABLE ' RETURN ENDIF * * LECTURE DE LA TABLE * ------------------- IF (IERR.NE.0) RETURN * LECTURE DE L'INDICE DE LA LISTE A TRIER * --------------------------------------- MONTY2 = ' ' XINDIC = 0.D0 * "Il manque la donnee de l'indice de l'objet TABLE" IF (IERR .NE.0) RETURN IF (MONTY2.EQ.'FLOTTANT') THEN ELSE ENDIF * * BOUCLE SUR LES OBJETS DE LA TABLE * --------------------------------- SEGACT,MTABLE NBOBJ=MLOTAB IF (NBOBJ.EQ.0) THEN * "La table est vide" RETURN ENDIF SEGINI,MPILO IINCLE=0 DO I=1,MLOTAB * * STOCKAGE DU TYPE DE L'OBJET (SI VALIDE) DANS MPILO CHA8 = MTABTV(I) DO J=1,3 ITYOBJ(I)=J GOTO 14 ENDIF ENDDO * "On ne veut pas d'objet de type %m1:8" MOTERR(1:8)=CHA8 RETURN 14 CONTINUE * STOCKAGE DU POINTEUR DE L'OBJET DANS MPILO IPROBJ(I)=MTABIV(I) * * EST-CE LA LISTE A TRIER ? IF (MTABTI(I).EQ.MONTY2) THEN IF ((MONTY2.EQ.'FLOTTANT'.AND.RMTABI(I).EQ.XINDIC) & .OR.MTABII(I).EQ.IINDIC) THEN * IINCLE = rang de la liste principale dans MPILO * NUMLIS = type de la liste principale * IPLIST = pointeur vers la liste principale IINCLE = I NUMLIS = J IPLIST = IPROBJ(I) ENDIF ENDIF * ENDDO IF (IINCLE.EQ.0) THEN * "Erreur dans la recherche de l'indice d'une table" RETURN ENDIF * * ********************************************* * Autres objets : LISTxxxx, MAILLAGE, EVOLUTION * ********************************************* ELSE MTABLE=0 IINCLE=1 * * LECTURE DE L'OBJET PRINCIPAL * ---------------------------- IF (NBOBJ.EQ.0) THEN DO 10 NUMLIS=1,NBRTYP 10 CONTINUE * "On ne veut pas d'objet de type %m1:8" MOTERR(1:8)=MONTYP RETURN 11 CONTINUE IF (IERR.NE.0) RETURN NBOBJ=1 IF (NUMLIS.LE.3) THEN SEGINI,MPILO ITYOBJ(1)=NUMLIS IPROBJ(1)=IPLIST ENDIF ELSE IF (NUMLIS.GT.3) THEN * "On ne veut pas d'objet de type %m1:8" MOTERR(1:8)=MONTYP RETURN ENDIF ENDIF * * LECTURE D'EVENTUELS OBJETS A ORDONNER EN MEME TEMPS * --------------------------------------------------- IF (NUMLIS.LE.3) THEN 20 CONTINUE MONTY2 = ' ' IF (IERR.NE.0) RETURN IF (IRETOU.EQ.0) GOTO 21 IF (MONTY2.EQ.'MOT') GOTO 100 DO 110 NUMLI2=1,3 110 CONTINUE * "On ne veut pas d'objet de type %m1:8" MOTERR(1:8)=MONTY2 RETURN 111 CONTINUE IF (IERR.NE.0) RETURN NBOBJ = NBOBJ + 1 SEGADJ,MPILO ITYOBJ(NBOBJ) = NUMLI2 IPROBJ(NBOBJ) = IPOBJ GOTO 20 ENDIF * ENDIF * * LECTURE DE L'OBJET SUIVANT GOTO 100 21 CONTINUE * Dans le cas de l'option COUT, le tri porte sur la liste LISCOU et * non pas sur tous les objets stockes dans IPROBJ IF (ZCOUT) THEN NUMLI2 = NUMLIS IF (COUTYP.EQ.'LISTREEL') NUMLIS = -1 IF (COUTYP.EQ.'LISTENTI') NUMLIS = -2 IINCLE = 0 ENDIF * ERREUR : aucun objet a ordonner n'a ete fourni... IF (NBOBJ.EQ.0) THEN * "On attend un des objets : %M1:8 %M9:16 %M17:24 %M25:32 %M33:40" MOTERR(1:40)='LISTxxxxEVOLUTIOMAILLAGEou TABLE' RETURN ENDIF * VERIFICATION DES INCOMPATIBILITES ENTRE OPTIONS ET DONNEES * ********************************************************** IF (ICROI.EQ.1.AND.(NUMLIS.EQ.5.OR.ZCOUT)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'CROI' RETURN ENDIF IF (.NOT.CROISS.AND.(NUMLIS.EQ.5.OR.ZCOUT)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'DECR' RETURN ENDIF IF (ABSOLU.AND.(NUMLIS.EQ.3.OR.NUMLIS.EQ.5.OR.ZCOUT)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'ABSO' RETURN ENDIF IF (STRICT.AND.(NBOBJ.GT.1.OR.NUMLIS.LT.1.OR.NUMLIS.GT.3)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'UNIQ' RETURN ENDIF IF (.NOT.SENCAS.AND.(NUMLIS.NE.3.OR.ZCOUT)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'NOCA' RETURN ENDIF IF (ZCOUT.AND.(NUMLI2.LT.1.OR.NUMLI2.GT.3)) THEN * "Option %m1:8 incompatible avec les données" MOTERR(1:8) = 'COUT' RETURN ENDIF * * * * * +---------------------------------------------------------------+ * | | * | T R I D E S O B J E T S | * | | * +---------------------------------------------------------------+ * * * +-----------------------------------------------------+ * | O B J E T L I S T x x x x | * +-----------------------------------------------------+ * IF (NUMLIS.LE.3) THEN * TRI DU PREMIER OBJET ET MEMORISATION EVENTUELLE DE L'ORDRE... * ============================================================= * Objet LISTREEL * ************** IF (NUMLIS.EQ.1) THEN MLREE1 = IPLIST SEGINI,MLREEL=MLREE1 IPROBJ(IINCLE) = MLREEL IF (LLIST.EQ.0) THEN SEGDES,MLREEL GOTO 150 ENDIF * Creation du LISTREEL ordonne IF (NBOBJ.GT.1) THEN IORDRE=1 ELSE IORDRE=0 ENDIF * SEGDES,MLREEL * Memorisation de l'ordre MLENTI=IORDRE IF (NBOBJ.GT.1) SEGACT,MLENTI * * * Objet LISTENTI * ************** ELSEIF (NUMLIS.EQ.2) THEN MLENT1 = IPLIST SEGINI,MLENTI=MLENT1 IPROBJ(IINCLE) = MLENTI * LLIST = LECT(/1) IF (LLIST.EQ.0) THEN SEGDES,MLENTI GOTO 150 ENDIF * * Creation du LISTENTI ordonne IF (NBOBJ.GT.1) THEN IORDRE=1 ELSE IORDRE=0 ENDIF * SEGDES,MLENTI * Memorisation de l'ordre MLENTI=IORDRE IF (NBOBJ.GT.1) SEGACT,MLENTI * * * Objet LISTMOTS * ************** ELSEIF (NUMLIS.EQ.3) THEN MLMOT1 = IPLIST SEGACT,MLMOT1 LLIST=JGM SEGINI,MLMOTS IPROBJ(IINCLE)=MLMOTS IF (LLIST.EQ.0) THEN SEGDES,MLMOTS,MLMOT1 GOTO 150 ENDIF * Creation d'un hash entier pour chaque mot * en prevision du tri JG=JGM SEGINI,MLENT1 DO I=1,JGM IF (.NOT.SENCAS) THEN DO J=1,JGN K=INDEX(MINU,CHA4(J:J)) IF (K.NE.0) CHA4(J:J)=MAJU(K:K) ENDDO ENDIF I1=ICHAR(CHA4(1:1))*16777216 I3=ICHAR(CHA4(3:3))*256 I4=ICHAR(CHA4(4:4)) ENDDO * On ordonne les hashes IORDRE=1 IF (.NOT.STRICT) SEGSUP,MLENT1 * Creation du LISTMOTS ordonne MLENTI=IORDRE SEGACT,MLENTI DO I=1,JGM ENDDO IF (.NOT.STRICT) SEGDES,MLMOTS SEGDES,MLMOT1 * ...OU BIEN TRI SELON UN COUT ET MEMORISATION DE L'ORDRE * ======================================================= * Objet LISTREEL * ************** ELSEIF(NUMLIS.EQ.-1) THEN * Recuperation et traitement de la matrice des couts MLREEL=ICOUT SEGACT,MLREEL * On verifie que NN2 est bien un carre X1=SQRT(DBLE(NN2)) LLIST=NINT(X1) IF (ABS(X1-DBLE(LLIST)).GT.XSZPRE) THEN SEGDES,MLREEL RETURN ENDIF * On transpose JG=NN2 SEGINI,MLREE1 SEGDES,MLREEL ICOUT=MLREE1 * Creation du LISTENTI definissant la permutation JG=LLIST SEGINI,MLENTI IORDRE=MLENTI * On fait le travail * On recupere la permutation MLREEL=ICOUT SEGSUP,MLREEL MLENTI=IORDRE * Objet LISTENTI * ************** ELSEIF(NUMLIS.EQ.-2) THEN * Recuperation et traitement de la matrice des couts MLENTI=ICOUT SEGACT,MLENTI NN2=MLENTI.LECT(/1) * On verifie que NN2 est bien un carre X1=SQRT(DBLE(NN2)) LLIST=NINT(X1) IF(ABS(X1-DBLE(LLIST)).GT.XSZPRE) THEN SEGDES,MLENTI RETURN ENDIF * On transpose JG=NN2 SEGINI,MLENT1 SEGDES,MLENTI ICOUT=MLENT1 * Creation du LISTENTI definissant la permutation JG=LLIST SEGINI,MLENTI IORDRE=MLENTI * On fait le travail * On recupere la permutation MLENTI=ICOUT SEGSUP,MLENTI MLENTI=IORDRE ELSE RETURN ENDIF * * * EVENTUELLEMENT : TRI DES AUTRES OBJETS SUIVANT LE MEME ORDRE * ============================================================ 150 CONTINUE DO 30 I=1,NBOBJ IF (I.EQ.IINCLE) GOTO 30 * Objet LISTREEL * ************** IF (ITYOBJ(I).EQ.1) THEN MLREE1 = IPROBJ(I) SEGACT,MLREE1 IF (JG.NE.LLIST) THEN GOTO 900 ENDIF SEGINI,MLREE2 IF (LLIST.GT.0) THEN DO J=1,LLIST ENDDO ENDIF IPROBJ(I)=MLREE2 SEGDES,MLREE1,MLREE2 * Objet LISTENTI * ************** ELSEIF (ITYOBJ(I).EQ.2) THEN MLENT1 = IPROBJ(I) SEGACT,MLENT1 JG=MLENT1.LECT(/1) IF (JG.NE.LLIST) THEN GOTO 900 ENDIF SEGINI,MLENT2 IF (LLIST.GT.0) THEN DO J=1,LLIST MLENT2.LECT(J) = MLENT1.LECT(LECT(J)) ENDDO ENDIF IPROBJ(I)=MLENT2 SEGDES,MLENT1,MLENT2 * Objet LISTMOTS * ************** ELSEIF (ITYOBJ(I).EQ.3) THEN MLMOT1 = IPROBJ(I) SEGACT,MLMOT1 IF (JGM.NE.LLIST) THEN GOTO 900 ENDIF SEGINI,MLMOT2 IF (LLIST.GT.0) THEN DO J=1,LLIST ENDDO ENDIF IPROBJ(I)=MLMOT2 SEGDES,MLMOT1,MLMOT2 ENDIF 30 CONTINUE IF (LLIST.GT.0) SEGSUP,MLENTI * * * EVENTUELLEMENT : SUPPRESSION DES DOUBLONS * ========================================= IF (STRICT.AND.LLIST.GT.1) THEN * Objet LISTREEL * ************** IF (NUMLIS.EQ.1) THEN MLREEL = IPROBJ(1) SEGACT,MLREEL*MOD NDOUB=0 IF (ICRIT.NE.0) THEN DO I=2,LLIST ELSE NDOUB=NDOUB+1 ENDIF ENDDO ELSE DO I=2,LLIST ELSE NDOUB=NDOUB+1 ENDIF ENDDO ENDIF JG = LLIST-NDOUB SEGADJ,MLREEL SEGDES,MLREEL * Objet LISTENTI * ************** ELSEIF (NUMLIS.EQ.2) THEN MLENTI = IPROBJ(1) SEGACT,MLENTI*MOD NDOUB=0 DO I=2,LLIST IF (LECT(I-1).NE.LECT(I)) THEN IF (NDOUB.GT.0) LECT(I-NDOUB)=LECT(I) ELSE NDOUB=NDOUB+1 ENDIF ENDDO JG = LLIST-NDOUB SEGADJ,MLENTI SEGDES,MLENTI * Objet LISTMOTS * ************** ELSEIF (NUMLIS.EQ.3) THEN SEGACT,MLMOTS*MOD SEGACT,MLENT1 NDOUB=0 DO I=2,LLIST IF (MLENT1.LECT(I-1).NE.MLENT1.LECT(I)) THEN ELSE NDOUB=NDOUB+1 ENDIF ENDDO SEGSUP,MLENT1 JGM = LLIST-NDOUB SEGADJ,MLMOTS SEGDES,MLMOTS ENDIF ENDIF * * * ECRITURE DES OBJETS ORDONNES DANS LE BON ORDRE * ============================================== IF (MTABLE.GT.0) THEN M = NBOBJ SEGINI,MTAB1 MTAB1.MLOTAB=M DO I=1,NBOBJ IF (MTABTI(I).EQ.'FLOTTANT') THEN MTAB1.MTABTI(I)='FLOTTANT' MTAB1.RMTABI(I)=RMTABI(I) ELSE MTAB1.MTABTI(I)=MTABTI(I) MTAB1.MTABII(I)=MTABII(I) ENDIF MTAB1.MTABIV(I)=IPROBJ(I) ENDDO SEGDES,MTABLE,MTAB1 ELSE DO I=NBOBJ,1,-1 IPOBJ = IPROBJ(I) ENDDO ENDIF IF (ZCOUT) THEN ENDIF 900 CONTINUE SEGSUP,MPILO * * +-----------------------------------------------------+ * | O B J E T E V O L U T I O N | * +-----------------------------------------------------+ * ELSEIF (NUMLIS.EQ.4) THEN MEVOL1 = IPLIST SEGINI,MEVOLL=MEVOL1 IPLIST = MEVOLL * * * * +-----------------------------------------------------+ * | O B J E T M A I L L A G E | * +-----------------------------------------------------+ * ELSEIF (NUMLIS.EQ.5) THEN IPT2 = IPLIST SEGINI,IPT1=IPT2 IPLIST = IPT1 * * ENDIF RETURN END
© Cast3M 2003 - Tous droits réservés.
Mentions légales