Petrick's methodIn Boolean algebra, Petrick's method[1] (also known as Petrick function[2] or branch-and-bound method) is a technique described by Stanley R. Petrick (1931–2006)[3][4] in 1956[5][6] for determining all minimum sum-of-products solutions from a prime implicant chart.[7] Petrick's method is very tedious for large charts, but it is easy to implement on a computer.[7] The method was improved by Insley B. Pyne and Edward Joseph McCluskey in 1962.[8][9] Algorithm
PseudocodeThe algorithm above can be implemented with the C# as shown below: private string DoPetriksMethod(
Dictionary<string, string> PIchart,
List<string> epis,
List<string> primeImplicants,
List<string> minterms)
{
PIchart = RemoveEPIs(PIchart, epis, minterms);
string minimisedExpression;
Dictionary<char, string> termsImplicantMapping = MapTermsToImplicants(primeImplicants);
List<Bracket> productOfSums = GetProductOfSums(termsImplicantMapping, PIchart);
string[] sumOfproducts = GetSumOfProducts(productOfSums);
string minProduct = GetMinProduct(sumOfproducts);
minimisedExpression = GetFinalExpression(termsImplicantMapping, minProduct);
return minimisedExpression;
}
private static Dictionary<char, string> MapTermsToImplicants(List<string> primeImplicants)
{
var mapping = new Dictionary<char, string>();
char minChar = (char)(primeImplicants[0].Length + 65);
for (var i = 0; i < primeImplicants.Count; i++)
{
mapping.Add(minChar, primeImplicants[i]);
minChar++;
}
return mapping;
}
private static List<Bracket> GetProductOfSums(Dictionary<char, string> termToImplicantMap, Dictionary<string, string> primeImplicantChart)
{
var productOfSums = new List<Bracket>();
List<Bracket> sumsToAdd;
string primeImplicant;
foreach (string key in primeImplicantChart.Keys)
{
primeImplicant = primeImplicantChart[key];
for (var i = 0; i < primeImplicant.Length; i++)
{
if (primeImplicant[i] == '1')
{
sumsToAdd = GetSumsToAdd(primeImplicantChart, termToImplicantMap, key, i);
AddSumsToList(productOfSums, sumsToAdd);
}
}
}
return productOfSums;
}
private static void AddSumsToList(List<Bracket> productOfSums, List<Bracket> sumsToAdd)
{
foreach (Bracket s in sumsToAdd)
{
if (!productOfSums.Contains(s))
{
productOfSums.Add(s);
}
}
}
private static List<Bracket> GetSumsToAdd(Dictionary<string, string> PIchart, Dictionary<char, string> termToImplicantMap, string key, int positionWithinKey)
{
var sumsToAdd = new List<Bracket>();
Bracket sum;
string implicant;
char term1;
char term2;
for (var i = 0; i < PIchart.Keys.Count; i++)
{
implicant = PIchart.Keys.ToArray()[i];
if (PIchart[implicant][positionWithinKey] == '1')
{
term1 = GetTermFromImplicant(termToImplicantMap, key);
term2 = GetTermFromImplicant(termToImplicantMap, implicant);
if (term1 != term2)
{
sum = new Bracket(term1, term2);
sumsToAdd.Add(sum);
}
}
}
return sumsToAdd;
}
private static char GetTermFromImplicant(Dictionary<char, string> termToImplicantMap, string implicant)
{
string[] implicants = termToImplicantMap.Values.ToArray();
char[] keys = termToImplicantMap.Keys.ToArray();
for (var i = 0; i < termToImplicantMap.Values.Count; i++)
{
if (implicants[i] == implicant)
{
return keys[i];
}
}
throw new Exception("Could not map implicant to key");
}
private static string[] GetSumOfProducts(List<Bracket> productOfSums)
{
Bracket b1;
Bracket b2;
Bracket mergedTerm;
bool merged = true;
while (merged)
{
merged = false;
for (var i = 0; i < productOfSums.Count - 1; i++)
{
for (var c = i + 1; c < productOfSums.Count; c++)
{
b1 = productOfSums[i];
b2 = productOfSums[c];
if (b1.term1 == b2.term1 != (b1.term2 == b2.term2) != (b1.term1 == b2.term2) != (b1.term2 == b2.term1))
{
mergedTerm = MergeBrackets(b1, b2);
productOfSums.Add(mergedTerm);
productOfSums.Remove(b1);
productOfSums.Remove(b2);
merged = true;
i = c + 1;
c = i + 1;
}
}
}
}
List<List<string>> stringProducts = ConvertBracketsToString(productOfSums);
List<List<string>> sumOfProducts = RecursiveDistributiveLaw(stringProducts);
return sumOfProducts[0].ToArray();
}
private static Bracket MergeBrackets(Bracket b1, Bracket b2)
{
var b = new Bracket();
if (b1.term1 == b2.term1)
{
b.term1 = b1.term1;
b.term2 = b1.term2 + b2.term2;
return b;
}
else
{
b.term1 = b1.term2;
b.term2 = b1.term1 + b2.term2;
return b;
}
}
private static List<List<string>> ConvertBracketsToString(List<Bracket> brackets)
{
var result = new List<List<string>>();
List<string> tmp;
foreach (Bracket b in brackets)
{
tmp = new List<string> { b.term1, b.term2 };
result.Add(tmp);
}
return result;
}
private static List<List<string>> RecursiveDistributiveLaw(List<List<string>> brackets)
{
var lls = new List<List<string>>();
if (brackets.Count > 1)
{
lls.Add(SingleDistributiveLaw(brackets[0], brackets[1]));
brackets.RemoveAt(0);
brackets.RemoveAt(0);
lls.AddRange(brackets);
return RecursiveDistributiveLaw(lls);
}
else
{
return brackets;
}
}
private static List<string> SingleDistributiveLaw(List<string> b1, List<string> b2)
{
var lls = new List<string>();
for (var i = 0; i < b1.Count; i++)
{
for (var j = 0; j < b2.Count; j++)
{
lls.Add(ApplyDistributiveLaw(b1[i], b2[j]));
}
}
return lls;
}
private static string ApplyDistributiveLaw(string a, string b)
{
string tempResult = a + b;
string finalResult = "";
foreach (char c in tempResult)
{
if (!finalResult.Contains(c))
{
finalResult += c;
}
}
return finalResult;
}
private static string GetMinProduct(string[] sumOfProducts)
{
string minProduct = sumOfProducts[0];
foreach (string p in sumOfProducts)
{
if (p.Length < minProduct.Length)
{
minProduct = p;
}
}
return minProduct;
}
private string GetFinalExpression(Dictionary<char, string> termToImplicantMap, string minProduct)
{
string subExpression;
string implicant;
string result = "";
for (var i = 0; i < minProduct.Length; i++)
{
implicant = termToImplicantMap[minProduct[i]];
subExpression = ConvertImplicantToExpression(implicant);
result += subExpression;
if (i < minProduct.Length - 1)
{
result += " + ";
}
}
return result;
}
The following code snippet assumes access to the struct Bracket
{
public Bracket(char term1, char term2)
{
// Sorting into alphabetical order. This can be done as OR is commutative.
if (term1 < term2)
{
this.term1 = term1.ToString();
this.term2 = term2.ToString();
}
else
{
this.term1 = term2.ToString();
this.term2 = term1.ToString();
}
}
// The two terms that make up the brackets. These are assigned to when the
// product of sums is created in Petrick's method.
public string term1;
public string term2;
}
Example of Petrick's methodFollowing is the function we want to reduce:[10] The prime implicant chart from the Quine-McCluskey algorithm is as follows:
Based on the ✓ marks in the table above, build a product of sums of the rows. Each column of the table makes a product term which adds together the rows having a ✓ mark in that column: (K+L)(K+M)(L+N)(M+P)(N+Q)(P+Q) Use the distributive law to turn that expression into a sum of products. Also use the following equivalences to simplify the final expression: X + XY = X and XX = X and X + X = X = (K+L)(K+M)(L+N)(M+P)(N+Q)(P+Q) = (K+LM)(N+LQ)(P+MQ) = (KN+KLQ+LMN+LMQ)(P+MQ) = KNP + KLPQ + LMNP + LMPQ + KMNQ + KLMQ + LMNQ + LMQ Now use again the following equivalence to further reduce the equation: X + XY = X = KNP + KLPQ + LMNP + LMQ + KMNQ Choose products with fewest terms, in this example, there are two products with three terms: KNP LMQ Referring to the prime implicant table, transform each product by replacing prime implicants with their expression as boolean variables, and substitute a sum for the product. Then choose the result which contains the fewest total literals (boolean variables and their complements). Referring to our example: KNP expands to A'B' + BC' + AC where K converts to A'B', N converts to BC', etc. LMQ expands to A'C' + B'C + AB Both products expand to six literals each, so either one can be used. In general, application of Petrick's method is tedious for large charts, but it is easy to implement on a computer.[7] Notes
References
Further reading
External links
|
Portal di Ensiklopedia Dunia