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
Karnaugh 맵 을 ifelse 캐스케이드로 변환하는 것을 의미 합니까?
래칫 괴물

@ratchet : 내가하지 않는 것 같아? 나는 그들에 대해 전에 몰랐다. 약간의 독서를해야하지만 여전히 나를 위해 그것을 할 앱은 내 손으로 결과를 확인하는 것이 좋을 것입니다.
Juan

1
@jalayn 대부분의 karnaugh 도구는 디지털 회로 용입니다. 그것들은 질문에 관한 것과는 다른 휴리스틱을 가지고 있습니다
ratchet freak

1
@jsoldi : 귀하가받는 답변은 귀하가 요청한 사이트에 따라 다릅니다. if-then-else 블록을 포함하는 특정 코드 조각에 대한 의견을 찾고 있다면 분명히 Code review (beta)에 속합니다 . Stackoverflow 는 도구와 기술을 알려줍니다. 프로그래머들은 SE를 통해 사람들이 이해하기 위해 또는 더 빠른 실행을 위해 논리 문을 다시 작성하는 것에 대해 걱정하지 않아야하는지 여부를 알려줄 것입니다.
rwong

2
도구 권장 오프 주제,하지만 당신은에 질문을 변경하는 경우 "어떻게 수 있습니다 나는 이렇게?" 주제에 관한 것입니다. 소프트웨어 권장 사항을 원하면 softwarerecs.stackexchange.com으로 이동하십시오.
Kilian Foth

답변:


14

Karnaugh 맵에서 디자인하는 경우 코드도 다음과 같이 보일 수 있습니다.

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

actionMap[a][b]()

이것이 무슨 언어 지? 자바 스크립트? 파이썬?
TheLQ

파이썬이 아닌 LQ는 자바 스크립트 일 수 있습니다. 그러나 그것은 파이썬으로 작성된다면 매우 유사 할 것입니다
grizwako

@ TheLQ : Groovy입니다. 요즘 내가하고있는 일이며 아마도 루비 일 것입니다. Javascript, Python, LUA 또는 Perl의 코드는 매우 유사합니다.
케빈 클라인

2
물론 이것은 평가가 필요하지 않은 경우에도 b를 평가하는 효과가 있습니다. 어쩌면 문제 일 수도 있고 아닐 수도 있습니다.
가명

@kevincline 제발, 제발, "LUA"가 아니라 "Lua"를 부탁드립니다. :)
Machado

4

C # .NET에서는 Dictionary 클래스를 사용하여 다음과 같이 IF ELSE없이 결과를 얻을 수 있습니다. 이에 대한 좋은 점은 다음과 같습니다.

  1. 읽을 수있다
  2. 새 키는 고유합니다 (그렇지 않으면 오류가 발생 함)
  3. 순서는 중요하지 않습니다
  4. 쉬운 항목 추가 또는 제거

Dictionary Class에 해당하지 않는 경우 이진 조회 / 검색 기능에서 동일한 기능을 수행 할 수 있습니다.

//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

@Lyise, 귀하의 의견에 감사드립니다. 당신은 절대적으로 맞습니다. 나는 기회를 얻을 때 당신의 좋은 점을 통합해야합니다.
NoChance

2

당신이 원하는 것은 Rete 알고리즘 입니다. 이렇게하면 일련의 규칙이 자동으로 결합되어 사용자가 설명하는 방식으로 규칙이 트리에 우선 순위로 지정됩니다.

실행 속도가 필수적인 대규모 (수백만 개의 규칙)에서이를 수행하는 많은 상용 "규칙 엔진"시스템이 있습니다.


2

여기에 라이브러리가 있습니다 :) 그리고 당신은 당신이 관심있는 필드 만 전체 K 테이블을 전달할 필요가 없습니다. 더 많은 연산자를 사용하려면 다시 작성할 수 있어야합니다. 여러 개의 인수를 사용할 수 있습니다. 에 작성하여 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 개가 추악 해지기 시작합니다. 입력이 많으면 먼저 다른 방법 (예 : Karnaugh 맵)으로 단순화하십시오.


0

"Gorgeous Karnaugh"소프트웨어를보십시오-샘플과 같은 진리표를 정확하게 받아 들일 수 있고, 분석 부울 공식 정의를 받아들이고, 진리표를 만들기 위해 Lua 스크립팅을 받아 들일 수 있습니다. 다음으로 "Gorgeous Karnaugh"소프트웨어는 입력을 위해 K-Maps를 가져와 수동으로 또는 "Espresso"로직 최소화기를 사용하여 C / C ++ 및 일부 하드웨어 언어에 대한 출력을 생성 할 수 있습니다. 요약을 봐는 "화려한 카르노"페이지의 기능 - http://purefractalsolutions.com/show.php?a=xgk/gkm


이것은 내가 필요한 것과 많이 비슷하지만 if진리표를 입력 한 후 빈 코드 이외의 것을 표시하는 C / C ++ 코드를 얻을 수 없습니다 .
Juan

예, 논리 기능 최소화를 위해 설계된이 도구는 진리표를 입력 한 후 논리 기능 (PoS / SoP-0 / x 1)을 최소화해야합니다. C ++ 코드는 최소화 후 "최소화 결과"창에서 찾을 수 있습니다.
Petruchio
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.