Algorithmus für Projekt Euler Problem Nr. 18

8

Das Problem Nr. 18 auf der Website von Project Euler lautet wie folgt:

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3
7 4
2 4 6
8 5 9 3

That is, 3 + 7 + 4 + 9 = 23.

Find the maximum total from top to bottom of the triangle below:

75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)

Die Formulierung dieser Probleme macht nicht klar, ob

  • Der "Traversor" ist gierig, was bedeutet, dass er das Kind immer mit einem höheren Wert ausgewählt hat
  • Das Maximum jeder einzelnen exemplarischen Vorgehensweise wird abgefragt

Das NOTEsagt das it is possible to solve this problem by trying every route. Das heißt für mich, das ist auch ohne möglich !

Dies führt zu meiner eigentlichen Frage: Angenommen, nicht der gierige ist der maximale, gibt es einen Algorithmus, der den maximalen Walkthrough-Wert findet, ohne jede Route auszuprobieren, und der sich nicht wie der gierige Algorithmus verhält?

Ich habe einen Algorithmus in Java implementiert, indem ich die Werte zuerst in eine Knotenstruktur eingefügt und dann den Greedy-Algorithmus angewendet habe. Das Ergebnis wird jedoch von Project Euler als falsch eingestuft.

sum = 0;

void findWay(Node node){
    sum += node.value;
    if(node.nodeLeft != null && node.nodeRight != null){
            if(node.nodeLeft.value > node.nodeRight.value){
                findWay(node.nodeLeft);
            }else{
                findWay(node.nodeRight);
            }
        }
}
Valentino Ru
quelle
1
Manchmal führt die Wahl der niedrigeren Zahl dazu, dass bei der nächsten Wahl eine höhere Zahl gewählt wird, die hoch genug ist, um den Unterschied in der vorherigen Wahl auszugleichen. Aus diesem Grund ist Ihr Algorithmus falsch.
Jimmy Hoffa
Natürlich ist es das, aber wird das im Problem gefragt?
Valentino Ru
"maximale Summe" bedeutet für mich genau das. Maximum ist ein absolutes Wort, lesen Sie es also als "absolut maximal insgesamt möglich".
Jimmy Hoffa
2
Ich würde es mit einem modifizierten Dijkstra-Algorithmus angehen, denke ich. Ich werde es morgen ausprobieren. Sie sollten schnell herausfinden können, wann Sie eine Route vorzeitig beenden müssen. Vielleicht gibt es einen besseren Weg ... da geht mein guter Schlaf.
James
Dies ist normalerweise ein Beispiel für ein dynamisches Programmierproblem, das häufig mit einer gierigen Methode lösbar erscheint. Dynamische Programmierung erfordert die Lösung von Teilproblemen, um das Hauptproblem zu lösen.
Peter Smith

Antworten:

9

Spoiler-Alarm : Diese Antwort führt Sie zu einer Lösung, implementiert diese jedoch nicht


Am Beispiel von WuHoUnited, modifiziert für die Eindeutigkeit:

   9
  7 0
 2 4 6
8 5 1 3

Fragen Sie sich Folgendes: Wenn Sie sich bei 2 befinden würden, würden Sie jemals 8 statt 5 nehmen, wenn Sie wissen, dass dies die Blattknoten des Baumes sind? Wenn Sie sich bei 6 befinden würden, würden Sie jemals 3 statt 1 nehmen, wenn Sie wüssten, dass dies die Blattknoten des Baumes sind?

Sicherlich nicht. Wir können jetzt den Baum verkleinern und wissen, welche Entscheidung wir am vorletzten Zweig treffen würden (unabhängig davon, wie wir dorthin gekommen sind):

   9
  7 0
10 9 9

Ich denke du siehst wohin das führt.

Ryan Cavanaugh
quelle
1

Als jemand, der das Problem gelöst hat, kann ich Ihnen sagen, dass der gierige Algorithmus NICHT das ist, wonach er sucht.

Es wird nach dem Maximalwert aller möglichen Routen gesucht.

Beispiel

   3
  7 4
 2 4 6
8 5 1 3

3 + 7 + 4 + 5 = 19 <- gierig
3 + 7 + 2 + 8 = 20 <- nicht gierig

Die Antwort sollte also 20 sein

WuHoUnited
quelle
ok, aber das bedeutet, dass es keinen anderen Weg gibt, als jede Route zu gehen, nicht wahr?
Valentino Ru
1
@ValentinoRu offensichtlich nicht, das Euler-Problem sagt es. Dies ist ein Diagrammproblem. Versuchen Sie daher, Diagramme mit den kleinen Zahlensätzen auf verschiedene Weise zu zeichnen, und prüfen Sie, ob Sie Darstellungen davon identifizieren können, die die gewünschten Informationen in den Vordergrund rücken.
Jimmy Hoffa
Es ist, wie Project Euler und Jimmy Hoffa sagen: Es gibt einen sehr effizienten Weg, um das Problem zu lösen, ohne jede Route auszuprobieren.
WuHoUnited
-1

Dijkstra-Algorithmus für kürzeste Wege (alle Kanten negativ drehen).

zvrba
quelle
5
Sie könnten in Ihrer Antwort etwas ausführlicher sein. Sogar ein Link zum Dijkstra-Algorithmus wäre hilfreicher.
Martijn Pieters
-1

Gieriger Ansatz ist definitiv nicht der Ansatz, den Sie für dieses Problem in Betracht ziehen sollten. Stellen Sie sich eine Lösung vor, die alle möglichen Routen gründlich überprüft und das Maximum findet. Optimieren Sie es dann mithilfe der dynamischen Programmierung .

agent13
quelle