09. juli 2003 - 10:11Der er
24 kommentarer og 1 løsning
Beregn og vis kombinationer (matematik)
Det er sgu for længe siden jeg har haft matematik.....
Jeg er ved at lave et lille spilleprogram til spil på Oddset. I den forbindelse har jeg brug for at kunne beregne og vise kombinationer ved taludtrækning. F.eks. 3 ud af 6: -Her er 20 forskellige kombinationer: 1-2-3, 1-2-4, 1-2-5,..............., 4-5-6
Jeg har brug for at gemme alle disse kombinationer, f.eks. i et array. Hvordan?
-Jeg har fundet et enkelt prog. fra Planetsourcecode som virker, men det er en recursiv funktion (kalder sig selv gentagne gange), og det bryder jeg mig absolut ikke om. ;-)
OK, men jeg regner med at det blot er 10-20 linier kode til at liste disse kombinationer. -Et par betingede løkker mm. Den funktion jeg nævner i spm. fylder heller ikke mere, men jeg er som sagt ikke helt 'tryg' ved recursive funktioner. Mail: tjacob@stofanet.dk
Du bliver nødt til at fortælle hvor store dine tal er. Hvis jeg har forstået dig ret, ønsker du en stump kode, som sørger for at alle de forskellige kombinationer, hvor man skal udtage p ting valgt blandt n ting bliver listet som tekststrnge gemt i en tabel.
Der er som bekendt K(n,p)= n!/(p!*(n-p)!) kombinationer, og det kan jo hurtigt blive meget store tal.
Derfor fortæl mellem hvilke grænser n og p skal ligge.
Det drejer sig kun om relativt små tal. Lad os sige 2-5 ud af 3-15. Det giver max. 3/4000 kombinationer.
Men disse tal afgrænsninger kan man jo sagtens lave før selve funktionen kaldes; Jeg ønsker blot en funktion, der kan liste dem, med n og p som inputs.
Her er først en løsning, som benytter rekursion. Det er en meget simpel procedure, som kalder sig selv, men den simpleste løsning er altså at gøre det rekursivt. Du bør vende dig til at det at benytte rekursion i mange tilfælde giver de simpleste og bedste løsninger.
Her er programmmet:
'Dette VB-program lister alle kombinationer, 'der består af p tegn valgt bnandt n tegn. 'Tegnene er her ABCDEFG... 'Kombinationerne gemmes i tekststrengen R adskilt af komma.
Option Explicit Dim n As Byte, p As Byte, R As String Const Tegn = "ABCDEFGHIJKLMNO" Sub Komb(ByVal pos As Byte, ByVal sum As Byte, med As Boolean, ByVal s As String) If med Then s = s & Mid(Tegn, pos, 1): sum = sum + 1 End If If sum < p And pos < n Then Komb pos + 1, sum, False, s Komb pos + 1, sum, True, s End If If sum = p Then R = R & s & " , " End Sub
Private Sub Form_Load() n = 5: p = 3 Komb 1, 0, False, "" Komb 1, 0, True, "" MsgBox R End Sub
Hvis du hellere vil have kombinationerne gemt i en tabel (array) er det let at ændre programmet. Nedenfor viser jeg om lidt et eksempel på en ikke rekursiv løsning. Det er en rigtig grim løsning, og det er besværligt at lave den om, så den også virker for store værdier af n og p.
'Dette program lister alle kombinationer, hvor p tegn udtages 'fra n tegn 'Tegnene er bogstaverne ABCDE... 'Nedenstående program virker kun fo n<=6 og p<=6, 'men det kan let udvides. Der skal blot tilføjes flere 'for-løkker og tilsvarende variable i7, i8,... 'Det er altså et rigtigt grimte program
Option Explicit Dim K(6) As Byte
Sub TilPas(n As Byte) Dim i As Byte For i = 1 To n K(i) = 1 Next End Sub
Private Sub Form_Load() Dim i1 As Byte, i2 As Byte, i3 As Byte Dim i4 As Byte, i5 As Byte, i6 As Byte Dim n As Byte, p As Byte Dim R As String n = 5: p = 3 TilPas n For i1 = 0 To K(1) For i2 = 0 To K(2) For i3 = 0 To K(3) For i4 = 0 To K(4) For i5 = 0 To K(5) For i6 = 0 To K(6) If i1 + i2 + i3 + i4 + i5 + i6 = p Then If i1 = 1 Then R = R & "A" If i2 = 1 Then R = R & "B" If i3 = 1 Then R = R & "C" If i4 = 1 Then R = R & "D" If i5 = 1 Then R = R & "E" If i6 = 1 Then R = R & "G" R = R & " , " End If Next Next Next Next Next Next MsgBox R End Sub
Hvis du vil have gemt kombinationerne i en tabel gøres det lettest således:
Private Sub Form_Load() Dim A Dim q as Byte n = 5: p = 3 Komb 1, 0, False, "" Komb 1, 0, True, "" MsgBox R A = Split(R,",") 'Øvre grænse for A findes således: 'Det sidste element i A er en tom streng, på grund af 'kommaet tilsidst. Her er lidt der bør ændres. q = UBound(A) End Sub
Option Explicit Dim n As Byte, p As Byte, R As String Const Tegn = "ABCDEFGHIJKLMNO" Sub Komb(ByVal pos As Byte, ByVal sum As Byte, med As Boolean, ByVal s As String) If med Then s = s & Mid(Tegn, pos, 1): sum = sum + 1 End If If sum < p And pos < n Then Komb pos + 1, sum, False, s Komb pos + 1, sum, True, s End If If sum = p Then R = R & s & " , " End Sub
Private Sub Form_Load() n = 5: p = 3 Komb 1, 0, False, "" Komb 1, 0, True, "" MsgBox R End Sub
Kan denne kode også bruges, hvis hvert tal godt må bruges 2 eller flere gange? Ved godt at der nok ville komme en del mere output, men vil du isåfald ikke skrive koden? plz!
therichman--> Så skal du lige definere hvad det er du vil have listet. Mener du at vi har et tegnsæt med n tegn og det så blot gælder om at lave ord med p af tegnene. SKal vi tage hensyn til rækkefølgen? Når man taler om kombinationer er ABC og CBA jo det samme.
therichman-->Jeg forslår, at du opretter et helt nyt spørgsmål med den nye problemstilling. Hvis n=4 og p=3 sår er det så sekvenser af form AAA, AAB, BCD,ABB, CCC, DDD, ADD,... du vil have listet?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.