algoritmo para o problema de euler do projeto no 18

8

O problema número 18 do site do Project Euler é o seguinte:

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)

A formulação desses problemas não deixa claro se

  • o "Traversor" é ganancioso, o que significa que ele sempre escolheu a criança com maior valor
  • é solicitado o máximo de cada passo a passo

O que NOTEdiz isso it is possible to solve this problem by trying every route. Isso significa para mim, isso também é possível sem !

Isso leva à minha pergunta real: Supondo que não seja o máximo ganancioso, existe algum algoritmo que encontre o valor máximo da explicação sem tentar todas as rotas e que não atue como o algoritmo ganancioso?

Eu implementei um algoritmo em Java, colocando os valores primeiro em uma estrutura de nó e aplicando o algoritmo ganancioso. O resultado, no entanto, é considerado errado pelo Projeto Euler.

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
fonte
1
Às vezes, escolher o número mais baixo resultará na escolha de um número mais alto na próxima escolha, alto o suficiente para compensar a diferença na escolha anterior; é por isso que seu algoritmo está errado.
Jimmy Hoffa
Claro que sim, mas isso é solicitado no problema?
Valentino Ru
"total máximo" para mim significa exatamente isso. Máximo é uma palavra absoluta, portanto, leia-o como "total máximo possível absoluto".
Jimmy Hoffa
2
Eu lidaria com um algoritmo de Dijkstra modificado, eu acho. Eu vou experimentar amanhã. Ele deve permitir que você descubra rapidamente quando finalizar uma rota antecipadamente. Talvez haja uma maneira melhor ... lá vai a minha boa noite de sono.
James
Este é geralmente um exemplo de um problema de programação dinâmica, que geralmente pode ser solucionado com um método ganancioso. A programação dinâmica requer a solução de subproblemas para resolver o problema principal.
Peter Smith

Respostas:

9

Alerta de spoiler : Esta resposta leva você a uma solução, mas não a implementa


Usando o exemplo de WuHoUnited, modificado por exclusividade:

   9
  7 0
 2 4 6
8 5 1 3

Pergunte a si mesmo: se você se encontrasse com 2 anos, aceitaria 8 em vez de 5, sabendo que são os nós das folhas da árvore? Da mesma forma, se você se encontrasse com 6 anos, aceitaria 3 em vez de 1, sabendo que esses são os nós das folhas da árvore?

Certamente não. Agora podemos reduzir a árvore, sabendo que decisão tomaríamos no penúltimo ramo (independentemente de como chegamos lá):

   9
  7 0
10 9 9

Eu acho que você vê para onde isso está indo.

Ryan Cavanaugh
fonte
1

Como alguém que resolveu o problema, posso lhe dizer que o algoritmo ganancioso NÃO é o que eles estão procurando.

Ele está procurando o valor máximo de todas as rotas possíveis.

exemplo

   3
  7 4
 2 4 6
8 5 1 3

3 + 7 + 4 + 5 = 19 <- ganancioso
3 + 7 + 2 + 8 = 20 <- não ganancioso

Portanto, a resposta deve ser 20

WuHoUnited
fonte
ok, mas isso significa que não há outra maneira senão percorrer todas as rotas, não é?
Valentino Ru
1
@ValentinoRu obviamente não, o problema de Euler diz isso. Esse é um problema de gráfico. Tente desenhar gráficos com os pequenos conjuntos de números de várias maneiras e veja se você consegue identificar alguma representação deles que traga as informações que você deseja para a frente.
Jimmy Hoffa
É como o Projeto Euler e Jimmy Hoffa dizem: Existe uma maneira muito eficiente de resolver o problema sem tentar todas as rotas.
WuHoUnited
-1

O algoritmo de Dijkstra para caminhos mais curtos (vire todas as bordas para negativas).

zvrba
fonte
5
Você pode ser um pouco mais detalhado em sua resposta. Mesmo um link para o algoritmo de Dijkstra seria mais útil.
Martijn Pieters
-1

A abordagem gananciosa definitivamente não é a abordagem que você deve considerar para esse problema. Pense em uma solução que verifique exaustivamente todas as rotas possíveis e encontre o máximo. Otimize-o usando a programação dinâmica .

agent13
fonte