2012-07-04 20 views
6

Sto provando a scrivere un pezzo di codice che può ridurre al minimo la LUNGHEZZA di un'espressione booleana, quindi il codice dovrebbe ridurre il numero di elementi nell'espressione al minimo possibile. In questo momento sono bloccato e ho bisogno di aiuto = [- Ridurre al minimo le espressioni booleane

Ecco la regola: ci può essere un numero arbitrario di elementi in un'espressione booleana, ma contiene solo operatori AND e OR, più parentesi.

Ad esempio, se passo un'espressione booleana: ABC + BCD + DE, l'uscita ottimale sarebbe BC (A + D) + DE, che salva 2 spazi unitari rispetto a quello originale perché i due BC sono combinati in uno.

La mia logica è che tenterò di trovare l'elemento più frequentemente apparso nell'espressione, e di tenerlo fuori. Quindi chiamo ricorsivamente la funzione per fare la stessa cosa con l'espressione fattorizzata fino a quando non viene completamente fattorizzata. Tuttavia, come posso trovare l'elemento più comune nell'espressione originale? Cioè, nell'esempio sopra, BC? Sembra che dovrei provare tutte le diverse combinazioni di elementi e trovare il numero di volte in cui ogni combinazione appare nell'intera espressione. Ma questo suona davvero ingenuo. Secondo

Qualcuno può dare un suggerimento su come farlo in modo efficiente? Anche alcune parole chiave che posso cercare su Google lo faranno.

+0

Utilizzare la mappa di Karnaugh, Luke? –

+0

@ Li-aungYip Ya Ci ho pensato, ma è solo se stai usando matite e carta, giusto? Come posso fare un codice computer che lo fa? – turtlesoup

+0

Con le parentesi, BC (A + D) + DE e ABC + BCD + DE hanno la stessa lunghezza. Sto lavorando allo stesso problema in questo momento. Questo [collegamento] (http://babbage.cs.qc.edu/courses/Minimize/) ne parla un po 'sotto la sezione Minimizzazione algebrica. Penso che si stiano facendo dei passaggi che applicano le identità booleane alla formula. – douggard

risposta

4

dispiace non ho letto su tutte quelle ancora algoritmi di fresco, ma lei ha chiesto di trovare il fattore comune, così ho pensato di quanto segue:

import itertools 
def commons(exprs): 
    groups = [] 
    for n in range(2, len(exprs)+1): 
     for comb in itertools.combinations(exprs, n): 
      common = set.intersection(*map(set, comb)) 
      if common: 
       groups.append(
          (len(common), n, comb, ''.join(common))) 
    return sorted(groups, reverse=True) 

>>> exprs 
['ABC', 'BCD', 'DE', 'ABCE'] 

>>> commons(exprs) 
[(3, 2, ('ABC', 'ABCE'), 'ACB'), 
(2, 3, ('ABC', 'BCD', 'ABCE'), 'CB'), 
(2, 2, ('BCD', 'ABCE'), 'CB'), 
(2, 2, ('ABC', 'BCD'), 'CB'), 
(1, 2, ('DE', 'ABCE'), 'E'), 
(1, 2, ('BCD', 'DE'), 'D')] 

La funzione restituisce un elenco ordinato per:

  1. la lunghezza del fattore comune
  2. il numero di termini che hanno questo fattore comune
+0

Grazie per l'algoritmo per la ricerca del fattore comune, proverò a creare un convertitore booleano. Gli attuali algoritmi esistenti sono difficili da implementare nel mio caso =] – turtlesoup

+0

Non penso che il factoring sia sufficiente, devi sapere quando eliminare le espressioni. L'esempio sopra può essere semplificato molto più che utilizzando un singolo fattore. Può essere prima trasformato in: 'B (AC + CD + ACE) + DE', che può a sua volta essere trasformato in' BC (A + D + AE) + DE'. Quindi notate che 'A + AE' è ridondante, quindi avrete finalmente' BC (A + D) + DE'. – speedplane

5

Quello che stai cercando è un modo per ridurre al minimo una funzione booleana. Questo è qualcosa che interessa in particolare alla comunità di progettazione dei chip. Una tecnica utilizzata per i propri scopi è Quine-McCluskey algorithm oppure è possibile utilizzare Karnaugh Maps come suggerito da Li-aung Yip nei commenti.

+0

Whoops, bastonami per 12 minuti. :) –

+0

Ho letto un po 'dell'algoritmo di Quine-McCluskey e dice che la memoria e il tempo crescono esponenzialmente man mano che l'input diventa più grande. Sto cercando qualcosa che possa gestire centinaia di input (letterali nell'espressione) ... quindi c'è un altro modo per farlo? O ho frainteso come usare l'algoritmo di Quine? Grazie! – turtlesoup

+1

@Jimster: Consiglio vivamente di leggere l'articolo di Wikipedia collegato, che tratta questo problema. L'articolo del wiki menziona che le grandi espressioni booleane possono essere gestite euristicamente dal minimizzatore "Espresso", che scala molto meglio di Quine-McCluskey. –

2

Utilizzare l'algoritmo Quine-McCluskey per ridurre al minimo le espressioni booleane. È funzionalmente equivalente all'approccio Karnaugh Map, ma molto più suscettibile all'implementazione su un computer.

1

Sfortunatamente, la maggior parte dei suggerimenti forniti potrebbe non fornire effettivamente a @turtlesoup ciò che sta cercando. @turtlesoup ha chiesto un modo per ridurre al minimo il numero di caratteri per una determinata espressione booleana. La maggior parte dei metodi di semplificazione non mira al numero di caratteri come punto di riferimento per la semplificazione. Quando si tratta di ridurre al minimo l'elettronica, gli utenti in genere vogliono il minor numero di porte (o parti). Questo non sempre si traduce in un'espressione più breve in termini di "lunghezza" dell'espressione - la maggior parte delle volte lo fa, ma non sempre. In effetti, a volte l'espressione può diventare più grande, in termini di lunghezza, anche se potrebbe essere più semplice dal punto di vista dell'elettronica (richiede meno porte da costruire).

boolengine.com è il miglior strumento di semplificazione che conosca quando si tratta di semplificazione booleana per i circuiti digitali. Non consente centinaia di input, ma ne consente 14, che è molto più della maggior parte degli strumenti di semplificazione.

Quando si lavora con l'elettronica, i programmi di semplificazione solitamente suddividono l'espressione in forma di somma di prodotto. Quindi l'espressione '(ab) +' cd diventa 'c +' b + 'a + d. Il risultato "semplificato" richiede più caratteri da stampare come espressione, ma è più facile da costruire dal punto di vista dell'elettronica. Richiede solo un singolo gate OR a 4 ingressi e 3 inverter (4 parti). Mentre l'espressione originale richiederebbe 2 porte AND, 2 inverter e una porta OR (5 parti).

Dopo aver dato l'esempio di @ turtlesoup a BoolEngine, mostra che BC (A + D) + DE diventa E + D + ABC. Questa è un'espressione più breve e di solito sarà. Ma certamente non sempre.

Problemi correlati