Kombinatorik
: effiziente Berechnung der Varianten
April 14th, 2009
1 comment
Ich hatte schon früher das Problem einen Algorithmus zu finden um alle Varianten der Positionierung von k Elementen auf n Plätzen zu ermitteln (also Möglichkeiten der Positionierung), besonders wenns um Speichereffizenz (nicht alle Kombination speichern) geht. Jupp hat mich heut wieder auf das Problem gestoßen und ich hab endlich eine “schöne” Lösung gefunden (es wird nicht viel benötigt, nur ein paar Schleifen und die Berechnung des Binomialkoeff.):
program iterkombi implicit none integer(kind=4), parameter :: n=6, k=2 integer(kind=4) :: tmpN, tmpK, ind, pos, i, j integer(kind=4), dimension(1:n) :: arrayP character(len=15) :: str ! schleife über Nr. der Kombination do j=1, binomial(n,k), 1 ind = j tmpN = n; tmpK = k pos = 0; arrayP = 0 ! jedes der k Elemente positionieren do i=1, k, 1 pos = pos + 1 do while( ind - binomial(tmpN-1,tmpK-1) > 0 ) ind = ind - binomial(tmpN-1,tmpK-1) tmpN = tmpN - 1 pos = pos + 1 end do tmpN = n - pos tmpK = tmpK - 1 arrayP( pos ) = 1 end do write(str,*) n write(unit=*,fmt='(A,I0,A,A,'//str//'I1)') "Belegungsarray (Nr. ", j, "): ", char(9), arrayP end do contains function binomial( n,k ) integer(kind=4) :: binomial integer(kind=4) :: n, k, i, x, y x = 1; y = 1 do i=k+1, n, 1 x = x*i ! n!/k! end do do i=2, n-k, 1 y = y*i ! (n-k)! end do binomial = x / y end function end program
Ausgabe:
Belegungsarray (Nr. 1): 110000 Belegungsarray (Nr. 2): 101000 Belegungsarray (Nr. 3): 100100 Belegungsarray (Nr. 4): 100010 Belegungsarray (Nr. 5): 100001 Belegungsarray (Nr. 6): 011000 Belegungsarray (Nr. 7): 010100 Belegungsarray (Nr. 8): 010010 Belegungsarray (Nr. 9): 010001 Belegungsarray (Nr. 10): 001100 Belegungsarray (Nr. 11): 001010 Belegungsarray (Nr. 12): 001001 Belegungsarray (Nr. 13): 000110 Belegungsarray (Nr. 14): 000101 Belegungsarray (Nr. 15): 000011
Der Vorteil: es kann jede Kombination einzeln berechnet werden ohne zu wissen wie die vorherige Kombination aussah.
Recent Comments