Ich habe ein Kombinatorik-Problem , das ich auf den OEIS anwenden möchte - das Problem ist, dass ich nicht genug Begriffe habe. Diese Code-Abfrage soll mir helfen, mehr Begriffe zu berechnen. Der Gewinner ist der Benutzer mit dem Beitrag, der die meisten Begriffe enthält.
Das Problem
Angenommen, ich gebe Ihnen eine dreieckige Anordnung von Glühbirnen mit der Seitenlänge :
o
o o
o o o
o o o o
o o o o o
o o o o o o
1 2 ... n
Ich werde drei Glühbirnen einschalten, die wie im folgenden Beispiel ein "aufrechtes" gleichseitiges Dreieck bilden:
o
o x
o o o
o o o o
o x o o x
o o o o o o
Bevor ich das Licht einschalte, müssen Sie so viele Glühbirnen wie möglich aus dem Array entfernen, ohne die Fähigkeit zu verlieren, das eingeschaltete Dreieck der Glühbirnen abzuleiten. Um klar zu sein, wenn eine Glühbirne entfernt wurde, leuchtet sie nicht, wenn ihre Position eingeschaltet ist.
Wenn Sie zum Beispiel die folgenden (mit gekennzeichneten .
) Lampen entfernen, werden nur die folgenden zwei Leuchten eingeschaltet (mit gekennzeichnet x
), was ausreicht, um die dritte (nicht beleuchtete) Position eindeutig zu bestimmen:
. .
. o . x
. . o . . o
o o o . => o o o .
o o o o . o x o o . <- the third unlit position
o . . . o o o . . . o o
Es a(n)
sei die maximale Anzahl von Lampen, die entfernt werden können, ohne dass Unklarheiten auftreten.
Beispiel
Mit einem naiven Algorithmus habe ich Werte bis zu einem Dreieck mit der Seitenlänge 7 überprüft, wie unten gezeigt:
.
. . o
. . o o . o
. . . . . o . o o .
. . . . o o o o o . o o . o .
. . . . o o o o . o o o o o . o . o . o o
. . . o o . o o o o . . o o o . . . o o o . o . o o o
a(2) = 3 a(3) = 4 a(4) = 5 a(5) = 7 a(6) = 9 a(7) = 11
Wertung
Die Übermittlung, die die Sequenz [a(2), a(3), ..., a(n)]
für die größten n berechnet, gewinnt. Wenn zwei Einreichungen identische Sequenzen aufweisen, gewinnt die zuvor veröffentlichte.
Obwohl dies für die Einreichung nicht erforderlich ist, wäre es für mich aufschlussreich, wenn Sie eine Konstruktion der resultierenden Triangluar-Arrays wie im obigen Beispiel posten.
quelle
Antworten:
Python 3 ,
n=8
Verwendet den CP-SAT-Solver von Google OR-Tools .
Nach einer Laufzeit von ca. 30 Sekunden wird Folgendes ausgegeben:
n=9
a(9)=15
n=8
Wie es funktioniert
Daher kann die Frage als SAT-Problem mit einer Einschränkung für jedes Dreieckspaar umformuliert werden.
PS: Ich würde sehr gerne ein Beispiel für
n=8
hinzufügen, aber ich habe Probleme mit dem SAT-Solver, der die Lösungen anscheinend für sich behalten möchte.quelle
Beziehen der Lösungen aus dem Programm von @ Delfad0r
Ich habe das Programm von @ Delfad0r auf Ausgabelösungen erweitert. Es gibt auch Zwischenergebnisse, so dass Sie die Ausgabe wie folgt erhalten:
Diese Berechnung dauerte mehrere Stunden.
Wenn Sie ungeduldig werden und drücken,
Ctrl-C
nachdem eine möglicherweise nicht optimale Lösung gefunden wurde, zeigt das Programm diese Lösung an. Das dauert also nicht lange:Hier ist das erweiterte Programm:
quelle
Python 3
Basierend auf der Antwort von Delfad0r folgt dieser Vorgang meist demselben logischen Ablauf, indem Dreieckspaare überprüft und die Konfiguration validiert werden, wenn keine Dreieckspaare vorhanden sind, die diese Validierung nicht bestehen. Da ich außer itertools und copy keine Bibliotheken verwendet habe, habe ich die volle Kontrolle über das Speichern der Beispiele, die im gesamten Programm vorkommen.
Das Problem ist, dass es nicht sehr effizient ist. Es läuft bis zu
n=5
diesem Punkt sehr schnell , verlangsamt sich jedoch ab diesem Punkt erheblich. Bein=6
dauert es eine Minute , um herumlaufen, und es ist viel langsamer ann=7
. Ich stelle mir vor, dass mit diesem Programm viele Effizienzverbesserungen vorgenommen werden können, aber es handelt sich um einen schnell erstellten Entwurf einer guten Lösung mit viel mehr Flexibilität, um das Innenleben dieser Methode zu überprüfen. Ich werde im Laufe der Zeit schrittweise daran arbeiten.quelle