Wie man die Graphentheorie nutzen kann, um bei Dominos Geld zu sparen
Im Lockdown habe ich mich (wie viele andere auch) von Dominos ernährt. Nicht weil Dominos besonders gut oder günstig ist, aber sie sind einfach sehr schnell bei der Lieferung. Das ganze gipfelte sogar darin, dass mein Bruder mir einen Dominos Gutschein zu Weihnachten besorgt hat :)
Da ich viel Zeit in der Dominos App verbracht habe, ist mir irgendwann aufgefallen, dass man einige Pizzen billiger bekommt, wenn man etwas mit den Zutaten rumspielt.
Die Frage, die sich dann aufdrängte, ist: Welche Pizzen kann ich billiger bekommen und wie muss ich dafür mit den Zutaten hantieren.
Ein kurzer Hinweis: Mit dieser Technik lässt sich nicht viel Geld sparen. Es geht meist nur um ein paar Cent bis hin zu
Was ist los bei Dominos?
Lasst mich zunächst mal erklären, wieso man bei den Preisen von Dominos überhaupt rumspielen kann. Bei Dominos gibt es ca. 30 Pizzen und ca. 40 verschiedene Zutaten. Die Zahlen können variieren,
da es immer wieder Saisons Angebote gibt. Jedoch gibt es einen festen “Pizzen-Stamm” auf den ich mich hier beziehen werde.
Jede Pizza besteht aus einer Auswahl aus den 40 Zutaten. Zum Beispiel befindet sich auf der Pizza Funghi Champignons, Käse und Basilikum-Pesto.
Um allen Kundenwünschen gerecht zu werden, kann man nun beliebige zusätzliche Zutaten auf die Pizza drauflegen bzw. herunternehmen.
Man könnte also die Champignons der Pizza Funghi entfernen und Ananas dafür hinzufügen.
Wie sieht es jetzt mit dem Preis unserer selbst entweihten Pizza Funghi aus? Die Champignons haben einen Preis von
Es gibt noch zwei Regeln, die Dominos (wahrscheinlich aus Gründen der Gewinnoptimierung) durchsetzt. Erstens, entfernt man mehrere Zutaten, so darf man nur den Preis der teuersten Zutat abziehen. Zweitens, eine Pizza kann durch Änderungen nur teuerer werden, aber nie billiger als ihr Ursprungspreis.
Ka-Ching!
Wie können wir diese Regeln ausnutzen?
Wir wollen jetzt eine Pizza Salami bestellen. Diese kostet
Die teuerste zu entfernende Zutat ist der Mozzarella mit
Wir haben also jetzt eine Pizza Salami erstellt, die statt
Natürlich habe ich das ganze auch ausprobiert. Hier seht ihr zwei Pizzen frisch von Dominos bestellt. Eine für
Welche Pizzen muss man in Zukunft bestellen?
Das geht leider nicht mit jeder Pizza. Die Aufgabe ist es nun rauszufinden, bei welcher Pizza eine Vergünstigung möglich ist.
Und was fast noch wichtiger ist, wie der Weg der Vergünstigung aussieht.
Natürlich könnte man das stumpf durchrechnen, aber das würde Stunden dauern. Lieber schreibe ich wochenlang an einem Programm, dass das ganze auf eine “Informatiker-Weise” löst.
Die Idee zur Lösung kam mir recht spontan und ich weiß nicht, ob es noch bessere Lösungen gibt. Um das ganze Nachvollziehen zu können, ist es wichtig, die Grundlagen der Graphentheorie zu kennen. Ich habe dazu auch schon einen Artikel verfasst.
Wir versuchen nun die gesamte Preisgestaltung in einem Graphen darzustellen. Die Pizzen sind unsere Knoten und die Preise sind unsere Kanten.
Ich habe in diesem Graph nur 3 Pizzen dargestellt, da es sonst schnell unübersichtlich wird. Man kann hier zum Beispiel sehen, dass man von der Pizza Caprese ohne Aufpreis auf die Pizza Salami kommt. Ist nichts Neues, haben wir ja schon festgestellt. Eine wichtige Information ist nun jedoch in diesem Graph verloren gegangen. Der Basispreis jeder Pizza. Diese Info ist sehr wichtig, da wir jetzt nicht wissen, ob es Billiger ist, die Pizza Salami direkt zu bestellen oder über den Umweg der Pizza Caprese zu gehen.
Um das zu lösen, kann ein Hilfsknoten hinzugefügt worden. Ich nenne ihn mal Start (warum wird evtl. später klar). Dieser wird mit jeder Pizza verbunden. Die Kanten bekommen den Basispreis der jeweiligen Pizza als Gewicht.
Jetzt haben wir alle Informationen, die wir benötigen. Wir können uns nun zum Beispiel alle Preise für die Pizza Salami ansehen. Dafür gehen wir vom Startknoten über jeden möglichen Weg zur Pizza Salami
und summieren dabei die Preise auf. In unserem Beispiel bekommen wir jetzt drei Preise:
Wenn das nicht nach Dijkstra schreit, weiß ich auch nicht. In dem oben verlinkten Kapitel habe ich bereits erklärt, wie der Dijkstra-Algorithmus funktioniert, deshalb erspare ich mich hier die Erklärung. Jetzt sollte auch klar werden, warum ich hier einen Graphen zur Darstellung gewählt habe und warum ich den ersten Knoten “Start”-Knoten genannt habe. Führen wir nun nämlich Dijkstra vom Startknoten zu jedem anderen Knoten aus, bekommen wir für jede Pizza die günstigste Konfiguration und den besten Preis geliefert.
Wie man die Kantengewichte berechnet
Noch ein paar kurze Sätze zu den Preisen an den Katen. Wie werden diese berechnet. Es gehören immer zwei Knoten (Pizzen) zu einer Kante. Die “Ausgangs”-Pizza und die “Ziel”-Pizza. Nun nimmt man die Ausgangspizza und entfernt alle Zutaten, die sich nicht auf der Zielpizza befinden und fügt im Anschluss die Zutaten, die fehlen hinzu. Natürlich dürfen wir die Regel, die für mehrere hinzugefügte Zutaten gilt, nicht vergessen und auch nicht, dass die Ausgangspizza nicht billiger werden kann. Im Übrigen: Das die Ausgangspizza nicht billiger werden kann, spielt uns gut in die Karten. Wir haben nämlich so keine negativen Kantengewichte. Das ist die Voraussetzung um Dijkstra anwenden zu können.
Will code for food
Ich habe das ganze jetzt mal in C++ implementiert. Den Code findet ihr auf GitHub. Alle Pizzen mit sämtlichen Zutaten sind in einer SQLite Datenbank hinterlegt, die auch dort zu finden ist. Natürlich will ich euch die Ausgabe meines Programmes nicht vorenthalten.
Alle Pizzen, die billiger bestellt werden können, sind hier mit ihren Preisen aufgelistet. Darunter befindet sich der beste Weg, diese Pizzen zu bestellen.
Zum Schluss: Es gibt zu dem Thema auch einen Talk. Dort wird die Berechnung jedoch nicht mit einem Graphen gelöst, sondern über einen Brute-Force Ansatz.
Mehr wollte ich schon gar nicht loswerden :)
Danke fürs Lesen, bleibt neugierig