2 Stimmen

Permutation/Algorithmus zur Lösung des Rätsels der bedingten Füllung

Ich habe mich umgesehen, um zu sehen, ob etwas Ähnliches schon einmal gemacht wurde, aber ich habe nichts mit gespiegelten Bedingungen gesehen. Um das Problem ein wenig verständlicher zu machen, werde ich es im Zusammenhang mit dem Auffüllen des Kaders einer Baseballmannschaft anwenden.

Die vorgegebene Dienstplanstruktur ist wie folgt aufgebaut: C, 1B, 2B, 3B, SS, 2B/SS (entweder oder), 1B/3B, OF, OF, OF, OF, UT (kann jede Position sein)

Jeder Spieler hat mindestens eine der Nicht-Backup-Positionen (Positionen, die mehr als eine Position zulassen), auf denen er wählbar ist, und in vielen Fällen mehr als eine (z. B. ein Spieler, der 1B und OF spielen kann, usw.). Nehmen wir an, Sie sind Manager eines Teams, das bereits einige Spieler hat, und Sie möchten sehen, ob Sie auf einer Ihrer Positionen Platz für einen bestimmten Spieler haben oder ob Sie einen oder mehrere Spieler versetzen können, um eine Position freizumachen, auf der er spielberechtigt ist.

Meine anfänglichen Versuche bestanden darin, eine bedingte Permutation zu verwenden und alle möglichen einzigartigen "Aufstellungen" für jeden Spieler in einer Liste zu sammeln und die offenen Plätze zu aktualisieren, bevor ich zum nächsten Spieler überging. Dies erforderte auch (da die Reihenfolge, in der der Spieler verschoben wurde, sich darauf auswirkte, welche Positionen für den nächsten Spieler verfügbar waren), dass die Liste, die in einer Schleife durchlaufen wurde, neu geordnet und dann erneut durchlaufen wurde. Ich bin immer noch der Meinung, dass dies der richtige Weg ist, aber es gibt eine Reihe von Fallstricken, an denen die Funktion hängen geblieben ist.

Die Daten zum Starten der Schleife, die Sie als gegeben annehmen, sind: 1. Liste der Positionen, die der ausgewertete Spieler einnehmen kann (derjenige, der geprüft wird, ob er passen kann) 2. Liste der Spieler, die derzeit im Dienstplan stehen, und die Positionen, für die jeder von ihnen in Frage kommt (ich speichere derzeit eine Liste von Listen und verwende den Listenindex als eindeutigen Bezeichner des Spielers) 3. Eine Liste der offenen Positionen, wie sie derzeit im Dienstplan stehen

Das hat mir mehr Kopfzerbrechen bereitet, als ich ursprünglich erwartet hatte. Ein Kollege schlug mir sogar vor, dass die Situation, die ich habe (die in viel größerem Umfang bedingte Zuweisungen für jedes Objekt beinhaltet) NP-komplett ist. Ich bin mir sicher, dass dies nicht der Fall ist, denn sobald ein Spieler in einer bestimmten Aufstellung, die getestet wird, neu positioniert wurde, sollte es nicht notwendig sein, den gesamten Dienstplan erneut zu iterieren, sobald ein anderer Spieler gewechselt hat. Das ist die Kurzfassung des Problems, und ich habe mich schließlich entschlossen, es in den Foren zu veröffentlichen.

Vielen Dank für jede Hilfe, die ich erhalten kann. Aufgrund von Beschränkungen kann ich keine Teile des Codes veröffentlichen (einige davon sind veraltet). Es wird jedoch in .NET (derzeit C#) übersetzt. Wenn zusätzliche Informationen erforderlich sind, werde ich versuchen, einige der kurzen Teile der Funktion neu zu schreiben und zu posten.

Joseph G.

BEARBEITET 07/24/2010 Herzlichen Dank für die Antworten. Ich habe tatsächlich die Verwendung eines genetischen Algorithmus in Erwägung gezogen, aber letztendlich verworfen, weil der Arbeitsaufwand für die Ermittlung der ordinalen Ergebnisse überflüssig war. Das eigentliche Ziel des Tests ist es, festzustellen, ob es tatsächlich ein Szenario gibt, das ein positives Ergebnis liefert. Es besteht keine Notwendigkeit, den relativen Nutzen jeder Arbeitslösung zu bestimmen.

Ich bin dankbar für die Rückmeldung, dass ich wahrscheinlich nicht mit dem Kontext vertraut bin, in dem ich das Problem dargestellt habe. Das eigentliche Modell besteht in der Verteilung von Build-Befehlen auf mehrere plattformspezifische Build-Server. Es ist zugänglich, aber ich möchte lieber nicht darauf eingehen, warum bestimmte Build-Aufgaben nur auf bestimmten Systemen ausgeführt werden können und warum bestimmte Systeme nur bestimmte Arten von Build-Befehlen ausführen können.

Es scheint, dass Sie das Wesentliche meiner Ausführungen verstanden haben, aber hier ist ein anderes Modell, das ein wenig weniger spezifisch ist. Es gibt eine Reihe von diskreten Positionen in einer geordneten Reihe von Listen (ich bezeichne sie als "Positionen"):

((2), (2), (3), (4), (5), (6), (4, 6), (3, 5), (7), (7), (7), (7), (7), (2, 3, 4, 5, 6, 7))

Außerdem gibt es ein ungeordnetes Listenfeld (ich nenne es "Mitarbeiter"), das nur dann einen der Plätze belegen kann, wenn sein Feld ein gemeinsames Mitglied mit der geordneten Liste hat, der es zugewiesen werden würde. Wenn nach den anfänglichen Zuweisungen ein zusätzlicher Mitarbeiter hinzukommt, muss ich feststellen, ob er eine der offenen Stellen besetzen kann, und wenn nicht, ob die aktuellen Mitarbeiter so umgeordnet werden können, dass eine der Stellen, die der Mitarbeiter besetzen KANN, verfügbar gemacht werden kann.

Brute Force möchte ich vermeiden, denn bei einer Größenordnung von 40 - 50 Objekten (und bald mehr) sind einzelne Festlegungen zur Laufzeit sehr aufwendig zu berechnen.

1voto

Tom Gullen Punkte 59095

Ich verstehe überhaupt nichts von Baseball, also entschuldigen Sie, wenn ich auf der falschen Fährte bin. Ich mag zwar Rounders, aber es gibt nur 2 Positionen, die man bei Rounders spielen kann, einen Batter oder alle anderen.

Haben Sie die Verwendung von Genetische Algorithmen um dieses Problem zu lösen? Sie sind sehr gut in der Lage, NP-schwere Probleme zu lösen, und funktionieren überraschend gut auch bei Problemen des Typs Dienstplan und Zeitplan.

Sie haben ein Lösungsmodell, das leicht bewertet und manipuliert werden kann, was ein guter Ausgangspunkt für einen genetischen Algorithmus ist.

Bei komplexeren Problemen, bei denen die Gesamtzahl der Permutationen zu groß ist, um sie zu berechnen, sollte ein genetischer Algorithmus in relativ kurzer Zeit eine nahezu optimale oder ausgezeichnete Lösung finden (zusammen mit einer Vielzahl anderer gültiger Lösungen). Wenn Sie jedoch jedes Mal die optimale Lösung finden wollen, müssen Sie aller Wahrscheinlichkeit nach mit roher Gewalt vorgehen (ich habe das Problem nur überflogen, so dass dies vielleicht nicht der Fall ist, aber es klingt so, als ob es wahrscheinlich ist).

In Ihrem Beispiel hätten Sie eine Lösungsklasse, die eine Lösung darstellt, z. B. eine Aufstellung für ein Baseballteam. Sie generieren nach dem Zufallsprinzip etwa 20 Lösungen, unabhängig davon, ob sie gültig sind oder nicht, und haben dann einen Rating-Algorithmus, der die Lösung bewertet. In Ihrem Fall würde ein besserer Spieler in der Aufstellung mehr Punkte erhalten als ein schlechterer Spieler, und alle ungültigen Aufstellungen (aus welchem Grund auch immer) würden eine Bewertung von 0 erzwingen.

Alle Lösungen mit 0 Punkten werden abgetötet und durch neue, zufällige Lösungen ersetzt, und die restlichen Lösungen bilden neue Lösungen. Theoretisch und nach genügend Zeit sollte sich der Pool an Lösungen verbessern.

Dies hat den Vorteil, dass Sie nicht nur viele gültige, einzigartige Aufstellungen finden, sondern diese auch bewerten können. Du hast in deinem Problem nicht angegeben, dass die Lösungen bewertet werden müssen, aber es bietet viele Vorteile (wenn zum Beispiel ein Spieler verletzt ist, kann er vorübergehend mit -10 oder so bewertet werden). Alle anderen Spieler werden auf der Grundlage ihrer quantifizierbaren Werte bewertet.

Sie ist skalierbar und leistungsfähig.

1voto

user382751 Punkte 1203

Es klingt, als hätten Sie ein zweiseitiges Zuordnungsproblem. Eine Partition hat einen Knoten für jeden Spieler auf dem Dienstplan. Die andere Partition hat einen Knoten für jede Position im Dienstplan. Es gibt eine Kante zwischen einem Spieler-Eckpunkt und einem Positions-Eckpunkt, wenn und nur wenn der Spieler diese Position spielen kann. Sie sind interessiert an Matchings Sammlungen von Kanten, so dass kein Endpunkt wiederholt wird.

Bei einer Zuordnung von Spielern zu Positionen (einem Matching) und einem neuen Spieler, der aufgenommen werden soll, gibt es einen einfachen Algorithmus, um festzustellen, ob dies möglich ist. Leite jede Kante im aktuellen Matching von der Position zum Spieler; leite die anderen vom Spieler zur Position. Suchen Sie nun mit Hilfe der Breadth-First-Suche nach einem Pfad von dem neuen Spieler zu einer nicht zugewiesenen Position. Wenn du einen findest, zeigt dir das eine mögliche Reihe von Neuzuweisungen an. Wenn Sie keinen finden, gibt es keine Übereinstimmung mit allen Spielern.

Angenommen, Spieler A kann die Positionen 1 oder 2 spielen

A--1
 \
  \
   2

Wir weisen A vorläufig 2 zu. Nun taucht B auf und kann nur 2 spielen. Richten Sie den Graphen aus:

A->1
 <
  \
B->2

Wir finden einen Weg B->2->A->1 was bedeutet: "B auf 2 setzen, A auf 1 verschieben".

Es gibt eine Menge schöner Theorien für den Umgang mit hypothetischen Übereinstimmungen. Genetische Algorithmen müssen nicht angewendet werden.


EDIT: Ich sollte hinzufügen, dass aufgrund der Verwendung von BFS die am wenigsten störende Abfolge von Neuzuweisungen berechnet wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X