Você pode usar um set
(no sentido matemático da palavra, ou seja, uma coleção que não pode conter duplicatas) para armazenar estados que você já viu. As operações que você precisará executar sobre isso são:
- inserindo elementos
- testando se os elementos já estão lá
Praticamente toda linguagem de programação já deve ter suporte para uma estrutura de dados que pode executar essas duas operações em tempo constante ( ). Por exemplo:O ( 1 )
set
em Python
HashSet
em Java
bb - 11 1b1 1
No pseudocódigo, esse conjunto (vamos chamá-lo closed_set
, para ser consistente com o pseudocódigo na wikipedia pode ser usado em uma pesquisa de amplitude inicial da seguinte forma:
frontier = First-In-First-Out Queue
frontier.add(initial_state)
closed_set = set()
while frontier not empty:
current = frontier.remove_next()
if current == goal_state:
return something
for each child in current.generate_children()
if child not in closed_set: // This operation should be supported in O(1) time regardless of closed_set's current size
frontier.add(child)
closed_set.add(current) // this should also run in O(1) time
(algumas variações desse pseudocódigo também podem funcionar e serem mais ou menos eficientes, dependendo da situação; por exemplo, você também pode closed_set
incluir todos os nós dos quais você já adicionou filhos à fronteira e evitar completamente a generate_children()
chamada se current
já estiver no closed_set
.)
O que eu descrevi acima seria a maneira padrão de lidar com esse problema. Intuitivamente, suspeito que uma "solução" diferente poderia ser sempre aleatória na ordem de uma nova lista de estados sucessores antes de adicioná-los à fronteira. Dessa forma, você não evita o problema de adicionar ocasionalmente estados que já expandiu para a fronteira, mas acho que isso deve reduzir significativamente o risco de ficar preso em ciclos infinitos.
Cuidado : não conheço nenhuma análise formal dessa solução que prove que ela sempre evita ciclos infinitos. Se eu tentar "executar" isso na minha cabeça, intuitivamente, suspeito que deva funcionar e não requer memória extra. Pode haver casos extremos nos quais não estou pensando agora, portanto, também pode não funcionar, a solução padrão descrita acima será uma aposta mais segura (ao custo de mais memória).