Helló, világ!
C -------------------------
C PROGRAM HELLO.F
C -------------------------
C A KIIRAS FORMATUMA EGY HOLLERITH-KONSTANS:
C AZ 5 KARAKTER HOSSZU HELLO SZOVEG
10 FORMAT (5HHELLO)
C KIIRJUK A FORMATUMOT ADAT NELKUL :)
C (NINCS STRINGKEZELES!)
WRITE(*, 10)
STOP
END
Szorzás, osztás
C -------------------------
C PROGRAM MUL.F
C -------------------------
C NEGY INTEGER TIPUSU VALTOZO DEKLARACIOJA
INTEGER M, N, RES1, RES2
C A KIIRASHOZ HASZNALT FORMATUM 4 HOSSZU
C HOLLERITH-KONSTANS AZ M = SZOVEGGEL
10 FORMAT(4HM = )
11 FORMAT(4HN = )
C A KIIRASHOZ HASZNALT FORMATUM:
C CSAK EGY HAROMJEGYU EGESZT IRUNK KI
20 FORMAT(I3)
C A KIIRASHOZ HASZNALT FORMATUM:
C 6 HOSSZU HOLLERITH-KONSTANS UTAN KIIRUNK
C EGY NYOLC HOSSZU EGESZT
30 FORMAT(6HMUL = , I8)
31 FORMAT(6HSUM = , I8)
40 FORMAT(14HWRONG NUMBERS!)
C
1 WRITE(*, 10)
READ(*, 20) M
WRITE(*, 11)
READ(*, 20) N
IF (M.LT.N) GOTO 2
WRITE(*, 40)
GOTO 1
C MEGHIVJUK A MUL ALPROGRAMOT
C (EGESZ INTERVALLUM SZORZASA)
2 CALL MUL(M, N, RES1)
C MEGHIVJUK A SUMM FUGGVENYT
C (EGESZ INGERVALLUM OSSZEGE)
RES2 = SUMM(M, N)
WRITE(*, 30) RES1
WRITE(*, 31) RES2
C A PROGRAM VEGET ER
STOP
END
C
C -------------------------
INTEGER FUNCTION SUMM(MM, MN)
C -------------------------
INTEGER MM, MN
C
SUM = 0
DO 99 I = MM, MN
SUM = SUM + I
99 CONTINUE
C A FUGGVENY VISSZATER
RETURN
END
C
C -------------------------
SUBROUTINE MUL(MM, MN, MRES)
C -------------------------
INTEGER MM, MN, MRES
C
MRES = 1
DO 99 I = MM, MN
MRES = MRES * I
99 CONTINUE
C AZ ALPROGRAM VISSZATER
RETURN
END
LNKO
C -------------------------
C PROGRAM GCD.F
C -------------------------
PROGRAM GCD
C EGYSZERUBB I/O
PRINT *, 'A?'
READ *, NA
IF (NA.LE.0) THEN
PRINT *, 'A LEGYEN POZITIV EGESZ!'
STOP
END IF
PRINT *, 'B?'
READ *, NB
IF (NB.LE.0) THEN
PRINT *, 'B LEGYEN POZITIV EGESZ!'
STOP
END IF
PRINT *, NA, ' ES ', NB, ' LNKO-JA: ', LNKO(NA, NB), '.'
STOP
END
FUNCTION LNKO(NA, NB)
IA = NA
IB = NB
1 IF (IB.NE.0) THEN
ITEMP = IA
IA = IB
IB = MOD(ITEMP, IB)
GOTO 1
END IF
NGCD = IA
RETURN
END
Vektor
C -------------------------
C PROGRAM VEKTOR.F
C FORTRAN 90
C -------------------------
INTEGER I, N, MAXDIM
PARAMETER (MAXDIM = 1000)
REAL*4 V(MAXDIM)
REAL*4 OSSZEG, MAX, MIN, VEKTORNORMA
REAL*4 SUM1, MAXVAL1, MINVAL1, NORMA
C A FORMAT-BAN KELL MEGADNI A BEOLVASANDÓ /
C KIÍRANDÓ ELEMEK FORMÁTUMÁT
C AZ 1X AZT JELENTI, HOGY AZ ELEMEK KÖZÉ
C NE TEGYEN SZÓKÖZT (2X EGY SZÓKÖZ STB.)
10 WRITE(*,20) 'HANY DIMENZIOS LEGYEN A VEKTOR (MAX. ',MAXDIM,'): '
20 FORMAT(1X,A,I4,A,$)
READ(*,*) N
IF ((N .GT. MAXDIM) .OR. (N .LT. 1)) GO TO 10
C CIKLUS GO TO-VAL
I = 1
30 WRITE(*,40) I,'. KOORDINATA: '
40 FORMAT(1X,I4,A,$)
READ(*,50) V(I)
50 FORMAT(F7.2)
I = I + 1
IF (I .LE. N) GO TO 30
OSSZEG = SUM1(V, N)
MAX = MAXVAL1(V, N)
MIN = MINVAL1(V, N)
C A FENTI HÁROM FÜGGVÉNY SUM, MAXVAL,
C MINVAL A FOTRAN90-BEN MÁR MEGTALÁLHATÓK,
C (EKVIVALENSEK AZ ALÁBB MEGTALÁLHATÓ
C IMPLEMENTÁCIÓKKAL)
C A FORDÍTÓ AZONBAN MÁR ITT IS FOGLALT
C SZÓNKÉNT KEZELI, NEM LEHET HASZNÁLNI
VEKTOR NORMA = NORMA(V, N)
C A VEKTORNORMA ÉS VEKTOR NORMA EKVIVALENSEK,
C MIVEL A FORDÍTÓ ELTÁVOLT MINDEN SZÓKÖZT
WRITE(*,60) 'KOORDINATAOSSZEG:',OSSZEG
WRITE(*,60) 'MAXIMALIS KOORDINATA:',MAX
WRITE(*,60) 'MINIMALIS KOORDINATA:',MIN
WRITE(*,60) 'VEKTORNORMA:',VEKTORNORMA
60 FORMAT(2X,A,F7.2)
C UGYANAZT A FORMÁTUMOT TERMÉSZETESEN TÖBB
C KIÍRÁS IS HASZNÁLHATJA
STOP
END
C KOORDINÁTAÖSSZEG-(SUM1)
C ILYEN RONDA KÓD IS ÍRHATÓ, MIVEL A FORDÍTÓ
C AZZAL KEZD, HOGY KISZED MINDEN SZÓKÖZT
C AZ ALÁBBI KÓDRÉSZLET AZ ALATTA KOMMENTBEN
C TALÁLHATÓ "SZÉP" KÓDDAL EKVIVALENS.
REAL*4FUNCTIONSUM1(VEKT, DIM)
IMPLICITNONE;INTEGERI,DIM;REAL*4OSSZEG,VEKT(DIM)
C REAL*4 FUNCTION SUM1(VEKT, DIM)
C IMPLICIT NONE
C INTEGER I, DIM
C REAL*4 OSSZEG, VEKT(DIM)
OSSZEG = 0
C EZ A DO MÁR A FORTRAN90-BOL ÚJÍTÁS, NINCS
C LEZÁRÓ END DO
DO 10 I = 1, DIM
10 OSSZEG = OSSZEG + VEKT(I)
SUM1 = OSSZEG
RETURN
END
C MAXIMÁLIS-KOORDINÁTA
REAL*4 FUNCTION MAXVAL1(VEKT, DIM)
IMPLICIT NONE
INTEGER I, DIM
REAL*4 MAX ,VEKT(DIM)
MAX = -9999.99
C MIVEL A KOORDINÁTÁK F7.2 ALAKÚAK
C (-9999.99 ... 9999.99)
DO 10 I = 1, DIM
10 IF (VEKT(I) .GT. MAX) MAX = VEKT(I)
MAXVAL1 = MAX
RETURN
END
C MINIMÁLIS-KOORDINÁTA
REAL*4 FUNCTION MINVAL1(VEKT, DIM)
IMPLICIT NONE
INTEGER I, DIM
REAL*4 MIN ,VEKT(DIM)
MIN = 9999.99
DO 10 I = 1, DIM
10 IF (VEKT(I) .LT. MIN) MIN = VEKT(I)
MINVAL1 = MIN
RETURN
END
C A-VEKTOR-NORMÁJA
REAL*4 FUNCTION NORMA(VEKT, DIM)
IMPLICIT NONE
INTEGER I, DIM
REAL*4 OSSZEG ,VEKT(DIM)
OSSZEG = 0
DO 10 I = 1, DIM
10 OSSZEG = OSSZEG + VEKT(I)*VEKT(I)
OSSZEG = SQRT(OSSZEG)
NORMA = OSSZEG
RETURN
END
Háromszög területe
C -------------------------
C PROGRAM TRIANGLE2.F
C -------------------------
C HAROMSZOG TERULETE HERON KEPLETTEL
501 FORMAT(I5,I5,I5)
601 FORMAT(4H A= ,I5,4H B= ,I5,4H C= ,I5,4H T= ,F10.2)
602 FORMAT(4HVEGE)
603 FORMAT(10HINPUT HIBA)
INTEGER A,B,C
10 READ(*,501,END=50,ERR=90) A,B,C
IF(A.EQ.0 .OR. B.EQ.0 .OR. C.EQ.0) GO TO 90
S = (A + B + C) / 2.0
AREA = SQRT( S * (S - A) * (S - B) * (S - C))
WRITE(*,601) A,B,C,AREA
GO TO 10
50 WRITE(*,602)
STOP
90 WRITE(*,603)
STOP
END
Kupacrendezés
C -------------------------
C PROGRAM RENDEZES.F
C -------------------------
C RENDEZENDO TÖMB EGÉSZEKKEL FELTÖLTVE
INTEGER I(9)
DATA I/12,23,11,8,45,2,56,17,6/
CALL RENDEZ(9,I)
END
C RENDEZO SZUBRUTIN
C X TÖMB, N AZ ELEMSZÁMA, HEAP: A KUPAC TÖMBJE
SUBROUTINE RENDEZ (N, X)
INTEGER N, J
INTEGER X(*)
INTEGER HEAP(N)
CALL KIIR(N,X)
C HEAP KIALAKITASA
DO 21 I=1, N
HEAP(I)=X(I)
CALL INSHEAP(I,HEAP)
21 CONTINUE
CALL KIIR(N,HEAP)
C HEAP SORT
C A HEAP ELSO ELEME A MAXIMUM, KIVESSZÜK, ÉS A JOBB-ALSÓ ELEMET
C AZ ELSO HELYRE RAKJUK, MAJD SULLYESZTJÜK
DO 22 I=1, N
X(I)=HEAP(1)
HEAP(1)=HEAP(N-I+1)
HEAP(N-I+1)=0
CALL SULYESZT(N,HEAP)
CALL KIIR(N,HEAP)
22 CONTINUE
CALL KIIR(N,X)
END
C a CSÚCSON LÉVO ELEMET HELYÉRE SÜLLYESZTO SZUBRUTIN
SUBROUTINE SULYESZT(N, X)
INTEGER N, I, J, SWAP
INTEGER X(*)
C AZ I=1 HELYROL INDITJUK A SÜLLYESZTÉST
I=1
C HA 2 GYEREKE VAN AZ ADOTT CSÚCSNAK
51 IF ((I*2+1).LE.N) THEN
C HA VAN NAGYOBB GYEREKE AKKOR A NAGYOBBIKKAL CSERELUNK
C MAJD FOLYTATJUK A SULLYESZTEST
IF (( X(2*I).GT.X(I) ).OR.( X(2*I+1).GT.X(I) )) THEN
IF (X(2*I).GT.X(2*I+1)) THEN
J=2*I
ELSE
J=2*I+1
ENDIF
SWAP=X(I)
X(I)=X(J)
X(J)=SWAP
I=J
ELSE
RETURN
ENDIF
C HA 1 GYEREKE VAN AZ ADOTT CSÚCSNAK ÉS AZ NAGYOBB
C AKKOR CSERÉLÜNK ÉS FOLYTATJUK A SÜLLYESZTÉST
ELSEIF (((I*2).EQ.N).AND.(X(I*2).GT.X(I))) THEN
SWAP=X(I*2)
X(I*2)=X(I)
X(I)=SWAP
I=I*2
ELSE
RETURN
ENDIF
GOTO 51
END
C HEAP-BE ÚJ ELEMET HELYEZO ELJÁRÁS
C A HEAP VÉGÉROL INDITJUK AZ ÚJ ELEMET
C MAJD ADDIG VISSZIK FÖLFELÉ AMIG A HELYÉRE NEM KERÜL
SUBROUTINE INSHEAP(M, X)
INTEGER N, M, SWAP
INTEGER X(*)
N=M
41 IF (N.EQ.1) RETURN
IF (X(N).GT.X(N/2)) THEN
SWAP=X(N/2)
X(N/2)=X(N)
X(N)=SWAP
N=N/2
GOTO 41
ENDIF
RETURN
END
SUBROUTINE KIIR (N, X)
INTEGER N
INTEGER X(*)
31 FORMAT (I5)
32 FORMAT (4HVEGE)
DO 30 I=1, N
WRITE (*, 31) X(I)
30 CONTINUE
WRITE (*,32)
RETURN
END
Dijkstra algoritmus
C --------------
C PROGRAM DIJK.F
C --------------
C A DEKLARALT VALTOZOKAT
INTEGER DIST, PAR
C KOZOSSE TESSZUK, ES TOMBNEK DIMENZIONALJUK
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER STACK, SSIZE
COMMON /STACK/ STACK(100), SSIZE
C
INTEGER Y, T, S
INTEGER I, J
C I/O FORMATUMOK
10 FORMAT(5HPATH:)
20 FORMAT(19HMINIMAL DISTANCE = , I3)
30 FORMAT(4HS = )
40 FORMAT(4HT = )
50 FORMAT(1H>, I1)
60 FORMAT(1H )
70 FORMAT(I1)
C
WRITE(*, 30)
READ(*, 70) S
WRITE(*, 40)
READ(*, 70) T
C ELJARASHIVAS
CALL DIJKSTRA(S)
C
WRITE(*, 60)
WRITE(*, 20) DIST(T)
WRITE(*, 60)
WRITE(*, 10)
I = T
1 IF (I.EQ.0) GOTO 2
CALL PUSH(I)
I = PAR(I)
GOTO 1
2 IF (SSIZE.EQ.0) GOTO 3
CALL POP(J)
WRITE(*, 50) J
GOTO 2
C
3 STOP
END
C
C ----------------------
SUBROUTINE DIJKSTRA(X)
C ----------------------
INTEGER X
INTEGER S, U, V, E
INTEGER I
C
INTEGER DIST, PAR
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER NHOOD, EDGES
COMMON /GRAPH/ NHOOD(100,100), EDGES(100, 100)
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
C
S = X
C
CALL PUT(S,0)
1 IF(HSIZE.EQ.0) RETURN
CALL DELMIN(U)
I = 1
2 V = NHOOD(U,I)
E = EDGES(U,I)
IF (V.EQ.0) GOTO 1
IF (INDEX(V).EQ.-2) GOTO 6
IF (INDEX(V).EQ.-1) GOTO 3
GOTO 4
3 CALL PUT(V, DIST(U)+E)
PAR(V) = U
GOTO 6
4 IF(DIST(V).GT.DIST(U)+E) GOTO 5
GOTO 6
5 CALL KEYDEC(V, DIST(U)+E)
PAR(V) = U
6 I = I + 1
GOTO 2
C VISSZATERES ALPROGRAMBOL
RETURN
END
C
C -------------------
SUBROUTINE PUT(X,Y)
C -------------------
INTEGER X, Y
INTEGER PARENT
C
INTEGER DIST, PAR
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
C
IF (INDEX(X).NE.-1) RETURN
C
HSIZE = HSIZE + 1
DIST(X) = Y
HEAP(HSIZE) = X
INDEX(X) = HSIZE
C
1 PARENT = INDEX(X)/2
IF (PARENT.EQ.0) RETURN
IF (DIST(HEAP(PARENT)).LE.DIST(X)) RETURN
CALL CHANGE(INDEX(X), PARENT)
GOTO 1
C
RETURN
END
C
C --------------------
SUBROUTINE DELMIN(X)
C --------------------
INTEGER X, PARENT, CHILD
C
INTEGER DIST, PAR
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
C
IF (HSIZE.GT.0) GOTO 1
X = -1
RETURN
C
1 X = HEAP(1)
INDEX(HEAP(1)) = -2
HSIZE = HSIZE - 1
IF (HSIZE.EQ.0) RETURN
HEAP(1) = HEAP(HSIZE+1)
C
PARENT = 1
2 IF ((2*PARENT).GT.HSIZE) RETURN
CHILD = 2*PARENT
IF ((2*PARENT).LT.HSIZE) GOTO 3
GOTO 4
3 IF (DIST(HEAP(2*PARENT)).GT.DIST(HEAP(2*PARENT+1)))
- CHILD = 2*PARENT+1
4 IF (DIST(HEAP(CHILD)).GE.DIST(HEAP(PARENT))) RETURN
CALL CHANGE(CHILD, PARENT)
PARENT = CHILD
GOTO 2
C
RETURN
END
C
C ----------------------
SUBROUTINE KEYDEC(X,Y)
C ----------------------
INTEGER X, Y, PARENT
C
INTEGER DIST, PAR
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
C
IF (INDEX(X).LT.1) RETURN
IF (Y.GE.DIST(X)) RETURN
C
DIST(X) = Y
IF (INDEX(X).EQ.1) RETURN
1 PARENT = INDEX(X)/2
IF (DIST(HEAP(PARENT)).LE.DIST(X)) RETURN
CALL CHANGE(INDEX(X), PARENT)
GOTO 1
C
RETURN
END
C
C ----------------------
SUBROUTINE CHANGE(X,Y)
C ----------------------
INTEGER X, Y
INTEGER X2, Y2, TMP
C
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
C
IF (X.LT.1.OR.Y.LT.1.OR.X.GT.HSIZE.OR.Y.GT.HSIZE.OR.X.EQ.Y)
- RETURN
C
X2 = X
Y2 = Y
TMP = HEAP(X2)
INDEX(HEAP(X2)) = Y2
INDEX(HEAP(Y2)) = X2
HEAP(X2) = HEAP(Y2)
HEAP(Y2) = TMP
C
RETURN
END
C
C ------------------
SUBROUTINE PUSH(X)
C ------------------
INTEGER X
C
INTEGER STACK, SSIZE
COMMON /STACK/ STACK(100), SSIZE
C
IF (SSIZE.EQ.100) RETURN
C
SSIZE = SSIZE + 1
STACK(SSIZE) = X
C
RETURN
END
C
C -----------------
SUBROUTINE POP(X)
C -----------------
INTEGER X
C
INTEGER STACK, SSIZE
COMMON /STACK/ STACK(100), SSIZE
C
IF (SSIZE.EQ.0) RETURN
C
X = STACK(SSIZE)
SSIZE = SSIZE - 1
C
RETURN
END
C
C ----------
BLOCK DATA
C ----------
INTEGER DIST, PAR
COMMON /PUBLIC/ DIST(100), PAR(100)
INTEGER NHOOD, EDGES
COMMON /GRAPH/ NHOOD(100,100), EDGES(100, 100)
INTEGER INDEX, HEAP, HSIZE
COMMON /HEAP/ INDEX(100), HEAP(100), HSIZE
INTEGER STACK, SSIZE
COMMON /STACK/ STACK(100), SSIZE
C
DATA SSIZE /0/
DATA HSIZE /0/
C
DATA INDEX(1) /-1/
DATA INDEX(2) /-1/
DATA INDEX(3) /-1/
DATA INDEX(4) /-1/
DATA INDEX(5) /-1/
DATA INDEX(6) /-1/
DATA INDEX(7) /-1/
C
DATA PAR(1) /0/
DATA PAR(2) /0/
DATA PAR(3) /0/
DATA PAR(4) /0/
DATA PAR(5) /0/
DATA PAR(6) /0/
DATA PAR(7) /0/
C
DATA NHOOD(1,1) /2/
DATA NHOOD(1,2) /3/
DATA NHOOD(1,3) /7/
DATA NHOOD(1,4) /0/
C
DATA NHOOD(2,1) /1/
DATA NHOOD(2,2) /3/
DATA NHOOD(2,3) /0/
C
DATA NHOOD(3,1) /1/
DATA NHOOD(3,2) /2/
DATA NHOOD(3,3) /4/
DATA NHOOD(3,4) /7/
DATA NHOOD(3,5) /0/
C
DATA NHOOD(4,1) /3/
DATA NHOOD(4,2) /5/
DATA NHOOD(4,3) /0/
C
DATA NHOOD(5,1) /4/
DATA NHOOD(5,2) /6/
DATA NHOOD(5,3) /7/
DATA NHOOD(5,4) /0/
C
DATA NHOOD(6,1) /5/
DATA NHOOD(6,2) /7/
DATA NHOOD(6,3) /0/
C
DATA NHOOD(7,1) /1/
DATA NHOOD(7,2) /3/
DATA NHOOD(7,3) /5/
DATA NHOOD(7,4) /6/
DATA NHOOD(7,5) /0/
C
DATA EDGES(1,1) /3/
DATA EDGES(1,2) /4/
DATA EDGES(1,3) /1/
C
DATA EDGES(2,1) /3/
DATA EDGES(2,2) /2/
C
DATA EDGES(3,1) /4/
DATA EDGES(3,2) /2/
DATA EDGES(3,3) /2/
DATA EDGES(3,4) /2/
C
DATA EDGES(4,1) /2/
DATA EDGES(4,2) /5/
C
DATA EDGES(5,1) /5/
DATA EDGES(5,2) /1/
DATA EDGES(5,3) /4/
C
DATA EDGES(6,1) /1/
DATA EDGES(6,2) /2/
C
DATA EDGES(7,1) /1/
DATA EDGES(7,2) /2/
DATA EDGES(7,3) /4/
DATA EDGES(7,4) /2/
C
END
A K-means algoritmus
C 2009. PETER CSIZSEK. PROGRAMMING LANGUAGES 4. SEMINAR.
C ===================================================
C THIS PROGRAM IS A DEMONSTRATION OF THE K-MEANS CLUSTERING ALGORITHM.
PROGRAM K_MEANS
C VARIABLE DECLARATIONS.
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
INTEGER OWNERS(1:10000)
INTEGER N, K, M
CHARACTER * (80) FILENAME
INTEGER IARGC
INTEGER NARGS
CHARACTER * (80) OPT
C THE COMMONLY-USED DATA AMONG THE SUBPROGRAMS.
COMMON /DAT/ CENTERS, POINTS
COMMON /OWN/ OWNERS
COMMON /PAR/ N, K, M
COMMON /FNAME/ FILENAME
C SET PARAMETERS.
N = 5
K = 20
M = 200
C CHECK THE NUMBER OF THE COMMAND-LINE ARGUMENTS.
WRITE(*, 9010) 'CHECKING COMMAND-LINE ARGUMENTS.'
NARGS = IARGC()
IF(NARGS .NE. 2) THEN
WRITE(*, 9010) 'ERROR:'
WRITE(*, 9010) 'THE PROGRAM HAS TO BE CALLED WITH EXACTLY TWO COMM
/AND-LINE ARGUMENTS:'
WRITE(*, 9010) '- THE OPTION (''GEN'' = GENERATE RANDOM DATA / ''S
/OL'' = SOLVE PROBLEM).'
WRITE(*, 9010) '- THE FILE NAME (OUTPUT FILE NAME FOR GENERATING D
/ATA / INPUT FILE NAME FOR SOLVING PROBLEM).'
GOTO 10
ENDIF
C THE FIRST ARGUMENT HAS TO BE 'GEN' OR 'SOL'.
CALL GETARG(1, OPT)
IF(OPT .NE. 'GEN' .AND. OPT .NE. 'SOL') THEN
WRITE(*, 9010) 'ERROR:'
WRITE(*, 9010) 'THE OPTION MUST BE ONE OF THE FOLLOWING:'
WRITE(*, 9010) '-''GEN'' (GENERATE RANDOM DATA).'
WRITE(*, 9010) '-''SOL'' (SOLVE PROBLEM).'
GOTO 10
ENDIF
C THIS ARGUMENT IS THE FILE NAME.
CALL GETARG(2, FILENAME)
WRITE(*, 9020) 'OK'
IF(OPT .EQ. 'GEN') THEN
WRITE(*, 9010) 'GENERATING RANDOM DATA WITH PARAMETERS: '
WRITE(*, 9030) 'N: ', N
WRITE(*, 9030) 'K: ', K
WRITE(*, 9030) 'M: ', M
CALL GENERATE
WRITE(*, 9040) 'SUCCESFULLY GENERATED DATA. EXITING.'
ELSE
WRITE(*, 9010) 'SOLVING PROBLEM WITH PARAMETERS: '
WRITE(*, 9030) 'N: ', N
WRITE(*, 9030) 'K: ', K
WRITE(*, 9030) 'M: ', M
CALL SOLVE
WRITE(*, 9040) 'SUCCESFULLY SOLVED THE PROBLEM. EXITING.'
ENDIF
9010 FORMAT(A)
9020 FORMAT(5X, A)
9030 FORMAT(5X, A, I5)
9040 FORMAT(A, A)
10 STOP
END
C ===================================================
C THIS SUBROUTINE GENERATES A RANDOM PROBLEM INTO A FILE.
SUBROUTINE GENERATE
REAL RAND
CHARACTER * (80) FILENAME
INTEGER N, K, M
INTEGER * 4 TARRAY(3), I, J
COMMON /FNAME/ FILENAME
COMMON /PAR/ N, K, M
C INITIATE RANDOM GENERATOR.
WRITE(*, 9110) 'INITIATING RANDOM GENERATOR.'
CALL ITIME(TARRAY)
I = RAND(TARRAY(1) + TARRAY(2) + TARRAY(3))
WRITE(*, 9120) 'OK'
C OPEN OUTPUT FILE TO WRITE.
WRITE(*, 9140) 'OPENING FILE TO WRITE: ', FILENAME
OPEN(10, FILE = FILENAME, STATUS = 'NEW')
WRITE(*, 9120) 'OK'
C GENERATE DATA.
WRITE(*, 9110) 'WRITING DATA TO FILE.'
DO 20 J = 1, N * (K + M)
WRITE(10, *) RAND(0)
20 CONTINUE
WRITE(*, 9120) 'OK'
C CLOSE FILE.
WRITE(*, 9140) 'CLOSING FILE: ', FILENAME
CLOSE(10)
WRITE(*, 9120) 'OK'
9110 FORMAT(A)
9120 FORMAT(5X, A)
9140 FORMAT(A, A)
RETURN
END
C ===================================================
C THIS SUBROUTINE LOADS THE PROBLEM INTO THE COMMON DATA FROM A FILE.
SUBROUTINE LOAD
CHARACTER * (80) FILENAME
INTEGER N, K, M, I, J
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
COMMON /FNAME/ FILENAME
COMMON /PAR/ N, K, M
COMMON /DAT/ CENTERS, POINTS
C OPEN INPUT FILE TO READ FROM.
WRITE(*, 9240) 'OPENING FILE TO READ FROM: ', FILENAME
OPEN(11, FILE = FILENAME, STATUS = 'OLD')
WRITE(*, 9220) 'OK'
WRITE(*, 9210) 'LOADING DATA FROM FILE.'
C LOAD CENTROIDS.
DO 30 I = 1, K
DO 40 J = 1, N
READ(11, *) CENTERS(J, I)
40 CONTINUE
30 CONTINUE
C LOAD POINTS.
DO 50 I = 1, M
DO 60 J = 1, N
READ(11, *) POINTS(J, I)
60 CONTINUE
50 CONTINUE
WRITE(*, 9220) 'OK'
C CLOSE FILE.
WRITE(*, 9240) 'CLOSING FILE: ', FILENAME
CLOSE(11)
WRITE(*, 9220) 'OK'
9210 FORMAT(A)
9220 FORMAT(5X, A)
9240 FORMAT(A, A)
RETURN
END
C ===================================================
C THIS SUBROUTINE SOLVES THE PROBLEM THAT IS LOADED INTO THE COMMON DATA.
SUBROUTINE SOLVE
LOGICAL CHANGED
CALL LOAD
CALL SETOWNERS(CHANGED)
CALL PSTATE
150 CONTINUE
IF(CHANGED) THEN
CALL MOVEALL
CALL SETOWNERS(CHANGED)
CALL PSTATE
GOTO 150
ENDIF
100 RETURN
END
C ===================================================
C THIS SUBROUTINE DETERMINES THE OWNER OF ALL POINTS AND SETS L TRUE IF
C THERE WAS ANY CHANGE.
SUBROUTINE SETOWNERS(L)
INTEGER I, N, K, M, TMP, OWNER
INTEGER OWNERS(1:10000)
LOGICAL L
COMMON /PAR/ N, K, M
COMMON /OWN/ OWNERS
L = .FALSE.
DO 90 I = 1, M
TMP = OWNER(I)
IF(OWNERS(I) .NE. TMP) THEN
OWNERS(I) = TMP
L = .TRUE.
ENDIF
90 CONTINUE
RETURN
END
C ===================================================
C THIS FUNCTION RETURNS THE OWNER OF A GIVEN POINT.
INTEGER FUNCTION OWNER(P)
INTEGER OWNERS(1:10000)
INTEGER IDX, I, N, K, M
REAL MINV,MINP, DIST, TMP
COMMON /PAR/ N, K, M
COMMON /OWN/ OWNERS
MINP = 1
MINV = DIST(P,1)
DO 80 I = 2, K
TMP = DIST(P, I)
IF(TMP .LT. MINV) THEN
MINP = I
MINV = TMP
ENDIF
80 CONTINUE
OWNER = MINP
RETURN
END
C ===================================================
C THIS FUNCTION RETURNS THE DISTANCE OF A GIVEN POINT AND A GIVEN CENTROID.
REAL FUNCTION DIST(P, C)
INTEGER P, C, I, N, K, M
REAL S
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
COMMON /PAR/ N, K, M
COMMON /DAT/ CENTERS, POINTS
S = 0
DO 70 I = 1, N
S = S + (POINTS(I, P) - CENTERS(I, C)) ** 2
70 CONTINUE
DIST = SQRT(S)
RETURN
END
C ===================================================
C THIS SUBROUTINE MOVES THE CENTROIDS TO THE APPROPRIATE POSITIONS.
SUBROUTINE MOVEALL
INTEGER I, N, K, M
COMMON /PAR/ N, K, M
DO 110 I = 1, K
CALL MOVE(I)
110 CONTINUE
RETURN
END
C ===================================================
C THIS SUBROUTINE MOVES A GIVEN CENTROID TO THE APPROPRIATE POSITION.
SUBROUTINE MOVE(C)
INTEGER C, I, N, K, M
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
COMMON /PAR/ N, K, M
COMMON /DAT/ CENTERS, POINTS
DO 120 I = 1, N
CENTERS(I,C) = PAVG(C, I)
120 CONTINUE
RETURN
END
C ===================================================
C THIS FUNCTION RETURNS THE AVERAGE OF THE I. COORDINATES OF THE POINTS
C BELONGING TO THE C. CENTROID.
REAL FUNCTION PAVG(C, I)
INTEGER OWNERS(1:10000)
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
REAL S
INTEGER C, I, J, CNT, N, K, M
COMMON /PAR/ N, K, M
COMMON /DAT/ CENTERS, POINTS
COMMON /OWN/ OWNERS
S = 0
CNT = 0
DO 130 J = 1, M
IF(OWNERS(J) .EQ. C) THEN
S = S + POINTS(I, J)
CNT = CNT + 1
ENDIF
130 CONTINUE
PAVG = S / CNT
RETURN
END
C ===================================================
C THIS SUBROUTINE PRINTS THE STATE OF THE SYSTEM.
SUBROUTINE PSTATE
INTEGER OWNERS(1:10000)
REAL CENTERS(1:100,1:100), POINTS(1:100,1:10000)
INTEGER I, J, N, K, M
COMMON /PAR/ N, K, M
COMMON /DAT/ CENTERS, POINTS
COMMON /OWN/ OWNERS
WRITE(*, 9310) 'SYSTEM STATE:'
WRITE(*, 9320) 'CENTROIDS:'
DO 140 I = 1, K
WRITE(*, 9330) 'CENTROID: ', I
DO 150 J = 1, N
WRITE(*, 9340) CENTERS(J,I)
150 CONTINUE
140 CONTINUE
WRITE(*, 9320) 'POINTS:'
DO 160 I = 1, M
WRITE(*, 9330) 'POINT: ', I
WRITE(*, *) 'OWNER: ', OWNERS(I)
DO 170 J = 1, N
WRITE(*, 9340) POINTS(J,I)
170 CONTINUE
160 CONTINUE
9310 FORMAT(A)
9320 FORMAT(5X,A)
9330 FORMAT(10X,A,I3)
9340 FORMAT(15X,F10.5)
9350 FORMAT(15X,A,I10)
RETURN
END
C ===================================================
Gauss elimináció
PROGRAM testg
!-----------------------------------------------------------
! A kövektkező program egy lineáris egyenletrendszert old meg
! Gauss-Jordan módszerrel, teljes főelem kiválasztással
! külső modul és osztály használata
!-----------------------------------------------------------
USE Gauss_Jordan
USE Permutation
INTEGER IMAX,JMAX
PARAMETER(IMAX=3,JMAX=4)
!PARAMETER(IMAX=10,JMAX=11)
! tömb deklalárása
REAL matrix(IMAX, JMAX)
! ugyanez vektorra
REAL ismeretlen(IMAX)
! egész számok
INTEGER i, index, n
! tömb feltöltése oszloponként
DATA matrix(:,:) / 2.0, -1.0, 3.0, &
3.0, 2.0, 0.0, &
0.0, -1.0, 2.0, &
8.0, 0.0, 9.0/
n = IMAX
! matrix = 0.0
! do 10, i =1, n
! matrix(i,i) = 1
! matrix(i,n+1) = i
! 10 continue
write(*,*) "Az eredeti matrix,",n," X ",n+1," :"
! szubrutin hívás
call wrtmat(matrix, n)
call ELIMINATION(matrix, n)
write(*,*) "A felso haromszog-matrix:"
call wrtmat(matrix, n)
call VISSZHELY(matrix, ismeretlen, n)
write(*,*) "A megoldas visszahelyettesites utan:"
write(*,*) "********************************************"
write(*,*) (ismeretlen(i), i=1,n)
write(*,*) "********************************************"
end
MODULE Gauss_Jordan
!---------------------------------------------
! Ez a modul három szubrutint tartalmaz:
! 1. wrtmat(matrix, n)
! 2. ELIMINATION(A, n)
! 3. VISSZHELY(A, x, n)
!---------------------------------------------
USE Permutation
IMPLICIT NONE
CONTAINS
! szubrutin definiálása
SUBROUTINE wrtmat(matrix, n)
! paraméterek típusa
INTEGER i,j,n
REAL matrix(n, n+1)
do 10, i=1, n
! belső do-ra egy példa
write(*,*) (matrix(i,j), j= 1,n+1)
10 continue
write(*,*)
end subroutine wrtmat
SUBROUTINE ELIMINATION(A, n)
INTEGER n, i, j, k, u, v, maxi, maxj, tc
REAL A(n, n+1), tempsor(n+1), temposzlop(n)
i = 1
j = 1
call permut_init(n)
! iterácio fortranban
do while (i <= n .and. j <= n)
! Főelem kiválasztása az i. sortól és j. oszloptól
maxi = i
maxj= j
do k=i,n
do u=j,n
if (abs(A(k,u)) > abs(A(maxi,maxj))) then
maxi = k
maxj = u
end if
end do
end do
if (A(maxi,maxj) .ne. 0) then
! Az i. és a főelemet tartalmazó sor cseréje-vektor műveletek
!$OMP WORKSHARE
! blokk kiosztása a szálak között
tempsor = A(i, :)
A(i, :) = A(maxi, :)
A(maxi, :) = tempsor
!$OMP END WORKSHARE
write(*,*) "Az", i, ". es a foelemet tartalmazo (", maxi, ") sor csereje"
call wrtmat(A, n)
! A j. és a főelemet tartalmazó oszlop cseréje
!$OMP WORKSHARE
temposzlop = A(:,j)
A(:,j) = A(:,maxj)
A(:,maxj) = temposzlop
!$OMP END WORKSHARE
call permut_csere(j, maxj)
write(*,*) "Az", j, ". es a foelemet tartalmazo (", maxj, ") oszlop csereje"
call wrtmat(A, n)
! Az i. sort elosztjuk a főelemmel
A(i, :) = A(i, :) / A(i,j)
write(*,*) "Az", i, ". sort elosztjuk a foelemmel"
call wrtmat(A,n)
! A főelem A(i, j) = 1
! A j. oszlop eliminálása
!$OMP DO SCHEDULE(STATIC,1)
do u=i+1,n
A(u, j+1:) = A(u, j+1:) - A(i, j+1:) * A(u,j)
enddo
!$OMP END DO
A(i+1:,j) = 0
write(*,*) "Az", j, ". oszlop eliminalasa!"
call wrtmat(A, n)
i = i+1
else
write(*,*) "Szingularis matrix: nincs inverz!"
stop
end if
j = j+1
end do
end subroutine ELIMINATION
SUBROUTINE VISSZHELY(A, x, n)
INTEGER n, i, j
REAL A(n, n+1), x(n), sum
!$OMP PARALLEL
do i=n,1,-1
! belső függvény- skaláris szorzat
! bágyazott szálak létrehozása
!$OMP PARALLEL
sum = dot_product(A(i,i+1:n), x(i+1:n))
!$OMP END PARALLEL
x(i) = A(i, n+1) - sum/A(i, i)
enddo
!$OMP END PARALLEL
! Az eredeti sorrend az oszlopcseréket figyelembe véve
call permut_vector(x)
end subroutine VISSZHELY
end module gauss_jordan
MODULE Permutation
IMPLICIT NONE
INTEGER, PRIVATE, ALLOCATABLE :: permutacio(:)
INTEGER, PRIVATE :: n
CONTAINS
SUBROUTINE permut_init(quantity)
INTEGER, INTENT(IN) :: quantity
INTEGER i
ALLOCATE (permutacio(quantity))
n = quantity
DO 10,i=1,n
permutacio(i) = i
10 CONTINUE
END SUBROUTINE permut_init
SUBROUTINE permut_csere(i,j)
INTEGER, INTENT(IN) :: i, j
INTEGER temp, k
temp = permutacio(i)
permutacio(i) = permutacio(j)
permutacio(j) = temp
do 10, k=1,n
! write(*,*) "permutacio(", k,")=", permutacio(k)
10 continue
END SUBROUTINE permut_csere
SUBROUTINE permut_vector(x)
REAL, INTENT(OUT) :: x(n)
REAL :: temp(n)
INTEGER i
DO 10, i=1,n
temp(i) = x(permutacio(i))
10 continue
x(:) = temp(:)
END SUBROUTINE permut_vector
END module Permutation
Bellman-Ford algoritmus
A programhoz tartozó fájlok az alábbi linkeken letölthetők:
Harmadfokú egyenletmegoldó
PROGRAM harmadfoku
IMPLICIT NONE
DOUBLE PRECISION a1, b1, c1, d1 !A bemeno egyutthatok
DOUBLE PRECISION a, b, c !A lenormalt egyutthatok
DOUBLE PRECISION a2, b2, theta !segedvaltozok
COMPLEX q, r !Segedvaltozok
COMPLEX x1, x2, x3 !Gyokok
DOUBLE PRECISION pi !A pi szam
pi=3.1415926535897932
WRITE(*,*) 'Valos egyutthatos harmadfoku egyenlet megoldasa.'
WRITE(*,*) 'Adja meg az egyenlet egyutthatoit,'
WRITE(*,*) 'es megadom az adott egyutthatoju egyenlet megoldasait.'
WRITE(*,*) 'Kerem x**3 egyutthatojat:'
READ(*,*) a1
IF (a1 .NE. 0) THEN
WRITE(*,*) 'Kerem x**2 egyutthatojat:'
READ(*,*) b1
WRITE(*,*) 'Kerem x egyutthatojat:'
READ(*,*) c1
WRITE(*,*) 'Kerem a konstans tagot:'
READ(*,*) d1
!Az egyenlet egyutthatoinak atszamitasa, hogy a foegyutthato 1 legyen
a=b1/a1
b=c1/a1
c=d1/a1
!Segedvaltozok
q=(a**2-3*b)/9
r=(2*a**3-9*a*b+27*c)/54
IF ((real(r)**2) .LT. (real(q)**3)) THEN
!Casus irreducibilis, a valos gyokok csak komplex szamolassal erhetok el
WRITE(*,*) 'Az egyenletnek harom kulonbozo valos gyoke van.'
theta=acos(real(r)/(sqrt((real(q))**3)))
!A komplex gyokvonasnak megfeleloen harom gyok adodik
x1=-2.0*sqrt(q)*cos(theta/3)-a/3
x2=-2.0*sqrt(q)*cos((theta+2*pi)/3)-a/3
x3=-2.0*sqrt(q)*cos((theta-2*pi)/3)-a/3
ELSE
!Casus reducibilis, egy valos es ket konjugalt komplex gyok
a2=0
IF (real(r) .LT. 0) THEN
a2=(abs(r)+sqrt(r**2-q**3))**(1.0/3)
ELSE
a2=-1*(abs(r)+sqrt(r**2-q**3))**(1.0/3)
ENDIF
b2=0
IF (a2 .NE. 0) THEN
b2=q/a2
ENDIF
!A valos gyok
x1=(a2+b2)-a/3
!A komplex gyokok
x2=cmplx((-1.0/2)*(a2+b2)-a/3, sqrt(3.0)/2*(a2-b2))
x3=cmplx((-1.0/2)*(a2+b2)-a/3, -1*sqrt(3.0)/2*(a2-b2))
ENDIF
WRITE(*,*) 'Az ', a1, b1, c1, d1, ' egyutthatos harmadfoku egyenlet gyokei'
WRITE(*,*) 'x1 = ', x1
WRITE(*,*) 'x2 = ', x2
WRITE(*,*) 'x3 = ', x3
ELSE
WRITE(*,*) 'Az egyenlet nem harmadfoku.'
ENDIF
STOP
END PROGRAM
Program legfeljebb harmadfokú egyenletek megoldására
A programhoz tartozó fájlok az alábbi linkeken letölthetők:
QR módszer
! ************************************************************************
! Fájl: QRAlg.f08
! Leírás: QR felbontás és QR módszer mátrix sajátértékeinek meghatározására
! ************************************************************************
program QRAlg
implicit none
! Rövid főprogram amely teszt adatokon futtatja a QR módszer algoritmusát
double precision, dimension(4,4) :: A,eig
double precision :: eps = 0.00001 ! epsilon a megengedett hiba
! Az A 4x4-es mátrix, elemei oszlopfolytonosan megadva
A = reshape( [2.0, 2.0, 0.0, 0.0, 1.0, 3.0, 0.0, 0.0, -1.0, 1.0, 4.0, -1.0, 1.0, -2.0, 2.0, 1.0], shape(A) )
! eig egy 4x4-es felsőháromszögmátrix,
! a diagonálisában a számított sajátértékekkel
eig = qr_method(A, eps)
! Input és az eredmény kiíratása
call print_matrix(A)
print *, '--------------------------'
call print_matrix(eig)
! A lényegi munkát végző függvények
contains
! ********************************************************
! Egy adott mátrix QR felbontását készíti el
! Input: A = négyzetes valós elemű mátrix
! Output: Q,R = négyzetes valós mátrixok,
! A = Q*R, Q ortogonális, R felsőháromszög mátrix
! A megvalósítás Gram-Schmidt ortogonalizációval történik
! Segédfüggvények: normalize(), projection()
! ********************************************************
subroutine qr_decomposition(A,Q,R)
implicit none
double precision, intent(in), dimension(:,:) :: A
double precision, intent(out), dimension(:,:) :: Q,R
! segédváltozó, az A n x n-es esetén egy n hosszú vektor
double precision, dimension(size(A,1)) :: sum_proj
integer :: n,k,j
n = size(A,1) ! mátrix mérete
! Elég csupán a Q mátrixot elkészíteni, az R utána szorzással megkapható
! Az algoritmus inicializálása, az input mátrix első oszlopát normalizáljuk
! Megjegyzés: A(1:n,1) syntaxis: array slice, A első oszlopát adja
Q(1:n,1) = normalize(A(1:n,1))
! A ciklusban Q további oszlopait ortogonalizáljuk minden előzőre
do k=2,n
! Gram-Schmidt féle projekciók elkészítése és összegzése
sum_proj = 0.0
do j=1,k-1
! A k. lépésben az eredeti mátrix k. oszlopát vetítjük a már meglévőkre
sum_proj = sum_proj + projection(vector=A(1:n,k),project_to=Q(1:n,j))
end do
! A vetítések összegét levonva az eredeti vektorból,
! egy az összes a rendszerben őt megelőzőre merőleges vektort kapunk,
! majd az elkészült új oszlopot normalizáljuk
Q(1:n, k) = normalize(A(1:n, k) - sum_proj)
end do
! R = Q'*A, a két intrinsic a transzponálást és mátrixszorzást végzi
R = matmul(transpose(Q), A)
end subroutine qr_decomposition
! ********************************************************
! Merőleges vetület számítása
! Input: vector = n hosszú valós vektor, amit vetítünk
! project_to, ugyanakkora méretű vektor, amire vetítünk
! Result: vetület vektor
! ********************************************************
function projection(vector, project_to)
implicit none
double precision, intent(in), dimension(:) :: vector, project_to
double precision, dimension(size(vector)) :: projection
! proj a on b = a dot b/ a dot a * a
! a vetület vektor tehát két skalár szorzat hányadosa * a vektor amire vetítünk
projection = dot_product(project_to, vector)/dot_product(project_to, project_to) * project_to
end function projection
! ********************************************************
! Vektor normalizálása (2-es normában)
! Input: vector, n hosszú valós vektor
! Result: a normalizált vektor
! ********************************************************
function normalize(vector)
implicit none
double precision, intent(in), dimension(:) :: vector
double precision, dimension(size(vector)) :: normalize
! A vektort elosztjuk a hosszával, vagyis sqrt() - vel
normalize = vector / sqrt(dot_product(vector, vector))
end function normalize
! ********************************************************
! Mátrix sajátértékeinek meghatározása QR módszerrel
! Input: matrix, négyzetes valós mátrix
! eps: numerikus hibakorlát
! Result: R felsőháromszög mátrix,
! ami a sajátértékeket a diagonálisában tartalmazza
! X(k+1) = R(k) * Q(k) k=1,2,... az iteráció
! segédfüggvény: qr_decomposition(),check_convergence()
! ********************************************************
function qr_method(matrix, eps)
implicit none
double precision, intent(in), dimension(:,:) :: matrix
double precision, dimension(size(matrix,1),size(matrix,2)) :: qr_method
double precision, intent(in) :: eps
double precision, dimension(size(matrix,1),size(matrix,2)) :: Q,R,eigenvalues
! inicializáljuk az algoritmust
eigenvalues = matrix
! A fő iterációs ciklus
do while ( check_convergence(eigenvalues, eps) .eqv. .false. )
! Előállítjuk a QR felbontást,
call qr_decomposition(eigenvalues, Q,R)
! majd fordított sorrendben szorozzuk őket össze
eigenvalues = matmul(R,Q)
end do
qr_method = eigenvalues
end function qr_method
! ********************************************************
! A QR módszer segéd függvénye a konvergencia ellenőrzésére
! Input: matrix: négyzetes valós mátrix
! eps: a numerikus hibakorlát
! ********************************************************
function check_convergence(matrix, eps)
implicit none
logical :: check_convergence
double precision, intent(in), dimension(:,:) :: matrix
double precision, intent(in) :: eps
double precision :: max_err
integer :: n,i,j
n = size(matrix,1)
! A mátrixnak felsőháromszög mátrixhoz kell tartania,
! vagyis az alsóháromszög beli elemeknek 0-hoz kell tartania
! Megkeressük az alsóháromszög rész abszolútértékben maximális elemét
max_err = 0.0
do i=2,n
do j=1,i-1
if ( abs(matrix(i,j)) > max_err ) then
max_err = abs(matrix(i,j))
end if
end do
end do
! Ha a maximális hiba kisebb mint epsilon akkor ok
if ( max_err < eps ) then
check_convergence = .true.
else
check_convergence = .false.
end if
end function check_convergence
! Egyszerű kiírató segédfüggvény, a mátrixot soronként írja ki
subroutine print_matrix(matrix)
implicit none
double precision, dimension(:,:) :: matrix
integer :: i,j,n,m
n = size(matrix,1)
m = size(matrix,2)
do i=1,n
print *, ( matrix(i,j), j=1,m )
end do
end subroutine print_matrix
end program QRAlg
A programhoz tartozó fájlok az alábbi linkeken letölthetők:
Verem típus szimuláció
C Verme típus szimulációs program FORTRAN 77-ben
C Készítette: Kuthi Balázs
C Használt fordítóprogram: fort77
PROGRAM VEREM
INTEGER BE
C Szimulációhoz szükséges menü kiiratása
1 WRITE (*,*) "---------------------------------"
WRITE (*,*) "Verem muveletek tesztelese"
WRITE (*,*) "1. Ures-e a verem"
WRITE (*,*) "2. Legfelso elem lekerdezese"
WRITE (*,*) "3. Elem felvetele"
WRITE (*,*) "4. Legfelso elem eltavolitasa"
WRITE (*,*) "5. Verem tartalmának megtekintése"
WRITE (*,*) "6. Kilepes"
WRITE (*,*) "Kivalasztott muvelet: "
C Választott művelet beolvasása
READ (*,*) BE
C Felhasználó választásának megfelelő művelet végrehajtása
IF (BE .EQ. 1) THEN
IF (ISEMPTY()) THEN
WRITE (*,*) "A verem ures."
ELSE
WRITE (*,*) "A verem nem ures."
END IF
GOTO 1
ELSE IF (BE .EQ. 2) THEN
IF (ISEMPTY()) THEN
WRITE (*,*) "A veremben nincsenek elemek."
ELSE
20 FORMAT(1x, 'A verem legfelso eleme: ', I3)
WRITE (*,20) TOP()
END IF
GOTO 1
ELSE IF (BE .EQ. 3) THEN
WRITE (*,*) "Kerem a felveendo elemet: "
READ (*,*) BE
IF((BE .GE. 100) .OR. (BE .LE. -100)) THEN
WRITE(*,*) "Az adat nem -100 és 100 között van"
GOTO 1
END IF
CALL PUSH(BE)
GOTO 1
ELSE IF (BE .EQ. 4) THEN
IF (.NOT. ISEMPTY()) THEN
30 FORMAT(1x, 'A verem legfelso eleme eltavoltiva: ', I3)
WRITE (*,30) POP()
ELSE
WRITE (*,*) "A veremben nincsenek elemek."
END IF
GOTO 1
ELSE IF (BE .EQ. 5) THEN
CALL WRITESTACK()
GOTO 1
ELSE IF (BE .NE. 6) THEN
WRITE (*,*) "Nem megfeleo input."
GOTO 1
END IF
STOP
END
C Közös használatú adatok (verem szimulálása egy tömbbel valamint egy elemszámmal)
BLOCK DATA
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
DATA STACK/100*0/, COUNT/0/
END
C Üres-e a tömb
LOGICAL FUNCTION ISEMPTY()
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
IF (COUNT .EQ. 0) THEN
ISEMPTY = .TRUE.
ELSE
ISEMPTY = .FALSE.
END IF
RETURN
END
C Legfelső elem lekérdezése
INTEGER FUNCTION TOP()
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
TOP = STACK(COUNT)
RETURN
END
C Elem felvétele a tömbbe
SUBROUTINE PUSH(A)
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
INTEGER A
IF(COUNT .LT. 100) THEN
STACK(COUNT + 1) = A
COUNT = COUNT + 1
ELSE
WRITE (*,*) "A verem betelt."
END IF
RETURN
END
C Legfeső elem eltávolítása (ezt az elemet visszaadjuk)
INTEGER FUNCTION POP()
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
POP = STACK(COUNT)
COUNT = COUNT - 1
RETURN
END
C Verem tartalmának kiiratása
SUBROUTINE WRITESTACK()
INTEGER STACK(100), COUNT
COMMON /STACK/ STACK, COUNT
WRITE(*,*) "A verem tartalma:"
DO 100 I=COUNT, 1, -1
WRITE(*,40) COUNT-I+1, STACK(I)
40 FORMAT(1x, I3, ".: ", I3)
100 CONTINUE
RETURN
END
Aknakereső
program miner
c Author: Zsolt Turi
c E-mail: tuzraai at inf.elte.hu
c Date: 2013.05.15.
c
c Description: The classic minesweeper game written in fortran
c
c 'mines(i,j)' stores how many adjacent mines, 9 if it is a mine
c 'visible(i,j)' stores is the field visible for the user
c 'maxn' is the size of the minefield
c 'mineCount' is the number of mines hidden
c 'state' is an enum: 0 playing, 1 lost, 2 won
c TODO: randomize the mines
c TODO: make colors if possible
c initial definitions
implicit none
integer maxn, mineCount
parameter (maxn=8)
parameter (mineCount=5)
integer mines(maxn,maxn)
logical visible(maxn,maxn)
integer x,y, state, remains
state = 0
remains = maxn*maxn-mineCount
call init(mines, visible, maxn, mineCount)
call draw(mines, visible, maxn)
50 call getPoint(x,y,maxn)
write(*,200) x,y
call reveal(mines, visible, maxn, x, y, state, remains)
call draw(mines, visible, maxn)
if (state .eq. 1) go to 250
if (state .eq. 2) go to 280
go to 50
200 format (i3,i3)
250 call showall(visible, maxn)
call draw(mines, visible, maxn)
call gameOver()
goto 300
280 call showall(visible, maxn)
call draw(mines, visible, maxn)
call winner()
300 end
c--------------------------------------
c the 2nd version of reveal, to make recursion
c NOTE: recursion is not allowed to oneself
subroutine reveal2(mines, visible, n, x, y, state, remains)
implicit none
integer i,j,n,x,y, state, remains
integer mines(n,n)
logical visible(n,n)
call reveal(mines, visible, n, x, y, state, remains)
end
c--------------------------------------
c reveals a field (x,y) on the minefield
subroutine reveal(mines, visible, n, x, y, state, remains)
implicit none
integer i,j,n,x,y, state, remains
integer mines(n,n)
logical visible(n,n)
if(.not.(((x .gt. 0) .and. (x .le. n)) .and.
1 ((y .gt. 0) .and. (y .le. n)))) go to 1700
if(visible(x,y)) go to 1700
visible (x,y) = .true.
remains = remains - 1
if (mines(x,y) .eq. 9) then
state = 1
else if (remains .lt. 1) then
state = 2
else if (mines(x,y) .eq. 0) then
call reveal2(mines, visible, n, x-1, y, state, remains)
call reveal2(mines, visible, n, x+1, y, state, remains)
call reveal2(mines, visible, n, x, y-1, state, remains)
call reveal2(mines, visible, n, x, y+1, state, remains)
endif
1700 end
c--------------------------------------
c writes the winning caption to the screen
subroutine winner()
write (*,1750) ''
write (*,1750) ''
write (*,1750) 'CONGRATULATION!'
write (*,1750) 'You won the GAME!'
write (*,1750) ''
write (*,1750) ''
1750 format(a)
end
c--------------------------------------
c writes the losing caption to the screen
subroutine gameOver()
write (*,1780) ''
write (*,1780) ''
write (*,1780) 'BOOOOOM!'
write (*,1780) 'GAME OVER!'
write (*,1780) ''
write (*,1780) ''
1780 format(a)
end
c--------------------------------------
c asks for a coordinate from the user
subroutine getPoint(x,y,n)
implicit none
integer x,y,n,i
1800 write (*, 1810) 'Adj meg egy sort es egy oszlopot! Pl.:34'
read (*, 1820) x,y
if(((x .gt. 0) .and. (x .le. n)) .and. ((y .gt. 0) .and. (y .le. n))) go to 1850
go to 1800;
1810 format(a)
1820 format(i1,i1)
1850 end
c--------------------------------------
c draws the minefield to the console
subroutine draw(mines, visible, n)
implicit none
integer i,j,n
integer mines(n,n)
logical visible(n,n)
write(*,1930)
write(*,1950) ' 1 2 3 4 5 6 7 8'
write(*,1950) 'o----------------'
do 1910 i=1,n
write(*,1940) i,'|'
do 1900 j=1,n
if (visible(i,j)) then
if (mines(i,j) .ne. 9) then
if (mines(i,j) .ne. 0) then
write(*,1920) mines(i,j)
else
write(*,1921) ' '
end if
else
write(*,1921) 'X'
end if
else
write(*,1921) '?'
end if
1900 continue
write(*,1930)
1910 continue
write(*,1930)
1920 format(i2,$)
1921 format(1x,a,$)
1930 format(1x)
1940 format(1x,i2,a,$)
1950 format(3x,a)
end
c--------------------------------------
c initialises the minefield
subroutine init(m, v, n, mc)
implicit none
integer i,j,n,mc,s,x,y
integer m(n,n)
logical v(n,n)
do 2000 i=1,n
do 2000 j=1,n
m(i,j) = 0
v(i,j) = .false.
2000 continue
do 2050 i=1,mc
2030 x = int(rand(0)*n+1)
y = int(rand(0)*n+1)
if (m(x,y) .eq. 9) go to 2030
m(x,y)=9
2050 continue
do 2100 i=1,n
do 2100 j=1,n
if (m(i,j) .ne. 9) then
call near(m,n,i,j,s)
m(i,j) = s
end if
2100 continue
end
c--------------------------------------
c show the whole field
subroutine showall(v, n)
implicit none
integer i,j,n
logical v(n,n)
do 2200 i=1,n
do 2200 j=1,n
v(i,j) = .true.
2200 continue
end
c--------------------------------------
c computes how many mines are in the nearest fields
subroutine near(m,n,i,j,s)
implicit none
integer n,i,j
integer m(n,n)
integer s
s = 0
if(i .gt. 0)then
if(j .gt. 0)then
if(m(i-1,j-1) .eq. 9) s = s + 1
end if
if(m(i-1,j ) .eq. 9) s = s + 1
if(j .lt. n)then
if(m(i-1,j+1) .eq. 9) s = s + 1
end if
end if
if(j .gt. 0)then
if(m(i ,j-1) .eq. 9) s = s + 1
end if
if(j .lt. n)then
if(m(i ,j+1) .eq. 9) s = s + 1
end if
if(i .lt. n)then
if(j .gt. 0)then
if(m(i+1,j-1) .eq. 9) s = s + 1
end if
if(m(i+1,j ) .eq. 9) s = s + 1
if(j .lt. n)then
if(m(i+1,j+1) .eq. 9) s = s + 1
end if
end if
end
c--------------------------------------
Dáma
c egy dama jatek, ahol nincs uteskenyszer, sem utessorozat az alap babuk: o,x
c a dama babuk: O,X ; a tabla 8x8 as, lepni a sor oszlop indexek megadasaval
c pl. E2 F3, kilepni a programbol az EX paranccsal lehet
program draughts
implicit none
character table(8, 8)
logical pl_o, piece_ok, valid_index, move_ok
character*2 in_from, in_to
character c
integer fr,fc,tr,tc,player_lose,letter_to_int
call build_table(table)
c a o jatekos kezd
pl_o = .true.
c elvalaszto karakterek, atlathatosag miatt, (A10)--> formatum
600 write(*, "(A10)") "=========="
c a tabla kriajzolasa
call print_table(table)
c kiirom ki lep
if (pl_o) then
c /: uj sor karakter
write(*, "(A5/)") "o lep"
else
write(*, "(A5/)") "x lep"
end if
601 print *, "Adja meg honnan lep (pl. E2)"
print *, "Kilepes: EX parancs"
read (*, *) in_from
c ha ex et irt be kilepek a programbol(, ugorj a 900 as cimkehez)
if(in_from .eq. "ex")then
goto 900
end if
c fr,fc be beolvasom melyik oszlop, sor lett megadva
fr = letter_to_int(in_from(2:2))
fc = letter_to_int(in_from(1:1))
c ellenorzom, hogy 1-8 kozott vannak e az indexek
if(.not.valid_index(fr,fc)) then
goto 601
end if
c a mezon o vagy x kell hogy legyen, jatekostol fuggoen
c = table(fr, fc)
if(.not.piece_ok(c, pl_o)) then
c ha nem, akkor ujra bekeram a mezoket
goto 601
end if
print *, "Adja meg hova lep (pl. F3)"
read (*, *) in_to
c ha ex et irt be kilepek
if(in_to .eq. "ex")then
goto 900
end if
c tr, tc-be beolvasom melyik oszlop, sor lett megadva
tr = letter_to_int(in_to(2:2))
tc = letter_to_int(in_to(1:1))
c ellenorzom, hogy 1-8 kozott vannak e az indexek
if(.not.valid_index(tr,tc)) then
goto 601
end if
c legalis-e a lepes
if(.not.move_ok(fr,fc,
+ tr,tc,c,pl_o,table,.true.)) then
goto 601
end if
c ha legalis a lepes, lepek
table(fr,fc) = "_"
table(tr,tc) = c
c a masik jatekos fog jonni
pl_o = .not.pl_o
c megnezem beert e valaki az ellenfel alapvonalara, ha igen dama lesz
call cr_dames(table)
c megnezem vesztett-e valaki, ha nem visszamegyek az elejere
if (player_lose(table) .eq. 0) then
goto 600
else if(player_lose(table) .eq. 1) then
print *, "jatek vege, x nyert"
else if(player_lose(table) .eq. 2) then
print *, "jatek vege, 0 nyert"
end if
900 end program draughts
c a table kiirasa
subroutine print_table(table)
character table(8, 8)
do i=1,8
c kiirom a sor szamat
c I1: 1 hosszu integer, $: ne tegyen be uj sor karaktert a vegen
write(*, "(I1, A1$)") i," "
do j=1,8
c kiirom a sorban levo babukat
write(*, "(A1$)") table(i, j)
end do
print *, ""
end do
c /: uj sor karakter, a10: 10 hosszu karakterlanc
write(*, "(/A10)") " ABCDEFGH"
write(*, "(A10)") "=========="
end subroutine print_table
c c pl_o-tol fuggoen, o,O vagy x,X kell legyen?
logical function piece_ok(c, pl_o)
implicit none
character c
logical pl_o
c ha az o jatekos van soron, akkor o,O egyebkent x,X
if(pl_o .and. c.ne.'o' .and. c.ne.'O') then
print *, "hiba:nincs babuja az adott indexen"
piece_ok = .false.
else if(.not.pl_o .and. c.ne.'x' .and. c.ne.'X') then
print *, "hiba:nincs babuja az adott indexen"
piece_ok = .false.
else
piece_ok = .true.
end if
end function piece_ok
c melyik jatekos vesztett 0: egyik sem, 1: o vesztett, 2: x vesztett
c osszeszamolom a babuk szamat a tablan
integer function player_lose(table)
character table(8, 8)
integer o_num, x_num
o_num = 0
x_num = 0
do i=1,8
do j=1,8
if (table(i, j) .eq. 'o' .or.
+ table(i, j) .eq. 'O') then
o_num = o_num + 1
else if (table(i, j) .eq. 'x' .or.
+ table(i, j) .eq. 'X') then
x_num = x_num + 1
end if
end do
end do
c ha 0 darab o van, akkor o vesztett
if(0 .eq. o_num )then
player_lose = 1
c ha 0 darab x van akkor x vesztett
else if (0 .eq. x_num) then
player_lose = 2
else
c egyebkent megy tovabb a jatek
player_lose = 0
end if
end function player_lose
c lephet-e a babu ebbe az iranyba
logical function move_ok(fr,fc,tr,tc,c,pl_o,table,mod)
implicit none
character table(8, 8)
integer fr, fc, tr, tc
integer r_d, c_d, mr, mc
character c
logical pl_o, mod, piece_ok
c r_d: honnan sor indexe - hova sor indexe
r_d = fr - tr
c_d = fc - tc
c mr: a leutendo babu sorindexe
mr = fr-1*sign(1,r_d)
mc = fc-1*sign(1,c_d)
c ha nem dama a babu, akkor megnezem hogy visszafele lepett-e
if(pl_o.and.c.eq.'o'.and.r_d.le.0) then
move_ok = .false.
print *, "hiba: csak damaval lehet visszafele lepni"
return
else if(.not.pl_o.and.c.eq.'x'.and.r_d.ge.0) then
move_ok = .false.
print *, "hiba: csak damaval lehet visszafele lepni"
return
end if
c atlosan lepett-e 1-et
if(abs(r_d).eq.1.and.abs(c_d).eq.1) then
c van e ott valaki, ha van akkor nem legalis
if(table(tr,tc).ne."_") then
move_ok = .false.
print *, "hiba: van babu az adott mezon"
return
else
move_ok = .true.
return
end if
end if
c atlosan leptett- 2-t
if(abs(r_d).eq.2.and.abs(c_d).eq.2) then
c ha igen akkor van-e ott valaki
if(table(tr,tc).ne."_") then
move_ok = .false.
print *, "hiba: van babu az adott mezon"
return
else
c ha nincs senki akkor van-e ellenfel akit tudok utni
if(piece_ok(table(mr,mc),.not.pl_o)) then
move_ok = .true.
c ha van, es a modositas engedelyezett: leutom
if(mod) then
table(mr,mc) = "_"
end if
return
else
move_ok = .false.
print *, "hiba: nincs ellenfel"
return
end if
end if
end if
c egyéb esetben nem legalis a lepes
print *, "hiba: unkown"
move_ok = .false.
end function move_ok
c a megadott sor, oszlop indexek megfeleloek-e: [1, 8] kozottiek
logical function valid_index(r, c)
integer r, c
if (1 .gt. r .or. 8 .lt. r .or.
+ 1 .gt. c .or. 8 .lt. c) then
valid_index = .false.
print *, "hiba:nem jo indexeket adott meg"
else
valid_index = .true.
end if
end function valid_index
c betu index szam indexxe konvertalasa
integer function letter_to_int(letter)
character letter
select case(letter)
case ('a')
letter_to_int = 1
case ('b')
letter_to_int = 2
case ('c')
letter_to_int = 3
case ('d')
letter_to_int = 4
case ('e')
letter_to_int = 5
case ('f')
letter_to_int = 6
case ('g')
letter_to_int = 7
case ('h')
letter_to_int = 8
case ('A')
letter_to_int = 1
case ('B')
letter_to_int = 2
case ('C')
letter_to_int = 3
case ('D')
letter_to_int = 4
case ('E')
letter_to_int = 5
case ('F')
letter_to_int = 6
case ('G')
letter_to_int = 7
case ('H')
letter_to_int = 8
case ('1')
letter_to_int = 1
case ('2')
letter_to_int = 2
case ('3')
letter_to_int = 3
case ('4')
letter_to_int = 4
case ('5')
letter_to_int = 5
case ('6')
letter_to_int = 6
case ('7')
letter_to_int = 7
case ('8')
letter_to_int = 8
case default
letter_to_int = 0
end select
end function letter_to_int
c kezdo tabla letrehozasa
subroutine build_table(table)
character table(8, 8)
do i=1,8
do j=1,8
if(4 .GT. i .AND. 0 .EQ. modulo(i+j, 2)) then
table(i, j) = 'x'
else if(5 .LT. i
+ .AND. 0 .EQ. modulo(i+j, 2) ) then
table(i, j) = 'o'
else
table(i, j) = '_'
endif
end do
end do
end subroutine build_table
c ha egy babu atert a tuloldalra, ezert dama lesz
subroutine cr_dames(table)
character table(8, 8)
do i=1,8
if(table(1,i) .eq. "o") then
table(1,i) = "O"
end if
if(table(8,i) .eq. "x") then
table(8,i) = "X"
end if
end do
end subroutine cr_dames
Nem limitált polimorfikus objektumokat tároló adatszerkezetek és matematikai kiértékelőfa
A programhoz tartozó fájlok az alábbi linkeken letölthetők: