Avatar billede vestre Nybegynder
18. marts 2008 - 13:27 Der er 10 kommentarer og
2 løsninger

Udregning af kombinationer

I forbindelse med et projekt har jeg behov for en funktion som kan finde alle kombinationer af et problem.
Problemet skal forståes på den måde at man f.eks. har et rør som er 300 cm langt. Jeg er interesseret i at få skrevet en kode som selv kan finde alle de mulige kombinationer som opstår hvis man vil skære røret op i længder af: 40, 80, 110, 130, 150, 180, 210 cm.

Altså - man kan f.eks. skære
7 stykker på 40 cm
6 styker på 40 cm
5 stykker på 40 cm og et stykke på 80 cm
4 stykker på 40 cm og to stykker på 80 cm
......
Listen bliver hurtig lang og ville derfor gerne, hvis nogen kunne hjælpe med at skrive en kode som kunne regne det for mig.

På forhånd tak:)
Avatar billede nielle Nybegynder
18. marts 2008 - 19:00 #1
Godt nok i VB.NET, men mon ikke du kan tilpasse det til VB?

        Dim maksLen As Integer = 300
        Dim totalLen As Integer

        Dim antal40 As Integer = 0
        While antal40 * 40 <= maksLen

            Dim antal80 As Integer = 0
            While antal80 * 80 <= maksLen

                Dim antal110 As Integer = 0
                While antal110 * 110 <= maksLen

                    Dim antal130 As Integer = 0
                    While antal130 * 130 <= maksLen

                        Dim antal150 As Integer = 0
                        While antal150 * 150 <= maksLen

                            Dim antal180 As Integer = 0
                            While antal180 * 180 <= maksLen

                                Dim antal210 As Integer = 0
                                While antal210 * 210 <= maksLen
                                    totalLen = antal40 * 40 + antal80 * 80 + antal110 * 110 + antal130 * 130 + antal150 * 150 + antal180 * 180 + antal210 * 210

                                    If totalLen <= maksLen Then
                                        If antal40 <> 0 Then Console.Write(antal40 & " stk. á 40 cm, ")
                                        If antal80 <> 0 Then Console.Write(antal80 & " stk. á 80 cm, ")
                                        If antal110 <> 0 Then Console.Write(antal110 & " stk. á 110 cm, ")
                                        If antal130 <> 0 Then Console.Write(antal130 & " stk. á 130 cm, ")
                                        If antal150 <> 0 Then Console.Write(antal150 & " stk. á 150 cm, ")
                                        If antal180 <> 0 Then Console.Write(antal180 & " stk. á 180 cm, ")
                                        If antal210 <> 0 Then Console.Write(antal210 & " stk. á 210 cm, ")

                                        Console.WriteLine("")
                                    End If

                                    antal210 = antal210 + 1
                                End While

                                antal180 = antal180 + 1
                            End While

                            antal150 = antal150 + 1
                        End While

                        antal130 = antal130 + 1
                    End While

                    antal110 = antal110 + 1
                End While

                antal80 = antal80 + 1
            End While

            antal40 = antal40 + 1
        End While
Avatar billede vestre Nybegynder
18. marts 2008 - 20:51 #2
Tak for svaret.

Jeg kunne godt tænke mig at have det sat op i excel, men jeg er ikke helt sikker på hvordan jeg lige gør det. Outputtet skulle gerne komme til at se sådan her ud:

    |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |
__________________________________________________________
210 |  1  |  1  |  1  |  1  |  0  |  0  |  0  |  0  |  0  |
180 |  0  |  0  |  0  |  0  |  1  |  1  |  1  |  1  |  1  |
150 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
130 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
110 |  0  |  0  |  0  |  0  |  1  |  0  |  0  |  0  |  0  |
080 |  1  |  0  |  0  |  0  |  0  |  1  |  1  |  0  |  0  |
040 |  0  |  2  |  1  |  0  |  0  |  1  |  0  |  3  |  2  |

Det skal forståes sådan at:
kolonne 1 viser at et rør kan skæres i 1 stk af 210 og 1 stk af 80 (spild på 10)
kolonne 2: 1 stk på 210 og 2 stk på 40 (samt spild på 10)
kolonne 3: 1 stk på 210 og 1 stk på 40 (samt spild på 50)

Hvordan får jeg lavet den løkke, som først udfylder kolonne 1 og derefter kolonne 2, samtidig med at jeg sikrer at alle løsninger er forskellige?
Avatar billede nielle Nybegynder
18. marts 2008 - 21:12 #3
Beklager ... den kan jeg ikke lige hjælpe dig med.
Avatar billede supertekst Ekspert
18. marts 2008 - 23:43 #4
Forslag - med basis i "nielles" forslag:

