Método de minimizacion minimizacion Quine-McCluskey Quine–McCluskey es El Algoritmo un método de simplificación simplificació n de funciones de funciones booleanas desarrollado por por Willard Van Orman Quine y Edward J. McCluskey. McCluskey. Es funcionalmente idéntico a la utilización del mapa del mapa de Karnaugh, pero Karnaugh, pero su forma tabular lo hace más eficiente para su implementación en lenguajes computacionales, y provee un método determinista de conseguir la mínima expresión de una función booleana.
El punto de partida para el algoritmo de minimización tratado, es la tabla de la verdad, o de manera equivalente la lista de mini términos de una función. Se sabe que un mini término de una función lógica de n variables se representa por un entero de n bits, en cuyo caso particular podría indicar si una variable se encontraba negada o no con 0 y 1 respectivamente. Sin embargo, para un método de minimización es también necesarito tomar en cuenta las variables que no aparecen en determinado mini término, representándola con una X.
Generación de los implicantes primos Se mencionó anteriormente que el método parte de la tabla de la verdad al igual que Mapas K, pero el primer paso real en el algoritmo es determinar todos los implicantes primos de la función lógica. Para la determinación de dichos implicantes será necesaria la agrupación de mini términos con mismas cantidades cantidades de unos en ellos, y posteriormente posteriormente la realización de ciertas combinaciones entre ellos, y nuevamente colocarlos colocarlos en una tabla en la que en cierto momento momento se notará que ciertos de los términos obtenidos no se podrán combinar nuevamente, siendo estos los implicantes primos; luego se excluyen estos de la tabla y se sigue combinando el resto hasta que solo queden implicantes primos.
Generación de cobertura mínima Esto se logra mediante ciertas tablas en las que se usan como cierto tipo de palomitas. Estos son arreglos bidimensionales que se les conoce como tablas de implicantes primos, de los cuales se seleccionan los suficientes como para cubrir todos los unos de la función lógica dada..
En el arreglo hay una columna por cada mini terminó de la función y un renglón (fila) por cada implicante primo. Cada entrada es un bit que es 1, si y solo si, el implicante primo para ese renglón cubre el mini término correspondiente correspondiente a la columna, lo cual en otras palabras se refiere a una celda 1 distinguida, columna con un solo uno o paloma en este caso, concepto que iría referido a la dominancia de columnas. El reglón que contenga este uno perteneciente a una celda 1 distinguida, referirá al concepto de dominancia de filas.
Así, estos implicantes determinarán la forma de la expresión mínima de esta función como suma de mini términos.
Se procederá con un ejemplo: Sea la función:
F(A, B, C, D) = Sm (1, 3, 4, 5, 7, 9, 10, 11, 15) (Sm: Sumatoria). La TABLA 1 presenta la lista de los mini términos, expresados en forma binaria e indica el número de UNOS que estos contienen:
En la TABLA 2, se agrupan los mini términos con el mismo número de UNOS
De la TABLA 2, se combinan los términos que tienen un solo UNO con los que tienen dos UNOS, los que tienen dos UNOS con los que tienen tres UNOS y así sucesivamente. Dos términos se podrán combinar siempre y cuando exista un solo cambio entre ellos; es decir, cuando el lugar en que estén colocados los UNOS coincidan. Por ejemplo, los términos 1 y 3 se combinan debido a lo siguiente:
Lo que quiere decir que entre los términos 1 y 3 se eliminó la variable C. Haciendo lo mismo con los demás términos, se obtiene la TABLA 3.
Los términos que en su fila tienen palomitas, son los que se combinaron. Los términos con *, son los que no pudieron combinarse; es decir, aquellos que en su fila no tienen palomitas. A estos términos se les denomina IMPLICANTES PRIMOS . Para la TABLA 4, se combinan los niveles de agrupación 1-2 con 2-3 y 2-3 con 3-4, tomando en cuenta que coincidan tanto las x como los UNOS.
Como ya se indicó, los implicantes primos son términos que no se combinan con ningún otro, por tanto pueden formar parte de la función reducida. Para determinar cuáles de los implicantes primos forman parte de la función reducida, se hace la siguiente tabla, llamada de implicantes primos.
Obsérvese que en la tabla anterior, se encerraron entre paréntesis las palomitas que se encontraron solas en una columna y su fila se proyectó en la parte inferior de la tabla. Si en los cuatro penúltimos renglones se llenan todas las columnas (última fila), entonces se ha llegado a la solución mínima. Nótese que c no tuvo ninguna palomita sola dentro de sus columnas, lo que significa que este implicante primo está contenido en los demás; es decir, no forma parte de la función reducida. Por tanto, la función reducida es: F(A, B, C, D) = a + b + d + e Dónde:
Finalmente, la función reducida es: F(A,B,C,D) = CD+ B’D + AB’C + A’BC’
Para concluir, en general se puede decir en función de lo observado que este método de minimización tiende a ser de mayor complejidad que el de Mapas K, más sin embargo, posee una inmensa ventaja al momento de poder implementarse en la programación con la finalidad de la realización de un programa capaz de la minimización de funciones lógicas, pues es más sencillo de tratar en ese aspecto.
Un programa que se utiliza para aplicar este método, es el MinBool.m, creado por Andrey Popov. Este programa funciona de tal manera que al introducirle una función lógica de la misma forma que fue especificada inicialmente como en el ejemplo anterior, (con ciertas modificaciones), este arroja el resultado de la minimización en forma de matriz, donde -1 indicaria una variable negada, 1 una normal, y NaN o 0 va referido a las variables que no se usan al momento. Podemos usar como ejemplo la misma función explicada en el ejemplo anterior:
F(A, B, C, D) = Sm (1, 3, 4, 5, 7, 9, 10, 11, 15) (Sm: Sumatoria).
R = minBool([1, 3, 4, 5, 7, 9, 10, 11, 15]) (se inserta de esta manera en Matlab teniendo el programa abierto) R= 1 2 3 4 0 -1 0 1 -1 1 -1 0 0 0 1 1 1 -1 1 0 (y esta matriz es el resultado que arroja, siendo en este caso particular, 1, 2 ,3 y 4 correspondientes a las variables A, B, C y D).
F(A,B,C,D) = CD+ B’D + AB’C + A’BC’
Ese sería básicamente el funcionamiento genérico.
Otro ejemplo podría ser:
En cuyo caso se tendría: R = minBool([4, 8, 10, 11, 12, 15],[9, 14])
R=
1
2
NaN 1
3 1
-1
1 NaN
-1
4 -1
NaN
-1
1
1
Siendo el resultado interpretado el siguiente: F(A,B,C,D) = BC’D’ + AB’D’ + ACD
El código del programa incluyendo comentarios del creador es el siguiente:
function result = minBool(numbers, resulttype) % MINBOOL Quine-McCluskey method for boolean function minimization % % R = minBool( N, V )
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
R - result matrix N - input arguments. N should be vector with integers V - visualization type 1) 1=normal; -1=inverse; NaN = not used 2) 1=normal; -1=inverse; 0 = not used Example R = minBool([5 13 14 26 30],1) R = 1 2 3 4 5 -1 NaN 1 -1 1 NaN 1 1 1 -1 1 1 NaN 1 -1 This function is distributed under GPL license (see code for details). Original authors information: Andrey Popov www.automatics.hit.bg minBool ver. 1.3, Copyright 2002-2010
release Sept 2002, Andrey Popov
Last update: 14 Feb 2010
[email protected]
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see
.
%% Input arguments check if (nargin==0) error('minBool:noinput','No input data'); end % % % %
The input argument is integer numbers, so the minimization is independant on the size of the boolean variables, i.e. we are not interested whether the real boolean variables are represented with 3 or 30 bits
numbers = round(abs(numbers)); v = size(numbers,2); numbers = numbers(:); %% Remove repeated input numbers -----------------------------------------S = numbers(1); for g = 2:v
if ~any(S == numbers(g)) S = [S numbers(g)]; end end numbers = sort(S); v = length(numbers); % Determine the number of involved boolean variables n = max(1,ceil(log2(max(numbers)+1))); % Create empty disjunction matrix s W = zeros(v,n); %% Convert the input numbers to binary -----------------------------------for i = 1:v % cycle over the numbers k = numbers(i); for j = 1:n % cycle over the bits p = 2^(n-j); if k >= p k = k - p; W(i,j) = 1; end end end %% Arange the numbers according to the number of '1' they have -----------w1 = [1:v; sum(W,2)']; % [no; num 1's] w1 = sortrows(w1',2); % sort by num 1's w = w1(:,1); G = [W(w,:) numbers(w)'];% arrange by num 1's %% Joining the numbers close in a boolean sence --------------------------extend=1; % stitched=1; % to be able to enter 'while' if v == 1 F = G; else while (stitched~=0) F = []; stitched = 0; G = [G zeros(v,1)]; ncomb = 0; for i=1:v % loop over all combinations if ~isinf(G(i,1)) % Inf on first position can appear only if we have 2 % combinations which are identical. Since this is covered % for the initial input variables, such case can only % occure after combining several variables and having % invariant bits. joined=0;
for j=(i+1):v % compare with all other combinations if ~isinf(G(j,1)) % allowed k = sum(abs(G(i,1:n)-G(j,1:n))); if k == 1 % difference by exactely 1 bit L = G(i,1:(n+extend)); % copy the combination p = find(G(i,1:n)-G(j,1:n)); % find the differing bit L(1,p) = -1; % mark it with -1 L = [L G(j,(n+1):(n+extend))]; % add the other combination F = [F; L];
% store in the pass
matrix F ncomb = ncomb + 1; stitched = stitched + 1;% mark that there was stitch joined = joined + 1; % G(i,n+extend+1) = 1; % mark the combinations as used G(j,n+extend+1) = 1; elseif k == 0 % could be only by 2 identical combinations % at later stage of stitching G(j,1)=inf; end end end if joined == 0 && G(i,n+extend+1) == 0 % the current combination cannot be joined with any % other L = G(i,1:(n+extend)); L = [L Inf*ones(1,extend)]; F = [F; L]; ncomb = ncomb + 1; % however this is a combination end end end % end of the cycle over the combinations if stitched == 0 % not a single combination pare found F = F(:,1:(n+extend)); % this removes the extra combination columns else extend = 2*extend; % the number of spaces to mark combinations is doubled end G = F; % not the combinations are written again in G v = ncomb; end end % end of the while cycle
%% Create the table ------------------------------------------------------% extend - max number of the involved input variables in the output % n - number of boolean variables
% v - number of derived combinations % y - number input combinations y = length(numbers); E = zeros(v+2,y+3); % 0 0 0 i i i i i i % 0 0 0 t t t t t t % x n u ; ; ; ; ; ; % x n u ; ; ; ; ; ; % x n u ; ; ; ; ; ; % x n u ; ; ; ; ; ; combination uses the
% create empty table of the form i i – input combinations t t – is this variable included ; x – output combination ; n – number of the included base variables ; u – is this output combination used ; ; - 1/0 depending on whether the output corresponding input combination
E(1,3+(1:y)) = numbers; E(2+(1:v),1) = [1:v]'; % Fill with 1/0 depending on the variables involved for g = 1:v for j = n+(1:extend) if ~isnan(F(g,j)) for i = 1:y if E(1,i+3) == F(g,j) E(g+2,i+3) = 1; end end end end end
%% Mark the base input variables (those involved in only 1 output)--------marked=0; for j = 3+(1:y) if E(2,j) ~= 1 % the input variable is not yet involved in an output one if sum(E(2+(1:v),j)==1) == 1 % this is a base variable E(2,j) = 1; marked = marked + 1; p = find(E(2+(1:v),j)==1); E(2+p,3) = 1; % mark the output variable as used for h = 1:y if E(2+p,h+3) == 1 % this output var. includes also other input if E(2,h+3) == 0 % not yet marked input E(2,h+3) = 1; marked = marked + 1; end end end end end end
%% Mark the non-base variables -------------------------------------------while marked < y
E(2+(1:v),2) = zeros(v,1); for g=1:v if E(g+2,3)==0 p=0; % num included, but non-marked non-base variables for j=3+(1:y) if E(g+2,j)==1 && E(2,j)==0 % output combination, containing the % non-marked, non-base boolean combination p=p+1; end end % % % % q c
Calculate extra weighing coef. based on the number of boolean combination describing the particular combination (q) and number of inverted (negated) boolean variables (c) = sum(F(g,1:n)<0); = sum(F(g,1:n)==0);
E(g+2,2) = p + q/(n+1) + c/(10*n); % Thus the choice of this combination is done depending upon % 1) how many of the input numbers it describes % 2) with how mnay boolean variables it is described % 3) how many of the boolean variables are inverted end end maks = max(E(:,2)); g=1; while E(g+2,2)
%% Generate the output variables -----------------------------------------Z=[]; % matrix for the output variables output = 0; for g = 1:v if E(g+2,3) == 1 Z = [Z; F(g,:)];
output = output + 1; end end Z = Z(:,1:n); %% Forming the result ===================================================== if nargin == 1 resulttype = 2; end % Define how the result is stored % T : x F : inv(x) N : if resulttype == 2 T = 1; F = -1; N = 0; else T = 1; F = -1; N = NaN; end B = Z; B(Z==-1) = N; B(Z==1) = T; B(Z==0) = F; result = [1:n; B];
Pero para entrar más en detalle con el funcionamiento especifico del programa se haría necesaria la comprensión del lenguaje utilizado para su creación, ámbito en el cual por el momento el estudiante carece de destreza.