Deutsch
Experimente

Job-Scheduler Nr.2: Ungarische Methode - Kuhn-Munkres-Algorithmus Demo

 

p.specht

Zur kostenoptimalen Aufgabenzuordnung zwischen Lieferfirmen, Handwerkern u.dgl. wird oft aus der sog. Ganzzahligen Optimierung ein Spezialfall des bekannten Simplex-Algorithmus verwendet. Zugrundeliegende Fragestellung: N Personen (z.B. Handwerker) sind zu N Jobs 1:1 zuzuordnen - und zwar so, daß die Arbeiten Gesamtkostenoptimal ausgeführt werden. Eine Kostenmatrix (z.B. aus Angeboten der Handwerker) liegt vor.
Bei 3 Personen: Ein Blick genügt! 4?: Nach näherer Betrachtung kommt man händisch rasch auf eine Lösung. 5?: Das kann dauern... nun kommt der PC ins Spiel: 10? 20? 50? Anbei eine Quick-n'-dirty-Transposition aus Fortran. Achtung, reine Demo, da Rechtslage ungeklärt!
Windowtitle upper$("  "+"ACM TOMS: Ungarische Methode (Kostenminimale 1:1-Zuordnung finden)")
' (D) Demo-Transposition 07-2013 aus Fortran77 nach XProfan11.2a by P. Specht, Wien
' Q: https://www.netlib.org/toms/548   <<< Es bestehen wahrscheinlich Rechte Dritter an ASSCT. KEINE WIE
' AUCH IMMER GEARTETE GEWÄHR! NUTZUNG NUR FÜR DEMONSTRATIONSZWECKE - STETS AUF GEFAHR DES ANWENDERS!
Windowstyle 1048:Window 0,0-%maxx,%maxy-40:var xm&=width(%hwnd):var ym&=height(%hwnd)
cls rgb(0,0,102):color 14,8:usepen 0,1,rgb(255,255,0):usebrush 1,rgb(255,255,0):randomize
var n&=40
declare A&[130,131], O&[130,131],i&,j&,t&,C&[131],sum!
Main:
ErzeugeTestwerte
zeig
ASSCT(n&,a&[])
zeig
print:print t&
waitinput
zeigloesg
print sum!
waitinput
end

proc ErzeugeTestwerte

    whileloop 1,n&:i&=&Loop

        whileloop 1,n&:j&=&Loop

            a&[i&,j&]=rnd(1000)
            o&[i&,j&]=a&[i&,j&]

        endwhile

    endwhile

endproc

proc linie

    print mkstr$("-",7*if(n&<24,n&,23)+7)+"\n"

endproc

proc show

    whileloop if(n&<24,n&,23):i&=&Loop'Alle Zeilen

        whileloop if(n&<24,n&,23):j&=&Loop'in jeder Spalte

            print tab(7*j&);int(a&[i&,j&]),
            endwhile :print:print

        endwhile

        linie

    endproc

    proc zeig

        cls rgb(0,0,102):linie:show:waitinput

    endproc

    proc zeigloesg

        cls rgb(0,0,102):linie
        sum!=0

        whileloop n&:j&=&Loop'in jeder Spalte

            sum!=sum!+o&[c&[j&],j&]
            print j&;"=";c&[j&];":";int(o&[c&[j&],j&]),
            case %pos>80:print
            endwhile :print:print
            linie

        endproc

        PROC ASSCT :parameters N&,A&[]

            declare CH&[130],LC&[130],LR&[130],LZ&[130],NZ&[130],RH&[131],SLC&[130],SLR&[130],U&[131]
            declare H&, Q&, R&, S&, K&, LJ&, LM&, M&, NL&, NM&
            ' EQUIVALENCE (LZ[],RH[]), (NZ[],CH[])
            '
            ' THIS SUBROUTINE SOLVES THE SQUARE ASSIGNMENT PROBLEM
            ' THE MEANING OF THE INPUT PARAMETERS IS
            ' N = NUMBER OF ROWS AND COLUMNS OF THE COST MATRIX, WITH
            '     THE CURRENT DIMENSIONS THE MAXIMUM VALUE OF N IS 130
            ' A(I,J) = ELEMENT IN ROW I AND COLUMN J OF THE COST MATRIX
            ' ( AT THE END OF COMPUTATION THE ELEMENTS OF A ARE CHANGED)
            ' THE MEANING OF THE OUTPUT PARAMETERS IS
            ' C(J) = ROW ASSIGNED TO COLUMN J (J=1,N)
            ' T = COST OF THE OPTIMAL ASSIGNMENT
            ' ALL PARAMETERS ARE INTEGER
            ' THE MEANING OF THE LOCAL VARIABLES IS
            ' A(I,J) = ELEMENT OF THE COST MATRIX IF A(I,J) IS POSITIVE,
            '          COLUMN OF THE UNASSIGNED ZERO FOLLOWING IN ROW I
            '          (I=1,N) THE UNASSIGNED ZERO OF COLUMN J (J=1,N)
            '          IF A(I,J) IS NOT POSITIVE
            ' A(I,N+1) = COLUMN OF THE FIRST UNASSIGNED ZERO OF ROW I
            '            (I=1,N)
            ' CH(I) = COLUMN OF THE NEXT UNEXPLORED AND UNASSIGNED ZERO
            '         OF ROW I (I=1,N)
            ' LC(J) = LABEL OF COLUMN J (J=1,N)
            ' LR(I) = LABEL OF ROW I (I=1,N)
            ' LZ(I) = COLUMN OF THE LAST UNASSIGNED ZERO OF ROW I(I=1,N)
            ' NZ(I) = COLUMN OF THE NEXT UNASSIGNED ZERO OF ROW I(I=1,N)
            ' RH(I) = UNEXPLORED ROW FOLLOWING THE UNEXPLORED ROW I
            '         (I=1,N)
            ' RH(N+1) = FIRST UNEXPLORED ROW
            ' SLC(K) = K-TH ELEMENT CONTAINED IN THE SET OF THE LABELLED
            '          COLUMNS
            ' SLR(K) = K-TH ELEMENT CONTAINED IN THE SET OF THE LABELLED
            '          ROWS
            ' U(I) = UNASSIGNED ROW FOLLOWING THE UNASSIGNED ROW I
            '        (I=1,N)
            ' U(N+1) = FIRST UNASSIGNED ROW
            '
            ' THE VECTORS C,CH,LC,LR,LZ,NZ,SLC,SLR MUST BE DIMENSIONED
            ' AT LEAST AT (N), THE VECTORS RH,U AT  LEAST AT (N+1),
            ' THE MATRIX A AT LEAST AT (N,N+1)
            '
            ' INITIALIZATION
            declare maxnum&,np1&,J&,I&,L&,KSLC&,KSLR&
            MAXNUM& = 2^31-1
            NP1& = N&+1
            ' DO 10 J=1,N

            whileloop 1,n&:J&=&Loop

                C&[J&] = 0
                LZ&[J&] = 0
                NZ&[J&] = 0
                U&[J&] = 0
                '10 CONTINUE

            endwhile

            U&[NP1&] = 0
            T& = 0
            ' REDUCTION OF THE INITIAL COST MATRIX
            'DO 40 J=1,N

            whileloop 1,n&:J&=&Loop

                S& = A&[1,J&]
                'DO 20 L=2,N

                whileloop 2,n&:L&=&Loop

                    Case ( A&[L&,J&] < S& ) S& = A&[L&,J&]
                    '20  CONTINUE

                endwhile

                T& = T&+S&
                'DO 30 I=1,N

                whileloop 1,n&:i&=&Loop

                    A&[I&,J&] = A&[I&,J&]-S&
                    '30  CONTINUE

                endwhile

                '40 CONTINUE

            endwhile

            'DO 70 I=1,N

            whileloop 1,n&:i&=&Loop

                Q& = A&[I&,1]
                'DO 50 L=2,N

                whileloop 2,n&:L&=&Loop

                    Case ( A&[I&,L&] < Q& ):Q& = A&[I&,L&]
                    '50   CONTINUE

                endwhile

                T& = T&+Q&
                L& = NP1&
                'DO 60 J=1,N

                whileloop 1,n&:J&=&Loop

                    A&[I&,J&] = A&[I&,J&]-Q&
                    Case ( A&[I&,J&] <> 0 ):GOTO "L60"
                    A&[I&,L&] = -J&
                    L& = J&
                    L60:
                    'CONTINUE

                endwhile

                '70 CONTINUE

            endwhile

            ' CHOICE OF THE INITIAL SOLUTION
            K& = NP1&
            'DO 140 I=1,N

            whileloop 1,n&:i&=&Loop

                LJ& = NP1&
                J& = -1*A&[I&,NP1&]
                L80:
                Case ( C&[J&] = 0 ):GOTO "L130"
                LJ& = J&
                J& = -1*A&[I&,J&]
                Case ( J& <> 0 ):GOTO "L80"
                LJ& = NP1&
                J& = -1*A&[I&,NP1&]
                L90:
                R& = C&[J&]
                LM& = LZ&[R&]
                M& = NZ&[R&]
                L100:
                Case ( M& = 0 ):GOTO "L110"
                Case ( C&[M&] = 0 ):GOTO "L120"
                LM& = M&
                M& = -1*A&[R&,M&]
                GOTO "L100"
                L110:
                LJ& = J&
                J& = -1*A&[I&,J&]
                Case ( J& <> 0 ):GOTO "L90"
                U&[K&] = I&
                K& = I&
                GOTO "L140"
                L120:
                NZ&[R&] = -1*A&[R&,M&]
                LZ&[R&] = J&
                A&[R&,LM&] = -J&
                A&[R&,J&] = A&[R&,M&]
                A&[R&,M&] = 0
                C&[M&] = R&
                L130:
                C&[J&] = I&
                A&[I&,LJ&] = A&[I&,J&]
                NZ&[I&] = -1*A&[I&,J&]
                LZ&[I&] = LJ&
                A&[I&,J&] = 0
                L140:
                '140 CONTINUE

            endwhile

            ' RESEARCH OF A NEW ASSIGNMENT
            L150:
            Case ( U&[NP1&] = 0 ): RETURN
            'DO 160 I=1,N

            whileloop 1,n&:i&=&Loop

                CH&[I&] = 0
                LC&[I&] = 0
                LR&[I&] = 0
                RH&[I&] = 0
                '160 CONTINUE

            endwhile

            RH&[NP1&] = -1
            KSLC& = 0
            KSLR& = 1
            R& = U&[NP1&]
            LR&[R&] = -1
            SLR&[1] = R&
            Case ( A&[R&,NP1&] = 0 ):GOTO "L220"
            L170:
            L& = -1*A&[R&,NP1&]
            Case ( A&[R&,L&] = 0 ):GOTO "L180"
            Case ( RH&[R&] <> 0 ):GOTO "L180"
            RH&[R&] = RH&[NP1&]
            CH&[R&] = -1*A&[R&,L&]
            RH&[NP1&] = R&
            L180:
            Case ( LC&[L&] = 0 ):GOTO "L200"
            Case ( RH&[R&] = 0 ):GOTO "L210"
            L190:
            L& = CH&[R&]
            CH&[R&] = -1*A&[R&,L&]
            Case ( A&[R&,L&] <> 0 ):GOTO "L180"
            RH&[NP1&] = RH&[R&]
            RH&[R&] = 0
            GOTO "L180"
            L200:
            LC&[L&] = R&
            Case ( C&[L&] = 0 ):GOTO "L360"
            KSLC& = KSLC&+1
            SLC&[KSLC&] = L&
            R& = C&[L&]
            LR&[R&] = L&
            KSLR& = KSLR&+1
            SLR&[KSLR&] = R&
            Case ( A&[R&,NP1&] <> 0 ):GOTO "L170"
            L210:
            'CONTINUE  '??????????????????????????????????????????????????????????
            Case ( RH&[NP1&] > 0 ):GOTO "L350"
            ' REDUCTION OF THE CURRENT COST MATRIX
            L220:
            H& = MAXNUM&
            'DO 240 J=1,N

            whileloop 1,n&:J&=&Loop

                Case ( LC&[J&] <> 0 ) :GOTO "L240"
                'DO 230 K=1,KSLR

                whileloop 1,kslr&:k&=&Loop

                    I& = SLR&[K&]
                    Case ( A&[I&,J&] < H& ): H& = A&[I&,J&]
                    '230   CONTINUE

                endwhile

                L240:
                'CONTINUE

            endwhile

            T& = T&+H&
            'DO 290 J=1,N

            whileloop 1,n&:J&=&Loop

                Case ( LC&[J&] <> 0 ):GOTO "L290"
                'DO 280 K=1,KSLR

                whileloop 1,kslr&:k&=&Loop

                    I& = SLR&[K&]
                    A&[I&,J&] = A&[I&,J&]-H&
                    Case ( A&[I&,J&] <> 0 ):GOTO "L280"
                    Case ( RH&[I&] <> 0 ):GOTO "L250"
                    RH&[I&] = RH&[NP1&]
                    CH&[I&] = J&
                    RH&[NP1&] = I&
                    L250:
                    L& = NP1&
                    L260:
                    NL& = -1*A&[I&,L&]
                    Case ( NL& = 0 ):GOTO "L270"
                    L& = NL&
                    GOTO "L260"
                    L270:
                    A&[I&,L&] = -J&
                    L280:
                    'CONTINUE

                endwhile

                L290:
                'CONTINUE

            endwhile

            Case ( KSLC& = 0 ):GOTO "L350"
            'DO 340 I=1,N

            whileloop 1,n&:i&=&Loop

                Case ( LR&[I&] <> 0 ) :GOTO "L340"
                'DO 330 K=1,KSLC

                whileloop 1,kslc&:k&=&Loop

                    J& = SLC&[K&]
                    Case ( A&[I&,J&] > 0 ):GOTO "L320"
                    L& = NP1&
                    L300:
                    NL& = -1*A&[I&,L&]
                    Case ( NL& = J& ):GOTO "L310"
                    L& = NL&
                    GOTO "L300"
                    L310:
                    A&[I&,L&] = A&[I&,J&]
                    A&[I&,J&] = H&
                    GOTO "L330"
                    L320:
                    A&[I&,J&] = A&[I&,J&]+H&
                    L330:
                    'CONTINUE

                endwhile

                L340:
                'CONTINUE

            endwhile

            L350:
            R& = RH&[NP1&]
            GOTO "L190"
            ' ASSIGNMENT OF A NEW ROW
            L360:
            C&[L&] = R&
            M& = NP1&
            L370:
            NM& = -1*A&[R&,M&]
            Case ( NM& = L& ):GOTO "L380"
            M& = NM&
            GOTO "L370"
            L380:
            A&[R&,M&] = A&[R&,L&]
            A&[R&,L&] = 0
            Case ( LR&[R&] < 0 ):GOTO "L390"
            L& = LR&[R&]
            A&[R&,L&] = A&[R&,NP1&]
            A&[R&,NP1&] = -L&
            R& = LC&[L&]
            GOTO "L360"
            L390:
            U&[NP1&] = U&[R&]
            U&[R&] = 0
            GOTO "L150"

        ENDPROC


P.S: Sollten mehr Jobs als Handwerker vorhanden sein, erfindet man ein paar sehr teure. Umgekehrt könnte man virtuelle Jobs erfinden, denn die Kostenmatrix sollte jedenfalls quadratisch sein! Maximieren kann man auch: Man zieht alle Matrixelemente zuvor vom größten Element ab!

PPS: Was ist bei 200 zuzuordnenden Elementen? Die Kombinatorik (Laufzeit!) explodiert hier mit der dritten oder gar vierten Potenz! Spätestens da wünscht man sich Assembler - und da kommt die alte Spaghettiprogrammierung von Fortran77 gerade recht, denn händisch optimierter Maschinencode sieht ja sehr ähnlich aus...
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'...
10.05.2021  
 



Zum Experiment


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

468 Betrachtungen

Unbenanntvor 0 min.
p.specht06.07.2022
Ernst21.07.2021
Uwe ''Pascal'' Niemeier13.06.2021
R.Schneider28.05.2021
Mehr...

Themeninformationen

Dieses Thema hat 1 Teilnehmer:

p.specht (1x)


Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie