if / elseブロックで真理値表を最小にする方法


20

真理値表を取得して、それをコンパクトなifブロックに変換するにはどうすればよいですか?

たとえば、AとBが条件であり、x、y、zが可能なアクションであるこの真理値表があるとします。

A B | x y z
-------------
0 0 | 0 0 1
0 1 | 0 0 1
1 0 | 0 1 0
1 1 | 1 0 0

ブロックの場合、これは以下に変換できます。

if(A)
{
    if(B)
    {
        do(x)
    }
    else
    {
        do(y)
    }
}
else
{
    do(z)
}

これは簡単なサンプルですが、多くの場合、さまざまな方法で組み合わせてさまざまな出力を生成するいくつかの条件があり、ifブロックでロジックを表現する最もコンパクトでエレガントな方法を見つけるのは困難です。


10
カルノーマップをifelseカスケードに変換するということですか?
ラチェットフリーク

@ラチェット:私はそうではないようですね?以前は知りませんでした。いくつかの読書をする必要がありますが、それでも私のためにそれを行うアプリは、私の手作りの結果を確認するために、他に何もないとしても素晴らしいでしょう。
フアン

1
@jalaynのほとんどのkarnaughツールはデジタル回路用です。これらは、質問の内容とは異なるヒューリスティックを持っています
ラチェットフリーク

1
@jsoldi:あなたが受け取る答えは、あなたが尋ねるサイトに依存します。if-then-elseブロックを含む特定のコードフラグメントに関するコメントを探している場合、それは確かに Code review(beta)にますStackoverflowはツールとテクニックを教えます。Programmers.SEでは、人間が理解するために、またはより高速に実行するために、論理ステートメントを書き直すことを気にする必要があるかどうかを教えてくれます。
rwong

2
ツールの推奨事項はトピック外ですが、質問を「これ行うはどうすればよいですか?」に変更した場合 トピックになります。ソフトウェアの推奨が必要な場合は、softwarerecs.stackexchange.comにアクセスしてください。
キリアンフォス14

回答:


14

Karnaughマップから設計している場合、コードも同じように見える場合があります。

//                   a      b
def actionMap = [ false: [false: { z() },
                          true:  { z() }],
                  true:  [false: { x() },
                          true:  { y() }]]

actionMap[a][b]()

これは何語ですか?Javascript?Python?
TheLQ

pythonではなくTheLQはjavascriptである可能性があります。しかし、Pythonで書かれていれば非常に似ているでしょう
grizwako

@TheLQ:それはGroovyです。それが最近私がやっていることだからです。おそらくRubyもそうです。JavascriptまたはPythonまたはLUAまたはPerlのコードは非常に似ています。
ケビンクライン

2
もちろん、これには、評価が不要な場合でもbを評価する効果があります。たぶんそれは問題なのかもしれませんが、そうでないかもしれません。
仮名14

@kevinclineください、かなりください、「LUA」ではなく「Lua」。:)
マシャド

4

C#.NETでは、ディクショナリクラスを使用して、次のようにIF ELSEを使用せずに結果を取得できます。これに関する素晴らしい点は次のとおりです。

  1. 読める
  2. 新しいキーは一意になります(それ以外の場合、エラーが発生します)
  3. 順序は関係ありません
  4. エントリの追加または削除が簡単

辞書クラスに相当するものがない場合は、バイナリルックアップ/検索関数で同じことを行うことができます。

//A B | x y z
//-------------
//0 0 | 0 0 1
//0 1 | 0 0 1
//1 0 | 0 1 0
//1 1 | 1 0 0
// Create a Dictionary object and populate it
Dictionary<string, string> _decisionTable = new Dictionary<string, string>() { 
    { "0,0", "0,0,1" }, 
    { "0,1", "0,0,1" }, 
    { "1,0", "0,1,0" }, 
    { "1,1", "1,0,0"} 
};

//usage example: Find the values of X,Y,Z for A=1,B=0
Console.WriteLine(_decisionTable["1,0"]);
Console.Read();

