Domanda

domanda

Ci sono molti algoritmi per risolvere il #Sat problema, con un essere L'algoritmo DPLL ed è implementato per tutti i tipi di linguaggi di programmazione. Per quanto ho visto, prendono tutti una formula booleana sul CNF come input e produce il numero di interpretazioni soddisfatte.

I vincoli matematici , d'altra parte, è un altro modo definire un'istanza Di SAT-Problema ed è spesso usato in ottimizzazione discreta, in cui si cerca di ottimizzare qualche funzione rispetto a questi vincoli. Esiste un programma prendendo vincoli matematici come input e uscite il numero di interpretazioni soddisfatte?

Esempio

Rappresentiamo la formula booleana $ q= (a \ lor b) \ wedge (c \ lor d) $ come vincoli come $$ A + B \ GeQ 1 \\ C + D \ Geq 1 $$ o come matrice $ a $ e vettore di supporto < Span class="Math-Container"> $ B $ $$ A=. \ Begin {bmatrix} 1 e 1 e 0 e 0 \\ 0 e 0 e 1 e 1 \ end {bmatrix} \\ B=Begin {bmatrix} 1 e 1 \ end {bmatrix} $$

Dove tutte le variabili $ A, B, c, d \ in \ {0,1 \} $ . Sappiamo che ci sono programmi prendendo $ q $ come input e emette il numero di interpretazioni ma sono programmi prendendo $ A $ <> $ A $ < / span> e $ B $ come input (o costruzione simile) e emette lo stesso numero di interpretazioni?

È stato utile?

Soluzione

Conosco due approcci ragionevoli.

approccio # 1 : Conta il numero di punti interi all'interno di un polytope convesso.

L'insieme di disuguaglianze lineari che hai fornito, insieme alle disuguaglianze $ 0 \ Le A, B, C, D \ le 1 $ , definisce un polytope convesso. Ora, vuoi Conta il numero di punti interi che rientrano in questo Polytope . Ci sono algoritmi standard per farlo, che potresti applicare direttamente. Se cerchi "Contando punti interi in Polytope" o "Conteggio dei punti reticoli in Polytope" troverai molti documenti di ricerca. Vedi, ad esempio, https://cstheory.stackexchange.com/Q/22280/5038 , Findare tutte le soluzioni a un problema di programmazione lineare integer (ILP) .

approccio # 2 : Converti in CNF, quindi utilizzare un risolutore #SAT.

Puoi sempre convertire i tuoi vincoli in una formula CNF. Ogni disuguaglianza lineare può essere convertita in una serie di clausole CNF. Una disuguaglianza lineare della forma $ x_i + \ dots + x_j \ ge 1 $ corrisponde immediatamente alla clausola CNF $ (x_i \ lor \ dots \ lor x_j) $ . Per una disuguaglianza lineare più generale della forma $ x_i + \ dots + x_j \ ge c $ , vuoi esprimere il vincolo che almeno $ c $ fuori dalla $ k $ variabili $ x_i, \ dots, x_j $ sono vere. Ci sono molti modi standard per la codifica. Vedi https://cstheory.stackexchange.com/Q/23771/5038 , Rendita il seguente problema a Sab , Codifica 1 -out-of-n vincolo per solutori satelliti ,

(un approccio è quello di convertire un circuito booleano che calcola $ x_i + \ dots + x_j $ e confrontalo a $ c $ , quindi convertire il circuito booleano in CNF utilizzando il Tseitin Transform . È possibile creare un tale circuito booleano utilizzando i circuiti standard Adder and Comparator. Tuttavia, ci sono anche molti altri modi.)

Una volta che si dispone di una formula CNF che è equivalente al set di vincoli, quindi è possibile utilizzare qualsiasi risolutore #Sat off-the-shelf per contare il numero di soluzioni a quella formula CNF.


.

È difficile dire quale di questi due approcci funzionerà meglio; Potrebbe essere necessario provarli sia sul tipo di istanze con cui hai a che fare, per saperne di sicuro. Mi aspetterei che se hai delle disuguaglianze lineari del modulo $ x_i + \ dots + x_j \ ge c $ dove $ c $ è grande, quindi l'approccio n. 1 potrebbe essere superiore; Ma se $ c $ è in genere piccolo, quindi approccio # 2 potrebbe essere superiore.

Altri suggerimenti

È possibile implementare DPLL usando direttamente utilizzando i vincoli anziché le clausole.Ciò richiede modificare la struttura dei dati e l'algoritmo di propagazione, ma funziona lo stesso.

Non appena tutte le variabili del vincolo sono impostate tranne una, potrebbe verificarsi la propagazione dell'unità.

Non appena vengono impostate tutte le variabili del vincolo, potrebbe verificarsi un conflitto.

Il resto dell'algoritmo rimane lo stesso.

Un vincolo sulle variabili booleane è solo una raccolta di clausole CNF nascoste (potenzialmente esponenzialmente molte clausole a seconda del vincolo).

La domanda è stata Risposta su o.stackexchange per software di programmazione integro misto, con esempi di software e script esistenti (Clex, Scip, ...).

Questo è più simile all'algoritmo CDCL rispetto a DPLL: quando viene trovata una nuova soluzione, viene aggiunto un nuovo vincolo per vietarlo e la ricerca riprende, finché il problema non è infassibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a cs.stackexchange
scroll top