L'algoritmo implementato da git bisect è ottimale?


8

Lascia che sia un DAG. Sappiamo che alcuni nodi in sono "cattivi", mentre altri sono "buoni"; un discendente di un nodo cattivo è cattivo mentre gli antenati di un nodo buono sono buoni. Sappiamo anche che i nodi danneggiati hanno un unico elemento minimo in che vorremmo trovare interrogando il minor numero possibile di nodi con query del tipo "Sei buono o cattivo?".GGG

Questo problema è risolto in Git, il popolare sistema di controllo della versione, tramite il comando git-bisect, che aiuta un programmatore a trovare il primo commit in cui è stato introdotto un bug.

All'inizio, l'algoritmo implementato da Git presuppone di conoscere un singolo commit errato e uno o più commit positivi. Ad ogni passaggio della sua esecuzione, l'algoritmo trova un commit usando i seguenti passaggi (presi da qui ):

  1. Tieni solo gli impegni che:

    a) sono antenati del cattivo commesso (incluso il cattivo commesso stesso), e

    b) non sono antenati di un buon impegno (esclusi i buoni impegni).

  2. A partire dalle estremità buone del grafico risultante, associa a ciascun commit il numero di antenati che ha più uno.

  3. Associare a ciascun commit , dove X è il valore associato al commit nel passaggio 2 e N è il numero totale di commit nel grafico (dopo che è stato ridotto nel passaggio 1).min(X,NX)XN

  4. Il miglior punto di taglio è il commit con il numero associato più alto.

Questo algoritmo sta essenzialmente trovando il commit che ottiene il "peggior caso": in effetti, è il numero di nodi nel DAG alla successiva iterazione nel migliore dei casi, quindi è il peggior caso migliore.min(X,NX)maxmin(X,NX)

Mi sto chiedendo:

  • Fa differenza se selezioniamo il "miglior caso peggiore", ovvero il nodo che raggiunge ?minmax(X,NX)
  • Questo algoritmo nel caso peggiore è ottimale?

EDIT: ho notato che questo problema ha un limite . Considera il DAG formato da un singolo nodo con genitori chiamati . Se sappiamo che è male, allora controlliamo ciascuno dei genitori per vedere se sono il nodo minimo cattivo.Ω(N)bN1g1,,gN1b

EDIT 2: Il precedente è in realtà un associato, dove è la larghezza del poset. Un algoritmo alternativo per questo problema è riportato in questa risposta su cstheory.stackexchange che utilizza query .Ω(w)wO(wlogn)


1
Non possiamo rispondere se sia ottimale senza definire cosa intendiamo per ottimale. In particolare, stiamo parlando della complessità del caso peggiore? Complessità nel caso medio? Qual è il carico di lavoro tipico? (Che aspetto ha il tipico grafico? Qual è la distribuzione sui grafici?) Quelle domande sono molto importanti nella pratica, ma potrebbero non avere una risposta analitica chiara o semplice.
DW

Sono principalmente interessato alla complessità del caso peggiore. Ho provato a costruire casi in cui l'algoritmo avido prende troppe scelte sbagliate, ma non sono riuscito a farlo. Naturalmente, il tipico grafico git ha molta struttura (mi aspetterei una catena long-ish in cui si trova la maggior parte dei commit: il ramo master), ma probabilmente è troppo difficile da caratterizzare.
Jacopo Notarstefano,

1
Non capisco davvero cosa stai chiedendo, ma la seguente disuguaglianza può essere utile: per qualsiasi funzione di due variabili , è sempre il caso che . Vedi ad esempio, math.stackexchange.com/a/186722/3060fmaxxminyf(x,y)minxmaxyf(x,y)
Nick Alger

Risposte:


5

Ecco alcune intuizioni su cosa stanno facendo eConcentrarsi su un impegno particolare . Supponiamo di testare e classificarlo come "buono" o "cattivo". Fino a quando non lo testiamo, non sappiamo se è buono o cattivo, ma possiamo prevedere in anticipo quanto più piccolo sarà il grafico in ciascuno di questi due casi. In particolare, è il numero di commit che verrebbero eliminati se il commit risulta essere buono, e è il numero di commit che verrebbe eliminato se il commit risulta essere cattivo.XNccXcNXc

Pertanto, il valore è un limite inferiore del numero di commit che potremo tagliare nel passaggio successivo, indipendentemente dal risultato del test. L'idea dell'algoritmo Git è di massimizzare questa metrica. In altre parole, Git sceglie una soglia che è il più grande possibile e un commit per il test successivo, in modo che Git possa essere sicuro che sarà in grado di eliminare almeno commit nel passaggio successivo.min(X,NX)tct

Se non abbiamo informazioni sul fatto che ogni commit possa rivelarsi buono o cattivo, quindi è altrettanto probabile che sia buono o cattivo, allora questa sembra una scelta localmente ottimale. Pertanto, l'algoritmo Git è un algoritmo avido.

L'algoritmo Git è globalmente ottimale? Ciò dipenderà dalla definizione di "ottimale" e (probabilmente) dalla distribuzione dei DAG che si incontrano nella pratica. Probabilmente non esiste una semplice caratterizzazione della distribuzione di probabilità sui DAG che si incontrano in pratica, quindi mi aspetto che probabilmente sarà difficile trovare un risultato di ottimalità per questo problema.


2
Sebbene questa sia una spiegazione interessante, questa non è una risposta alla mia domanda, quindi non posso accettarla.
Jacopo Notarstefano,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.