2012-07-04 31 views
6

Estoy tratando de escribir un fragmento de código que pueda reducir al mínimo la LONGITUD de una expresión booleana, por lo que el código debería reducir el número de elementos en la expresión a la mínima posible. En este momento estoy atascado y necesito ayuda = [algoritmo - minimizando las expresiones booleanas

Esta es la regla: puede haber un número arbitrario de elementos en una expresión booleana, pero solo contiene operadores AND y OR, más corchetes.

Por ejemplo, si paso en una expresión booleana: ABC + BCD + DE, la salida óptima sería BC (A + D) + DE, que guarda 2 espacios de unidad en comparación con la original porque los dos BC son combinado en uno

Mi lógica es que intentaré encontrar el elemento que aparece con más frecuencia en la expresión, y lo descompongo. Luego invoco la función de manera recursiva para hacer lo mismo con la expresión factorizada hasta que esté completamente factorizada. Sin embargo, ¿cómo puedo encontrar el elemento más común en la expresión original? Es decir, en el ejemplo anterior, BC? Parece que tendría que probar todas las combinaciones diferentes de elementos y encontrar el número de veces que aparece cada combinación en toda la expresión. Pero esto suena realmente ingenuo. Segundo

¿Alguien puede dar una pista sobre cómo hacer esto de manera eficiente? Incluso algunas palabras clave que puedo buscar en Google servirán.

+0

Usa el mapa de Karnaugh, Luke? –

+0

@ Li-aungYip Ya he pensado en eso, pero eso solo si estás usando lápices y papel ¿no? ¿Cómo puedo hacer un código de computadora que lo haga? – turtlesoup

+0

Con los paréntesis, BC (A + D) + DE y ABC + BCD + DE tienen la misma longitud. Estoy trabajando en el mismo problema ahora mismo. Este [enlace] (http://babbage.cs.qc.edu/courses/Minimize/) habla un poco sobre esto en la sección Algebraic Minimization. Creo que es solo hacer pases que aplican identidades booleanas a la fórmula. – douggard

Respuesta

4

En este momento no he leído acerca de todos esos algoritmos fresco todavía, pero se preguntó acerca de encontrar el factor común, así que pensé lo siguiente:

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 función devuelve una lista ordenada por:

  1. la longitud del factor común
  2. el número de términos que tienen este factor común
+0

Gracias por el algoritmo para encontrar el factor común, intentaré construir un convertidor booleano además de eso. Los algoritmos actuales existentes son difíciles de implementar en mi caso =] – turtlesoup

+0

No creo que el factoring sea suficiente, debe saber cuándo eliminar las expresiones. El ejemplo anterior se puede simplificar mucho más que usando un solo factor. Primero se puede convertir en: 'B (AC + CD + ACE) + DE', que a su vez puede convertirse en' BC (A + D + AE) + DE'. Luego observe que el 'A + AE' es redundante, por lo que finalmente tiene' BC (A + D) + DE'. – speedplane

5

Lo que está buscando es una forma de minimizar una función booleana. Esto es algo que interesa especialmente a la comunidad de diseño de chips. Una técnica que se utiliza para sus propósitos es Quine-McCluskey algorithm, o puede usar Karnaugh Maps según lo sugerido por Li-aung Yip en los comentarios.

+0

Whoops, vencerme por 12 minutos. :) –

+0

He leído un poco sobre el algoritmo de Quine-McCluskey, y dice que la memoria y el tiempo crecen exponencialmente a medida que aumenta la entrada. Estoy buscando algo que pueda manejar cientos de entradas (litros en la expresión) ... ¿hay otra forma de hacerlo? ¿O no comprendí cómo usar el algoritmo de Quine? ¡Gracias! – turtlesoup

+1

@Jimster: sugiero que lea el artículo de Wikipedia vinculado, que trata este tema. El artículo de la wiki menciona que las expresiones booleanas grandes pueden manejarse de forma heurística con el minimizador 'Espresso', que se escala mucho mejor que Quine-McCluskey. –

2

Utilice el algoritmo Quine-McCluskey para minimizar las expresiones booleanas. Es funcionalmente equivalente al enfoque del Mapa de Karnaugh, pero mucho más susceptible de implementación en una computadora.

1

Desafortunadamente, la mayoría de las sugerencias pueden no dar a @turtlesoup lo que está buscando. @turtlesoup pidió una forma de minimizar el número de caracteres para una expresión booleana dada. La mayoría de los métodos de simplificación no se centran en el número de caracteres como un enfoque para la simplificación. Cuando se trata de la minimización de la electrónica, los usuarios generalmente quieren la menor cantidad de puertas (o partes). Esto no siempre se traduce en una expresión más corta en términos de la "longitud" de la expresión - la mayoría de las veces lo hace, pero no siempre. De hecho, a veces la expresión puede ser más grande, en términos de longitud, aunque puede ser más simple desde el punto de vista de la electrónica (requiere menos puertas para construir).

boolengine.com es la mejor herramienta de simplificación que conozco cuando se trata de la simplificación booleana para circuitos digitales. No permite cientos de entradas, pero permite 14, que es mucho más que la mayoría de las herramientas de simplificación.

Al trabajar con productos electrónicos, los programas de simplificación generalmente desglosan la expresión en forma de suma de producto. Entonces la expresión '(ab) +' cd se convierte en 'c +' b + 'a + d. El resultado "simplificado" requiere más caracteres para imprimir como una expresión, pero es más fácil de construir desde el punto de vista de la electrónica. Solo requiere una única puerta OR de 4 entradas y 3 inversores (4 partes). Mientras que la expresión original requeriría 2 puertas AND, 2 inversores y una puerta OR (5 partes).

Después de dar el ejemplo de @ turtlesoup a BoolEngine, muestra que BC (A + D) + DE se convierte en E + D + ABC. Esta es una expresión más corta, y generalmente lo será. Pero ciertamente no siempre.

Cuestiones relacionadas