
クワイン・マクラスキーアルゴリズム(QMC )は、プライムインプリカント法または表計算法としても知られ、ブール関数の最小化に使用される方法で、1952 年にウィラード・V・クワインによって開発され[ 1 ] [ 2 ] 、 1956 年にエドワード・J・マクラスキーによって拡張されました[ 3 ]。このアプローチの一般原理は、1878 年に論理学者ヒュー・マッコールによって既に実証されており[ 4 ] [ 5 ] [ 6 ]、1937 年にアーチー・ブレイクによって証明され[ 7 ] [ 8 ] [ 9 ] [ 6 ]、1954 年にエドワード・W・サムソンとバートン・E・ミルズによって再発見され[ 10 ] [ 6 ]、1955 年にレイモンド・J・ネルソンによって再発見されました[ 11 ] [ 6 ]。また、1955年には、Paul W. AbrahamsとJohn G. Nordahl [ 12 ]、Albert A. MullinとWayne G. Kellner [ 13 ] [ 14 ] [ 15 ] [ 16 ]が、この方法の10進数版を提案した。[ 17 ] [ 14 ] [ 15 ] [ 16 ] [ 18 ] [ 19 ] [ 20 ] [ 21 ]
クワイン・マクラスキーアルゴリズムは、機能的にはカルノー図法と同一ですが、表形式であるためコンピュータアルゴリズムでの使用効率が高く、またブールFの最小形式に到達したことを決定論的に確認する方法も提供します。
クワイン=マクラスキーアルゴリズムは次のように動作します。
4 変数を超える場合、カルノー図よりも実用的ではあるものの、クワイン-マクラスキー アルゴリズムは、解決する問題がNP 完全であるため、使用範囲が限られています。[ 22 ] [ 23 ] [ 24 ]クワイン-マクラスキー アルゴリズムの実行時間は、変数の数に対して指数関数的に増加します。n個の変数を持つ関数の場合、プライム インプリカントの数は最大で次のようになります。例えば、32個の変数の場合、 534 × 10 12を超える素因数が存在する可能性があります。多数の変数を持つ関数は、最適ではない可能性のあるヒューリスティック法で最小化する必要があります。1995 年当時、その事実上の標準はEspresso ヒューリスティックロジック最小化ツールでした。[ 26 ]関数の自然なクラスの一つについて、すべての主インプリカントを見つける正確な複雑さはよりよく理解されています。Milan Mossé、Harry Sha、およびLi-Yang Tanは、連言標準形の式のすべての主インプリカントを見つけるためのほぼ最適なアルゴリズムを発見しました。[ 27 ]
アルゴリズムのステップ 2 は、集合被覆問題を解くことに相当します。[ 28 ] このアルゴリズムのステップでは、この問題のNP 困難なインスタンスが発生する可能性があります。 [ 29 ] [ 30 ]
この例では、入力は4つの変数を持つブール関数です。これは次のように評価されます値についてそして、未知の値に評価されますそして、そしてその他の場所では(これらの整数は入力用にバイナリ形式で解釈されます)(表記の簡潔さのため)。これらは「最小項」と呼ばれます。このすべての情報を次のように記述してエンコードします。
この式は、最小項に対して出力関数 f が 1 になることを示しています。そして(「m」項で示される)出力については気にしないそして組み合わせ(「d」項で示される)。総和記号これは、合計対象となるすべての項の論理和(論理OR、または論理和)を表します。
まず、関数を表として記述します(ここで「x」は「気にしない」を表します)。
この表から、関数が1になる最小項(無関係な項を除く)を合計するだけで、標準的な積和の式を簡単に作成できます。
これは最小値ではありません。そこで最適化するために、まず評価値が 1 になるすべての最小項を最小項テーブルに格納します。また、このテーブルには、最小項と組み合わせることができるように、不確定項 (括弧内の名前) も追加されます。
この時点で、隣接するグループの他の最小項と最小項を組み合わせ始めることができます。つまり、n 番目のグループの最小項を (n+1) 番目のグループと比較します。したがって、1 の数が 1 つだけの m4 最小項については、1 の数が 2 つある m9、m10、m12 と比較します。
2 つの項の差が 1 桁のみの場合、その桁はダッシュに置き換えられ、その桁は重要ではないことを示します。たとえば、1000と は1001と組み合わせることができ100-、これは、両方の最小項が最初の桁が で1、次の 2 桁が であることを意味します0。これ以上組み合わせることができない項には、アスタリスク ( * ) が付けられます。
サイズ 2 からサイズ 4 に変更する場合は、-3 番目のビット値として扱います。-まず を一致させます。 項は積を表し、2 つの積項を組み合わせるには、同じ変数を持つ必要があります。一方の項では変数の 1 つが反転され、もう一方の項では反転されていない必要があります。残りの変数は一致する必要があります。したがって、2 つの項を一致させるには-、 が揃い、他の桁のうち 1 つを除くすべてが同じである必要があります。たとえば、-110と は-100組み合わせて を得ることができます。-1-0同様に、-110と を組み合わせ-010て を得ることができます--10が、-110と は組み合わせる011-ことができません。は BCD' に対応し 、 は A'BC に対応します。BCD' + A'BC は積項と同等ではありません。--110011-
注:この例では、サイズ4のインプリカント表の項はこれ以上結合できません。一般に、このプロセスは2のべき乗のサイズ(サイズ8、16など)で、これ以上項を結合できなくなるまで続けられます。
これ以上項を組み合わせることはできないため、この時点で必須の主項インプリカント表を作成します。横には、先ほど生成された主項インプリカント(前のステップで「*」マークが付いているもの)を配置し、上には先に指定した最小項を配置します。不要な項は、入力として必要ではないため、このセクションでは省略し、上には配置しません。
本質的なプライムインプリカントを見つけるには、「✓」が1つだけ付いている列を探します。列に「✓」が1つだけ付いている場合、それは最小項が1つのプライムインプリカントでしかカバーできないことを意味します。このプライムインプリカントが本質的なプライムインプリカントです。
例えば、最初の列の最小項4には「✓」が1つしかありません。これは、m(4,12)が必須であることを意味します(そのため「# 」でマークされています)。最小項15にも「✓」が1つしかないため、m(10,11,14,15)も必須です。これで、「✓」が1つあるすべての列がカバーされました。最小項m(4,12)とm(10,11,14,15)を含む行は、それらがカバーするすべての列とともに削除できます。
2 番目の主インプリカントは 3 番目と 4 番目で「カバー」でき、3 番目の主インプリカントは 2 番目と 1 番目で「カバー」できるため、どちらも必須ではありません。主インプリカントが必須である場合は、当然のことながら、最小化されたブール方程式にそれを含める必要があります。場合によっては、必須の主インプリカントがすべての最小項をカバーしていないため、チャート削減のための追加の手順を使用できます。最も単純な「追加の手順」は試行錯誤ですが、より体系的な方法はペトリック法です。この例では、必須の主インプリカントがすべての最小項を処理していないため、この場合、必須のインプリカントを 2 つの非必須のインプリカントのいずれかと組み合わせることで、1 つの方程式が得られます。
または
これら2つの最終的な方程式は、元の冗長な方程式と機能的に同等である。
以下の擬似コードは、ブール関数の最小項のリストが与えられた場合に、主項を再帰的に計算します。これは、考えられるすべての最小項をマージし、マージ済みの最小項を除外していくことで実現されます。この処理は、これ以上最小項をマージできなくなるまで繰り返され、最終的に関数の主項が求められます。
// 最小項のリストから主項を計算します。 // 各最小項は「1001」、「1010」などの形式で、文字列で表現できます。 関数getPrimeImplicants(list minterms)は primeImplicants ← 空のリスト merges ← minterms の数と同じ長さの新しいブール配列を作成し、それぞれを false に設定します マージ数 ← 0 mergedMinterm、minterm1、minterm2 ← 空の文字列 i = 0からlength(minterms)まで繰り返す c = i + 1からlength(minterms)まで繰り返す minterm1 ← minterms[i] minterm2 ← minterms[c] // 2つの最小項をマージできるかどうかを確認します CheckDashesAlign(minterm1, minterm2) && CheckMintermDifference(minterm1, minterm2)の場合、 mergedMinterm ← MergeMinterms(minterm1, minterm2) primeImplicants に mergedMinterm が含まれていない場合、 primeImplicants.Add(mergedMinterm) numberOfMerges ← numberOfMerges + 1 merges[i] ← true マージ[c] ← true // マージされていない最小項を、素項であるためフィルタリングします。また、重複も削除します。 j = 0からlength(minterms)まで繰り返す。もしmerges [j] == false かつ primeImplicants Does Not Contain minterms[j]ならば primeImplicants.Add(minterms[j]) // マージが行われていない場合は、すべての主インプリカントが見つかったので、戻ります。そうでない場合は、 // 最小項をマージし続ける。 numberOfmerges == 0の場合は primeImplicants を返し、そうでない場合は getPrimeImplicants(primeImplicants)を返す。
この例では、CheckDashesAlignおよびCheckMintermDifference関数は、2 つの最小項をマージできるかどうかを判断するために必要なチェックを実行します。関数は、MergeMinterms最小項をマージし、必要に応じてダッシュを追加します。以下のユーティリティ関数は、各最小項が文字列で表現されることを前提としています。
関数MergeMinterms(minterm1, minterm2)は mergedMinterm ← 空の文字列 i = 0からlength(minterm1)まで繰り返す //ビットが異なる場合は、それをダッシュに置き換えます。そうでない場合は、そのビットはマージされた最小項に残ります。 minterm [i] != minterm2[i]ならば mergedMinterm ← mergedMinterm + '-' それ以外 mergedMinterm ← mergedMinterm + minterm1[i] マージされたミニタームを返しますfunction CheckDashesAlign(minterm1, minterm2)は、 i = 0からlength(minterm1)まで実行されます。 // 一方の最小項にダッシュがあり、もう一方にない場合、最小項をマージすることはできません。 minterm1[i] != '-' && minterm2[i] == '-'の場合、 false を 返す。true を返す。 関数CheckMintermDifference(minterm1, minterm2)は // minterm1 と minterm2 は、現在見つかったすべての素インプリカントとマージされた素インプリカントを表す文字列です。 // 最小項。例として「01--」や「10-0」などがあります。 m1、m2 ← minterm1とminterm2の整数表現からハイフンを取り除き、0に置き換えます // ^ ここはビットごとの XOR です res ← m1 ^ m2 return res != 0 && (res & res - 1) == 0
以下の擬似コードは、2つのセクションに分けることができます。
主インプリカントチャートは、各キーが主インプリカントであり、対応する値が空の文字列である辞書で表現できます。この空の文字列は、この手順が完了するとバイナリ文字列を格納します。バイナリ文字列の各ビットは、主インプリカントチャート内の目盛りを表すために使用されます。主インプリカントチャートは、以下の手順で作成できます。
\d文字コードに置き換えます。これにより、各最小項に対して一致するものを検索できる正規表現が作成されます。"1"辞書内の対応する文字列に を追加します。そうでない場合は、 を追加します"0"。上記のアルゴリズムを擬似コードで表すと次のようになります。
function CreatePrimeImplicantChart(list primeImplicants, list minterms) primeImplicantChart ← キーが文字列型で値が文字列型の新しい辞書 // 主項をキー、空文字列を値とする空のチャートを作成します。 i = 0からlength(primeImplicants)まで繰り返す // チャートに新しい主インプリカントを追加します。 primeImplicantChart.Add(primeImplicants[i], "") for i = 0 to length(primeImplicantChart.Keys) do primeImplicant ← primeImplicantChart.Keys[i] // "-" を "\d" に変換します。これを使用して、上の目盛りの行を検索できます。 regularExpression ← ConvertToRegularExpression(primeImplicant) j = 0からlength(minterms)まで繰り返す // 正規表現と最小項が一致する場合は 1 を追加し、そうでない場合は 0 を追加します。 regularExpression.matches(minterms [ j])ならば primeImplicantChart[primeImplicant] += "1" それ以外 primeImplicantChart[primeImplicant] += "0" // 主インプリカントチャートが完成したので、完成したチャートを返します。 プライムインプリカントチャートを返す
ユーティリティ関数 はConvertToRegularExpression、主インプリカントを正規表現に変換し、インプリカントと最小項との一致をチェックするために使用されます。
function ConvertToRegularExpression(string primeImplicant) 正規表現 ← 新しい文字列 for i = 0 to length(primeImplicant) do if primeImplicant[i] == "-" then // リテラル文字「\d」を追加します。 regularExpression += @"\d" それ以外 regularExpression += primeImplicant[i] 正規表現を返す
上記で定義した関数 を使用するとCreatePrimeImplicantChart、辞書内の値を列ごとに反復処理するだけで、本質的な素インプリカントを見つけることができます"1"。 が 1 つ見つかった場合、それは本質的な素インプリカントです。このプロセスは、以下の擬似コードで説明されています。
function getEssentialPrimeImplicants(Dictionary primeImplicantChart, list minterms) essentialPrimeImplicants ← 新しいリスト mintermCoverages ← ディクショナリ内のすべての値を含むリスト i = 0からlength(ticks)まで繰り返す mintermCoverage ← ticks[i] j = 0からlength(mintermCoverage)まで繰り返す。mintermCoverage [j] == "1"の場合、 essentialPrimeImplicants.Add(primeImplicantChart.Keys[i]) essentialPrimeImplicantsを返します
上記のアルゴリズムを使用すると、必須のプライムインプリカントを標準形式(つまり)に変換し、論理ORでインプリカントを分離することで、最小化されたブール式を見つけることができます。擬似コードは、必須のプライムインプリカントがブール式全体を網羅することを前提としています。-100 -> BC'D'
[...] 式を最も単純な形に還元することが明白でない場合は、式の否定形を取り、それを還元し、その後肯定形に戻すことで容易になる場合があります。 [...]
パース
とその弟子たちに知られていた[...] これは
、ジョンズ・ホプキンス大学
のメンバーによる『Studies in Logic』、1883 年の数箇所で言及されている
[...]
(ii+60ページ)
[...] この論文は、マサチューセッツ工科大学でスイッチング回路を研究していた2人の学生の研究に基づいていることを記すのは喜ばしいことです。彼らは独自にこの方法について議論し、その後協力して授業メモを作成しました。PW
AbrahamとJG Nordahl
[...]
{{cite book}}ISBN / 日付の不一致 (ヘルプ) (xviii+686ページ) (注:本書に収録されている十進法に関する最初の主要な解説は、「コールドウェルの十進表」という誤解を招く名称で呼ばれることがあります。)[...] この論文の結果は、SH Caldwell によるより入手しやすい
書籍に掲載されています [...]。この書籍では、著者は、
10 進数の操作の開発について
Mullin と Kellner
に功績を認めています。
(1ページ)
{{cite book}}: CS1 maint: 場所が不明な出版社 (リンク) (4ページ) (注: 一部の資料では著者が「PW Abraham」と「IG Nordahl 」と記載されており、タイトルは「 Modified McCluskey–Quine Reduction Procedure」とも記載されています。 )[...] 1955 年、デジタル化されたシュライブヴァイゼ ウムゲシュテルト (
PW エイブラハムと IG ノルダール
、[
コールドウェル
])。 [...]
(注:1973年版の第2版も存在する。)
{{cite book}}: CS1メンテナンス: ISBNエラーを無視しました (リンク) (519ページ){{cite book}}ISBN /日付の不一致(ヘルプ)(viii+635ページ)(注:本書は1969年にチン・ジによって再版されました。)