Ich habe gerade ein Bild bekommen ... Das Bild unten aus meinem Spiel zeigt einige abgedunkelte Blöcke, die als Teil einer "T" -Form erkannt wurden. Wie zu sehen ist, hat der Code die Blöcke mit den roten Punkten abgedunkelt und die "T" -Formen mit den grünen Umrissen nicht gesehen.
Mein Code durchläuft x / y, markiert Blöcke als verwendet, dreht die Form, wiederholt, ändert die Farbe, wiederholt.
Ich habe versucht, diese Überprüfung mit großer Besorgnis zu beheben. Die aktuelle Idee ist:
- Durchlaufen Sie das Raster, notieren Sie sich alle Mustervorkommen (markieren Sie die Blöcke NICHT als verwendet) und fügen Sie diese einem Array hinzu
- Durchlaufen Sie das Raster erneut und notieren Sie diesmal, welche Blöcke von welchen Mustern und daher welche von mehreren Mustern belegt sind.
- Sie durchlaufen erneut das Raster und stellen diesmal fest, welche Muster welche Muster behindern
So viel fühlt sich richtig an ... Was mache ich jetzt?
Ich denke ich müsste
- Probieren Sie verschiedene Kombinationen widersprüchlicher Formen aus, beginnend mit denen, die zuerst die meisten anderen Muster behindern. Wie gehe ich mit diesem um?
- Verwenden Sie das Rationale, das besagt, dass ich 3 widersprüchliche Formen habe, die 8 Blöcke belegen, und die Formen sind jeweils 4 Blöcke, daher kann ich nur maximal zwei Formen haben.
(Ich beabsichtige auch, andere Formen einzubeziehen, und es wird wahrscheinlich eine Punktgewichtung geben, die berücksichtigt werden muss, wenn die widersprüchlichen Formen durchlaufen werden, aber das kann ein anderer Tag sein.)
Ich glaube nicht, dass es ein Problem beim Verpacken von Behältern ist, aber ich bin mir nicht sicher, wonach ich suchen soll. Hoffe das macht Sinn, danke für deine Hilfe
BEARBEITEN Trotz der Klarheit der Frage scheint jeder verstanden zu haben, ja,
Ich möchte die maximalen "T" -Formen in jeder Farbe finden
(denn wenn ich dir Punkte für zwei geben würde und du drei gemacht hättest, wärst du ein bisschen verärgert)
Antworten:
Lassen Sie mich sehen, ob ich es richtig verstanden habe, die rot markierten Blöcke waren blau und der Algorithmus hat eine T-Form gefunden und sie rot markiert. Ist das richtig? Ihr Ziel ist es, so viele T-Formen wie möglich mit gleichfarbigen Blöcken zu finden, wie ich hoffe, bis jetzt richtig. Derzeit markieren Sie sie, sobald Sie sie gefunden haben, und dies verringert die Nützlichkeit des Algorithmus (da Ihnen möglicherweise die optimale Lösung fehlt). Sie planen, nach allen Formen zu suchen und dann auszuwählen, welche verwendet werden sollen und welche nicht. Bin ich soweit richtig? Denn Sie möchten die Anzahl der Blöcke maximieren, die in den T-Formen enthalten sind, wenn der Algorithmus fertig ist.
Wenn ich richtig liege, ist das Folgende meiner Meinung nach die optimale Lösung für Ihre Situation.
Wir werden Integer Linear Programming verwenden.
Ich glaube, ich habe diesen in der Vergangenheit benutzt:
http://sourceforge.net/projects/lpsolve/
http://lpsolve.sourceforge.net/5.5/Java/README.html
(Sie können es mit vielen Sprachen zum Laufen bringen, ich habe es mit PHP, Java und C verwendet)
Wir registrieren jede mögliche T-Form auf der Platine und verwenden dann ILP, um die Anzahl der abgedeckten Blöcke zu maximieren. ILP ist exponentiell komplex. Angesichts der Größe Ihres Boards ist dies kein Problem. Ich habe mit ILP viel kompliziertere Min / Max-Fragen zu Diagrammen gestellt und es dauerte nur einen Bruchteil einer Sekunde, bis sie abgeschlossen waren, und bis zu 30-90 Sekunden mit Hunderten von Eckpunkten (in Ihrem Fall fällt sie in den Bruchteil einer Sekunde).
Was ich empfehlen würde:
0 <= Bi <= 1
) Da die Werte Ganzzahlen sind, bleibt 0 oder 1 übrig.Bi + Bj <= 1
)Das ist wertvolles Wissen, ich habe oft lineare Löser für Arbeitsprojekte verwendet.
ILP ist im Grunde eine Möglichkeit, Auswahlprobleme zu lösen, bei denen Sie für eine lineare Funktion ein Maximum oder ein Minimum erreichen möchten.
Weitere Informationen finden Sie hier. Die Verwendung der linearen Ganzzahlprogrammierung und der linearen Programmierung ist für den Programmierer gleich, nur dass die Ganzzahl für den Computer weitaus komplexer ist, was zu langen Laufzeiten führen kann. Nicht in Ihrem Fall, es ist sehr einfach und sollte im schlimmsten Fall nur weniger als Millisekunden dauern.
Ich denke, Sie könnten hier mehr lesen:
http://en.wikipedia.org/wiki/Integer_linear_programming#Integer_unknowns
Das erklärt es gut:
http://fisher.osu.edu/~croxton_4/tutorial/
Es ist im Grunde ein Entscheidungsproblemlöser, wie man Entscheidungen trifft, die das gewünschte Ergebnis maximieren. Dies setzt voraus, dass die Funktion, die das Ergebnis beurteilt, linear ist, wie es in Ihrem speziellen aktuellen Fall der Fall ist. Die Funktion, die in diesem Fall das Ergebnis beurteilt, fasst die Blöcke für alle T-Formen zusammen, die Sie abdunkeln möchten.
Mathematisch, wie man die Variablen setzt: In unserem aktuellen Fall Boolesche Werte (Habe ich die T-Form mit dem Index i abgedunkelt oder nicht) auf die optimalen Werte, um das gewünschte Ergebnis zu maximieren: Verdunkeln Sie so viele Blöcke wie möglich, ohne sich überschneidende T-Formen abzudunkeln. Solange das gewünschte Ergebnis mit einer linearen Funktion berechnet werden kann, wenn Sie alle Variablen festgelegt haben, wird es gelöst. In unserem Fall prüfen wir, welche T-Formen wir abgedunkelt haben, und addieren die Blöcke, die sie abdecken.
Ich weiß, dass dies nicht trivial ist. Wenn Sie sich also für den Sprung entscheiden, können Sie dies gerne kommentieren, und ich werde darauf näher eingehen.
quelle
Sobald Sie eine Liste aller (möglicherweise überlappenden) T-Formen in Ihrem Raster haben, bleibt Ihnen ein maximales Problem beim Packen .
Im Allgemeinen ist dies ein NP-vollständiges Problem. Ihr Raster ist jedoch klein genug (und zerfällt normalerweise in noch kleinere unabhängige Teilprobleme), sodass es durchaus möglich sein kann, genaue Lösungen zu erhalten.
Nachtrag: Hier ist ein grundlegender Backtracking-Suchalgorithmus, der den Trick machen könnte:
Hier
{X, Y, Z}
bezeichnet die Menge, die die Elemente enthältX
,Y
undZ
({}
wobei die leere Menge ist) und|Q|
bezeichnet die Größe der MengeQ
.In der rekursiven Funktion
A
enthält die Menge die Formen, die für die verbleibende Lösung verfügbar sind,S
enthält die Formen im aktuellen Lösungskandidaten undM
ist die bisherige maximale Lösung (die Sie möglicherweise als globale Variable speichern möchten, anstatt sie zurückzusenden Anrufkette). Die wichtige Optimierung befindet sich in der mit gekennzeichneten Zeile// upper bound
, die Zweige des Suchbaums beschneidet, die möglicherweise keine bessere Lösung als zurückgeben könnenM
.(Da wir wissen, dass jede T-Form genau vier Stellen enthält, könnte eine viel bessere Obergrenze erhalten werden, indem
|B|
durch die Anzahl der verschiedenen Stellen ersetzt wird, die von den Formen in abgedecktB
, durch vier geteilt und abgerundet werden (und ähnlich für|A|
die Linie markiert mit// shortcut
). Der oben angegebene Algorithmus funktioniert jedoch für beliebige Formensammlungen.)Eine mögliche zusätzliche Optimierung, die ich oben nicht implementiert habe, besteht darin, zu Beginn der rekursiven Funktion zu überprüfen, ob sie
A
sich in mehrere unabhängige Teilmengen aufteilt, in dem Sinne, dass sich keine Formen in verschiedenen Teilmengen überlappen, und wenn ja, die anzuwenden Algorithmus für jede der Teilmengen separat. (In jedem Fall sollten Sie dies auf jeden Fall mindestens einmal auf der obersten Ebene tun, bevor Sie den rekursiven Algorithmus aufrufen.) DasA
geeignete Sortieren der Formen vor dem Schleifen, z. B. in aufsteigender Reihenfolge nach Anzahl der überlappenden Formen, kann ebenfalls hilfreich sein .quelle