Seja um DAG. Sabemos que alguns nós em são "ruins", enquanto outros são "bons"; um descendente de um nó ruim é ruim enquanto os ancestrais de um nó bom são bons. Também sabemos que nós ruins têm um elemento mínimo exclusivo em que gostaríamos de encontrar consultando o menor número possível de nós com consultas do tipo "Você é bom ou ruim?".
Esse problema foi resolvido no Git, o popular sistema de controle de versão, pelo comando git-bisect
, que ajuda um programador a encontrar o primeiro commit no qual um bug foi introduzido.
No início, o algoritmo implementado pelo Git pressupõe conhecer um único commit incorreto e um ou mais commits válidos. Em cada etapa de sua execução, o algoritmo localiza uma confirmação usando as seguintes etapas (extraídas daqui ):
Mantenha apenas as confirmações que:
a) são um ancestral do commit incorreto (incluindo o próprio commit incorreto) e
b) não são ancestrais de um bom commit (excluindo o bom commit).
A partir das extremidades boas do gráfico resultante, associe a cada confirmação o número de ancestrais que possui mais um.
Associar a cada confirmação , em que é o valor associado à confirmação na etapa 2 e é o número total de confirmações no gráfico (depois que foi reduzido na etapa 1).
O melhor ponto de bissecção é o commit com o maior número associado.
Esse algoritmo está essencialmente encontrando a confirmação que alcança o "pior melhor caso": na verdade, é o número de nós no DAG na próxima iteração no melhor caso, portanto é o pior caso.
Eu estou pensando:
- Faz alguma diferença se selecionarmos o "melhor pior caso", ou seja, o nó que atinge ?
- Esse algoritmo é o pior caso ideal?
Edição: notei que este problema tem um ligado. Considere o DAG formado por um único nó com pais chamado . Se sabemos que é ruim, temos que verificar cada um dos pais para ver se eles são o nó ruim mínimo.
EDIT 2: O anterior é realmente um ligado, onde é a largura do poset. Um algoritmo alternativo para esse problema é fornecido nesta resposta em cstheory.stackexchange que usa consultas .