1
私はこのソリューションが好きです、唯一の変更は、Dictionary <string、string>の代わりにDictionary <Tuple <bool、bool>、Tuple <bool、bool、bool>を使用することです。その後、Tuplesがこれを行うため、結果を検索して分解するための文字列を作成する必要はありません。
Lyise 14

@Lyise、発言ありがとうございます。あなたは絶対に正しいです。機会があればあなたの良さを取り入れるべきです。
NoChance 14

2

欲しいのはReteアルゴリズムです。これにより、一連のルールが自動的にコーミングされ、記述した方法でツリーに優先順位が付けられます。

実行速度が不可欠な非常に大規模(数百万のルール)でこれを行う多くの商用「ルールエンジン」システムがあります。


2

ここにあなたのライブラリがあります:)そして、あなたは完全なK-テーブルを渡す必要はありません、あなたが興味を持っているフィールドのみ:)それは真理値表のAND演算子を仮定しています。さらに多くの演算子を使用する場合は、書き換えることができるはずです。引数はいくつでも指定できます。で記述されpython、テストされています。

def x():
    print "xxxx"

def y():
    print "yyyyy"

def z(): #this is default function
    print "zzzzz"

def A():
    return 3 == 1

def B():
    return 2 == 2


def insert(statements,function):
    rows.append({ "statements":statements, "function":function })

def execute():
    for row in rows:
        print "==============="
        flag = 1

        for index, val in enumerate(row["statements"]):
            #for first pass of lopp, index is 0, for second its 1....
            #if any function returns result different than one in our row, 
            # we wont execute funtion of that row (mark row as not executable)
            if funcs[index]() != val:
                flag = 0

        if flag == 1:
            #we execute function 
            row["function"]()
        else: z() #we call default function


funcs = [A,B]  #so we can access functions by index key
rows = []

insert( (0,0), y)
insert( (0,1), y)
insert( (1,0), x)
insert( (1,1), x)
insert( (0,1), x)

execute()

1

入力を単一の値にマップしてから、スイッチをオンにします。

#define X(a, b) (!!(a) * 2 + !!(b))
switch(X(A, B)) {
case X(0, 0):
    ...
    break;
case X(0, 1):
    ...
    break;
case X(1, 0):
    ...
    break;
case X(1, 1):
    ...
    break;
}
#undef X

1

関数ポインターを含むルックアップテーブルは、状況によってはうまく機能します。たとえば、Cでは、次のようなことができます。

typedef void(*VoidFunc)(void);

void do(int a, int b)
{
    static VoidFunc myFunctions[4] = {z, z, y, x}; // the lookup table

    VoidFunc theFunction = myFunctions[ a * 2 + b ];
    theFunction();
}

これは、テーブル内のエントリの数が2 ^^ nである必要があるため、入力の数が比較的少ない場合に適したソリューションです。nは入力の数です。7または8の入力は管理しやすいかもしれませんが、10または12の入力は見苦しくなります。入力数が多い場合は、最初に他の手段(カルノーマップなど)で単純化してみてください。


0

「Gorgeous Karnaugh」ソフトウェアを見てください。サンプルとして非常に正確な真理値表を受け入れ、分析ブール式の定義を受け入れ、Luaスクリプトを受け入れて真理値表を作成できます。次に、「ゴージャスカルノー」ソフトウェアは、手動または「エスプレッソ」ロジックミニマイザーを使用して最小化することができる入力のKマップを描画し、C / C ++および一部のハードウェア言語の出力を生成します。「ゴージャスカルノー」の機能概要ページをご覧ください-http : //purefractalsolutions.com/show.php?a=xgk/ gkm


これは私が必要とするものによく似ていますがif、真理値表を入力した後、空のs 以外を表示するC / C ++コードを取得できませんでした。
フアン

はい、論理関数の最小化のために設計されたツール-真理値表を入力した後、論理関数を最小化する必要があります(PoS / SoP-0 / by 1)。C ++コードは、最小化後の「最小化結果」ウィンドウにあります。
ペトルチオ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.