Dim kol
Private Sub opskæring()
    maksLen = 300
    antal40 = 0
    kol = 1
   
    While antal40 * 40 <= maksLen
        antal80 = 0
        While antal80 * 80 <= maksLen
            antal110 = 0
            While antal110 * 110 <= maksLen
                antal130 = 0
                While antal130 * 130 <= maksLen
                    antal150 = 0
                    While antal150 * 150 <= maksLen
                        antal180 = 0
                        While antal180 * 180 <= maksLen
                            antal210 = 0
                            While antal210 * 210 <= maksLen
                                totalLen = antal40 * 40 + antal80 * 80 + antal110 * 110 + antal130 * 130 + antal150 * 150 + antal180 * 180 + antal210 * 210

                                    If totalLen <= maksLen Then
                                        If antal40 <> 0 Then indsæt antal40, 7, kol
                                        If antal80 <> 0 Then indsæt antal80, 6, kol
                                        If antal110 <> 0 Then indsæt antal110, 5, kol
                                        If antal130 <> 0 Then indsæt antal130, 4, kol
                                        If antal150 <> 0 Then indsæt antal150, 3, kol
                                        If antal180 <> 0 Then indsæt antal180, 2, kol
                                        If antal210 <> 0 Then indsæt antal210, 1, kol

                                        kol = kol + 1
                                    End If
                                    antal210 = antal210 + 1
                                Wend
                                antal180 = antal180 + 1
                            Wend
                            antal150 = antal150 + 1
                        Wend
                        antal130 = antal130 + 1
                    Wend
                    antal110 = antal110 + 1
                Wend
                antal80 = antal80 + 1
            Wend
            antal40 = antal40 + 1
        Wend
       
    Columns.AutoFit
End Sub
Private Sub indsæt(antal, ræk, kol)
    Cells(ræk, kol) = antal
End Sub
Avatar billede supertekst Ekspert
18. marts 2008 - 23:45 #5
PS: indsæt koden i f.eks. Ark1 (højreklik herpå - Vis programkode)
Avatar billede vestre Nybegynder
19. marts 2008 - 07:51 #6
I er simpelthen for seje! Tusind tak! Hvordan giver jeg jer point?
Avatar billede supertekst Ekspert
19. marts 2008 - 08:29 #7
Du skal have et svar fra begge og herefter skal du acceptere svarene - du kan jo så selv afgøre points-fordelingen.

Selv tak...
Avatar billede nielle Nybegynder
19. marts 2008 - 08:32 #8
Svar :^)
Avatar billede nielle Nybegynder
20. marts 2008 - 18:20 #9
Takker for point :^)
Avatar billede arne_v Ekspert
22. marts 2008 - 04:03 #10
Man kan undgå de nestede løkker med brug af rekursion.

Sub combisplit2(maxlen As Integer, lens As Variant, n() As Integer, curlen As Integer, start As Integer)
    Dim i As Integer
    Dim s As String
    If lens(0) > maxlen - curlen Then
        s = ""
        For i = 0 To UBound(lens)
            s = s & " " & n(i)
        Next
        MsgBox s
    Else
        i = start
        While i <= UBound(lens)
            If lens(i) <= maxlen - curlen Then
                n(i) = n(i) + 1
                Call combisplit2(maxlen, lens, n, curlen + lens(i), i)
                n(i) = n(i) - 1
            End If
            i = i + 1
        Wend
    End If
End Sub

Sub combisplit(maxlen As Integer, lens As Variant)
    Dim n() As Integer
    ReDim n(UBound(lens))
    Call combisplit2(maxlen, lens, n, 0, 0)
End Sub

Sub test()
    Call combisplit(300, Array(40, 80, 110, 130, 150, 180, 210))
End Sub
Avatar billede vestre Nybegynder
29. marts 2008 - 14:15 #11
Hvordan ville man skulle skrive koden så man ikke var låst af den syv længder. Altså så den trækker input fra en række og det er lige meget om det er for syv, to eller andre kombinationer af længder. Tænker på, hvordan det kan laves så brugerfladen i excel bliver bedre - så man ikke hele tiden skal være i macroen hvis det ikke lige er syv længder.
Avatar billede arne_v Ekspert
29. marts 2008 - 17:08 #12
Jeg har angivet den rekursive algoritme det kan klare det.

Der mangler kun lidt integration med Excel (kan muligvis være sværere end man umiddelbart
skulle tro).
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester