MathHammer 2.0: Armeezusammenstellung als MILP

oder: Warum der SPAM! inhärent ist.

Hallo Zusammen,

in den letzten Tagen wurde ja viel über SPAM! diskutiert, ob er schlecht ist, ob er gut ist, wie er zu bekämpfen sei, oder dass man sich als Dirty-Casual mal nicht so anstellen sollte, denn der SPAM gehöre nunmal zu einem kompetitiven Spiel dazu. Die Sinnhaftigkeit dieser Diskussionen sei mal dahingestellt, aber sie haben mich zum denken angeregt. Viele haben ja gesagt SPAM! ist inhärent im System und man wird ihn nie wegbekommen. Kann man diese Behauptung beweisen? Oder zumindest überzeugende Argumente finden warum man ihr glauben sollte?

Als guter Ingenieur habe ich natürlich sofort versucht, das Problem zu abstrahieren und mir ein Gedankenmodell zu erstellen. Dabei ist folgendes herausgekommen:


  • Im Grunde ist die Armeezusammenstellung in meiner Vorstellung ein gemischt-ganzzahliges lineares Optimierungsproblem (Mixed-integer linear problem = MILP).
  • Die Optimierungsvariablen entsprechen der Anzahl der Instanzen eines Datasheets. Ich bezeichne sie im folgenden mit der Variable d.
  • Für die gewählten Datasheets werden die Power-Points aufsummiert. Diese Summe muss unter einem Limit bleiben.
  • Jedem Datasheet ist eine Battlefield-Role zugeordnet. Aus dem Produkt einer Mapping-Matrix und der Variable d erhält man die Anzahl von Units mit der jeweiligen Battlefield-Role in einer Armee. Dieser Vektor ist nach oben und unten durch die Detachments begrenzt. Im Beispiel habe ich einfach mal ein Battalion als Limit gesetzt.
  • Für jedes Datasheet gibt es eine abstrakte Effektivitätszahl. Momentan ist diese geraten, aber eigentlich ist sie eine Funktion des Datasheets, der Ausrüstung und des erwarteten Metagams (=den Szenarien). Lintu hat einige wunderbare Artikel über die Berechnung von Effektivitätszahlen für Einheiten veröffentlicht. Ich gehe hier erstmal davon aus, dass wir diese Zahlen irgendwoher bekommen können. Im Zweifel könnte man sogar Data-Mining betreiben, wenn man eine formale Repräsentation (=Codierung) der Armeelisten hätte, aber das führt hier zu weit.
  • Für jedes Datasheet gibt es noch weitere Beschränkungen in Form von oberen und unteren Schranken. Dies kann die vorhandenen Modell in der eigenen Sammlung oder besondere Turnierregeln darstellen (Highlander, Trippelung verboten, nur 1 Hive Tyrant pro Detachment ;-)
  • Ziel ist es, unter Variation der Anzahl von Instanzen für jedes Datasheet die summierte Effektivität der Armee zu maximieren, wobei das Punktelimit und die Detachment-Limitierung eingehalten werden.

Dieses sehr einfache lineare Modell zeigt dann auch wunderbar das übliche Verhalten bei Turnierlisten. Die beste Einheit jedes Slots wird bis zum Limit dupliziert, danach wird die zweitbeste Einheit ausgewählt, und so weiter, bis das Punktelimit erreicht wird. Dafür muss man auch eigentlich keine Berechnung ausführen, eine Betrachtung der Karush-Kuhn-Tucker Bedingungen der Zielfunktion wird für den linearen Fall das gleiche Ergebnis sagen: das Optimum liegt immer an den Randbedingungen. Wenn also ein Turnierspieler rational agiert wird er zu einem ähnlichen Ergebnis kommen. Natürlich wird jeder seine eigenen Effektivitätszahlen im Kopf haben (die ja Metagame-abhängig sind) und somit zu leicht anderen Zusammenstellungen kommen.

Warum hab ich das Ganze also durch exerziert? Zum einen, weil es mir Spaß gemacht hat das Thema einmal theoretisch zu modellieren. Zum anderen, weil ich die Idee habe, das Modell noch weiter zu verfeinern. Neben der einfachen linearen Effektivität könnte es einen bilinearen Term geben, der die Wechselwirkungen (=Synergien) zwischen zwei Einheiten bewertet. Ein Carnifex alleine ist vielleicht nicht so gut, aber mit Old-One-Eye in der Armee steigt seine Effektivität. Das gleiche gilt für die üblichen Buff-Charaktere wie Guilliman, Cawl, etc. Das Problem ist nun natürlich die Matrix mit Wechselwirkungsparametern zu füllen. Wie sehr verbessert ein Charakter denn jetzt eine Einheit? Im Grunde ist auch hier wieder Lintu gefragt, der das mit seinen probabilistischen Ansätzen sicher beantworten kann.
Eine weitere offensichtliche Erweiterung des Modells ist natürlich die Berücksichtigung von einzelnen Modellen und Ausrüstung, dann mit Matched-Play Punkten. Hierdurch wächst die Komplexität natürlich enorm, vor allem wenn man Wechselwirkungen zwischen Einheitenprofilen und Waffen berücksichtigen will (e.g. ein Melter ist auf einem Tau-Commander effektiver als auf einem Crisis-Suit).

Ich habe das Modell mit Hilfe der Software AMPL aufgestellt und gelöst. AMPL gibt es als kostenlose Demo-Version (mit reduziertem Umfang): https://ampl.com/try-ampl/download-a-free-demo/

Als letztes füge ich noch die drei Dateien an, die das Modell implementieren:
Gleichungen des Modells:
Code:
set Datasheets;
set Roles;

param P {j in Datasheets }; # Power point cost for datasheet
param K {j in Datasheets }; # Effectiveness/value of datasheet (=guess)

param LD {j in Datasheets}; # lowerbound for datasheet (= personal preference)
param UD {j in Datasheets}; # upperbound for datasheet (= available models in collection)

param LR {i in Roles};         # lowerbound for battlefield role, taken from detachments
param UR {i in Roles};         # upperbound for battlefield role, taken from detachments

param Map {j in Datasheets, i in Roles}; # Which datasheet has which battlefield role

var d {j in Datasheets} integer >=0, <= 10; # How many instances of each datasheet does the army have
var s {i in Roles } >=0;             # How many datasheets of each role does the army have

var p1;                             # power point cost for the selected units
var pTotal;                         # total power point cost for the army


maximize Effectiveness: sum { j in Datasheets } K[j]*d[j];

subject to UnitPoints: p1 = sum { j in Datasheets } P[j]*d[j];
subject to Points: pTotal = p1;
subject to P_limit: 0 <= pTotal <= 100;

subject to DatasheetLimits {j in Datasheets}: LD[j] <= d[j] <=UD[j];

subject to BattlefieldRoles1 {i in Roles}: s[i] = sum { j in Datasheets } Map[j,i]*d[j];
subject to BattlefieldRoles2 {i in Roles}: LR[i] <= s[i] <=UR[i];

Daten für Tyraniden:
Code:
set Datasheets :=  BroodLord HiveTyrant Swarmlord TyranidPrime Tervigon Neurothrope OldOneEye 
          TyranidWarriors Genestealer Termagants Hormagaunts RipperSwarms
          TyrantGuard HiveGuard Zoanthropes
          Exocrine Tyrannofex Carnifex;

set Roles := HQ Elite Standard FastAttack HeavySupport Flyer Transport;

#Battlefield roles are for a single battalion detachment
param:             LR        UR :=
HQ                1        3
Elite            0        3
Standard        3        6
FastAttack        0        3
HeavySupport    0        3
Flyer            0        2
Transport        0        99;

#P is taken from the codex, K is guessed, LD and UD correspond to your collection and /or preferences          
param:             P        K     LD     UD:=
BroodLord        8        2   0   3
HiveTyrant         9        3   0   1
Swarmlord         15        2   0   3
TyranidPrime     6        1   0   3
Tervigon         13        1   0   3
Neurothrope     4        2   0   3
OldOneEye        10        1   0   3
TyranidWarriors 5        1   0   3
Genestealer     4        3   0   3
Termagants         3        1   0   3
Hormagaunts     3        1   0   3
RipperSwarms    2        2   0   3
TyrantGuard     7        1   0   3
HiveGuard         7        3   0   3
Zoanthropes        6        2   0   3
Exocrine         11        4   0   3
Tyrannofex         11        3   0   3
Carnifex        6        2   0   3;

#Mapping Table between datasheet and battlefield role
param Map:
                HQ     Elite     Standard     FastAttack     HeavySupport     Flyer     Transport :=
BroodLord          1      0           0              0              0                  0          0
HiveTyrant         1      0           0              0              0                  0          0
Swarmlord         1      0           0              0              0                  0          0
TyranidPrime     1      0           0              0              0                  0          0
Tervigon         1      0           0              0              0                  0          0
Neurothrope     1      0           0              0              0                  0          0
OldOneEye        1      0           0              0              0                  0          0
TyranidWarriors 0      0           1              0              0                  0          0
Genestealer     0      0           1              0              0                  0          0
Termagants         0      0           1              0              0                  0          0
Hormagaunts     0      0           1              0              0                  0          0
RipperSwarms    0      0           1              0              0                  0          0
TyrantGuard     0      1           0              0              0                  0          0
HiveGuard         0      1           0              0              0                  0          0
Zoanthropes        0      1           0              0              0                  0          0
Exocrine         0      0           0              0              1                  0          0
Tyrannofex         0      0           0              0              1                  0          0
Carnifex        0      0           0              0              1                  0          0;
Script zum schnellen Testen des Modells:
Code:
reset;
model warhammer.mod;
data tyranids.dat;
option solver cplex;

solve;
display d ; 
display s;
display pTotal;

Die optimale Lösung für die gewählten (*hust* geratenen) Parameter lautet:
Code:
ampl: include test.run;
CPLEX 12.8.0.0: optimal integer solution; objective 43
4 MIP simplex iterations
0 branch-and-bound nodes
d 
[*] :=
      BroodLord  2
       Carnifex  0
       Exocrine  3
    Genestealer  3
      HiveGuard  3
     HiveTyrant  1
    Hormagaunts  0
    Neurothrope  0
      OldOneEye  0
   RipperSwarms  3
      Swarmlord  0
     Termagants  0
       Tervigon  0
   TyranidPrime  0
TyranidWarriors  0
     Tyrannofex  0
    TyrantGuard  0
    Zoanthropes  0
;

s 
[*] :=
       Elite  3
  FastAttack  0
       Flyer  0
          HQ  3
HeavySupport  3
    Standard  6
   Transport  0

Eigentlich bin ich mit dem Post 10 Tage zu spät. 🙄 Aber ich hoffe ihr habt trotzdem Spaß an so einem übertrieben komplexen, verquasten Theorieverhau. Ich würde mich auf jeden Fall über Input und Feedback freuen.
 
+1.
Bist du sicher das du Ingenieur bist und nicht Mathematiker? 😉
Läßt sich bestimmt vermarkten.
Denke das Gedankenkonstrukt ist bestimmt richtig und das ganze nimmt uns die Arbeit ab, die kampfstärksten Einheiten in ein Detachment zu drücken, um an Ende das beste Verhältnis von Kampfkraft zu Machtpunkte zu ermitteln 😉 Also das perfekte Spam-System. Du übersieht aber das Folgene glaube ich. Wir hatten an Anfang der Editon z.B. die Fliegerlisten mit ihren wahnsinnigen Kampfkraft/Punkteverhältnis. Und nun gewinnt man damit keinen Blumentopf damit, weil sie keine Ziele halten können. Ich glaube das wird mit Punkte so nicht erfasst. In früheren Zeiten gab es da mal ein Verhältnis zwischen punktenden Einheiten die man haben mußte und Einheiten, die einen nur vom Missionsziel geputzt haben um es so einzunehmen. Nun ist es nicht nur Boots on the Ground sondern auch die Modellanzahl, die bestimmt, ob man ein Ziel hält oder nicht. Schwer zu erfassende Faktoren, die aber von uns als Spieler verstanden bzw. in ein Bauchgefühl gefasst werden, wenn man keine Zahlen hat.
 
@Sniperjack: Pff, wer braucht schon Missionsziele wenn er den Gegner mit mathematischer Präzision von der Platte putzen kann 😀 Aber du hast natürlich recht. Das "richtige" Warhammer am Tisch hat noch so viele weitere Randbedingungen, die man kaum in mathematische Form pressen kann. Eine vernünftige Effektivitätsfunktion könnte neben der Offensivkraft (gewichtet über übliche Szenarien), Defensivkraft (ebenfalls gewichtet), Mobilität auch solche Faktoren berücksichtigen. Oder man betrachtet mehrere Zielfunktionen: Output, Input, Mobilität, Anzahl Lebenspunkte, usw. Am Ende muss man diese Zielfunktionen dann aber wieder gewichten. Oder man findet Pareto-optimale Lösungen und wählt dann eine nach persönlicher Präferenz.

Ich glaube auch, dass das Modell ist seiner Form nicht für das wirkliche Erstellen einer Armeeliste geignet ist. Aber vielleicht ist es nützlich um bestimmte Dynamiken bei der Armeezusammenstellung zu verstehen. Und dann hat es sein Ziel ja auch irgendwie erreicht.
 
Mir sind eben noch ein paar Gedanken gekommen, die das zugrunde liegende Problem vielleicht klarer erkenntlich machen.

Wenn man die Effektivität einer Einheit gegen ihre Matched-Play Punkte aufträgt, gibt es 4 Möglichkeiten wo die Einheit liegen kann:
  1. Über der Korrelationslinie: Die Einheit ist OP. Sie ist effektiver als ihre Punkte es vermuten lassen.
  2. Auf der Korrelationslinie: Die Einheit ist gebalanced. Es sollte keinen Unterschied machen eine gebalancte Einheit für 100 P zu nehmen, oder 2 für je 50 P. Sie sollten in beiden Fällen die Gleiche Effektivität haben.
  3. Unter der Korrelationslinie: Die Einheit ist eine Codexleiche. Egal wie oft man sie nimmt, es wird nicht besser.
  4. Irgendwo im Unschärfebereich +- X % um die Korrelationslinie: Die Einheit wird als OK wahrgenommen und mal gespielt, mal nicht. Hier entscheidet die Präferenz jedes einzelnen Spielers.

Jetzt gibt es bei Einheiten, deren Effektivität linear skaliert, dazu gehören vor allem mobile Schusseinheiten (Flyrants, Commander, etc.). Da die Punkte für diese Einheiten auch linear skalieren, wird die Effektivität der Gesamtzahl von Einheiten immer über der Linie bleiben. Das führt zu Spam und wird auch durch das oben gezeigte lineare Modell erklärt.

Erst wenn entweder die Effektivität nicht linear skaliert (Buffbots, Support-Chars), oder es Strafpunkte für Doppelungen gibt (im Beispiel +20 für jede weitere Auswahl), kommt man in einen Bereich wo ein Ensemble an Einheiten erst gebalanced wird, und dann unwirtschaftlich wird. Die Effektivität ist doppelt so groß, aber die Punkte steigen überproportional. Nur mit einem solchen gegenläufigen Effekt kann man SPAM effektiv begrenzen (wenn man keine Hard-Limits einbauen möchte). Im Beispiel gilt der Strafterm nur für die erste zusätzliche Einheit. Die dritte Einheit kostet dann auch 70 Punkte, somit ergeben sich insgesamt 190 Punkte für 3 Einheiten die sonst 150 Punkte gekostet hätten. Der Strafterm muss aber für jede in Frage kommende Einheit ermittelt werden, was wiederum eine Fummelarbeit ist. Solange man nur die Basiskosten anpasst, bleibt man bei einem der 4 oben beschriebene Fälle.

Manchmal gibt es bei Einheiten aber auch Autosynergien: Mir fällt z.B. der Onager-Dunecrawler ein, der ab 2 Modellen Schutzwürfe von 1 wiederholen darf. Ab 2 Modellen ist jeder Onager ein kleines bisschen Effektiver als ein einzelner, dieser Effekt steigert sich aber nicht mit weiteren Onagern.

Ich hoffe das Diagramm macht die hier diskutierten Ideen etwas greifbarer. Viele der Ideen wurden in den letzten Wochen schon diskutiert (Harte Limits, Strafpunkte, etc.). Vielleicht kann diese theoretische Auseinandersetzung ja ein paar Denkanstöße geben so ein System auch wirklich zu implementieren.

Anhang anzeigen 360668
PS: Ich glaube auch fest daran, dass GW möchte, dass manche Einheiten einfach OP sind. Gerade Einheiten die exemplarisch für ihre Fraktion stehen (z.B. Tau Commander=mobiler waffenstarrender Anzug, Hive Tyrant = rieses Monster mit brutaler Tötungskraft) sollen ein bisschen mehr Ooomph mitbringen als vergleichbare "Standard-Einheiten", damit sie sich auf dem Spielfeld "mächtig" anfühlen. Diese Einheiten müssen dann mit Hard-Caps versehen werden, wenn man ihre Punkte nicht anpassen möchte um ihren "legendäre OP-Status" nicht zu gefährden.
 
So faszinierend ich andere Fachsprachen immer finde und Deinen enormen Aufwand dahinter sehe, so muss ich doch nochmal nachfragen:
Ich hab Dein Gedankenmodell insoweit richtig verstanden, als das innerhalb dieser konkreten Abstraktion -kurz gesagt- SPAM inhärent ist?
Da weiß ich nämlich nicht genau, ob Dein erster Halb-Satz im Beitrag noch Titel oder schon Ergebnis ist!😉
 
@beetlemeier: Ja ich bin der Meinung, dass SPAM von guten Einheiten in der klassischen Armeezusammenstellungsmethode unvermeidlich ist, weil gute Einheit kaum schlechter werden wenn man sie öfter nimmt, eigentlich werden sie nur besser, weil man die Redundanz erhöht und der Gegner seinen Beschuss aufteilen muss. Das Punktesysteme von 40k ist linear, also bleibt die Effizienz (=Effektvität/Punkt) der guten Einheiten konstant hoch.

Wie in eigentlich allen Threads lesen kann, führt dies entweder zu Hard-Caps oder alternativen Strafsystemen (Fluff-Cherry, CP-Malus), da die Punkte von sich aus keinen Anreiz geben ab einem bestimmten Sweetspot von Duplizierungen aufzuhören. Ich sehe zumindest keine rationalen Argumente nicht die maximale Anzahl Tau-Commander, Hive Tyrants oder Dark Reapers zu spielen.

Zum Glück baue ich selber lieber irrationale Listen a la Rule-of-Cool, also habe ich kein Problem mit der ganzen Diskussion 🙂
 
ok also das ist jetzt der dritte Thread innerhalb von 2 Wochen zum Spam, kann man das nicht alles in ein Thema posten ?

oder soll jetzt jeder mit einer idee ein eigenes Thema aufmachen ?

Zwingt dich irgendjemand, die entsprechenden Threads zu lesen? Nein. Falls dich das Thema nicht weiter interessiert, schau es dir doch einfach nicht an. Aber falls du einfach nur ein bisschen trollen willst, möchte ich dir natürlich nicht deinen Spaß nehmen.
 
Aber falls du einfach nur ein bisschen trollen willst, möchte ich dir natürlich nicht deinen Spaß nehmen.

Wieso wird die Kritik an etwas immer erstmal als Trollen abgetan?
Ja, es ist toll das es Leute gibt die das Thema beschäftigt. Aber das zu bündeln wäre doch tatsächlich gut, zumal der Startbeitrag zum Thema Spam ja auch derzeit eher im Kreis läuft.
 
Vor allem behandelt dieser Thread ein ganz anderes Thema? Ich wüsste jetzt nicht wie sich das sinnvoll in den Balance-Spam-Monsterthread integrieren lassen könnte.

Hier geht es um die Anwendung mathematischer Methoden auf ein formalisiertes Modell eines Vorgangs bei Warhammer 40k. Die spam Thematik wird ja eher durch Zufall angesprochen. Ich betrachte das hier eher als intellektuellen Spielplatz.
 
Ich betrachte das hier eher als intellektuellen Spielplatz.

Huihuihui!😀
Mal sehen, wann man metaphorisch auf diesem Spielplatz die ersten verbalen "Köttel" und "Spritzen" findet...

Und jetzt im Ernst:
@Nukleon: Ich find Deinen Ansatz total super, obwohl ich da maximal! die Hälfte von nachvollziehen kann!

Vielleicht ist diese streng wissenschaftliche Herangehensweise ja auch ein wirklicher Lösungsansatz, um bestimmte Thesen/Diskussionen, die sich hier im Forum ebenso end- wie sinn- und ergebnislos hinziehen, auf eine halbwegs reale Grundlage zu stellen?!

Du sagst, Du bist Ingenieur? Für mich lesen sich Deine Beiträge eher rein als Spieltheorie!😉
Gibt es da vielleicht irgendwelche Tipps von Dir, wo sich auch der LAIE mal einen Überblick verschaffen kann? Kann in einem Tabeltop-Forum ja nie verkehrt sein!😀