Eğer / else bloğu ise doğruluk tablosunu mümkün olan en küçük şekle dönüştürme


20

Bir doğruluk tablosunu nasıl alıp sıkıştırılmış bir bloğa dönüştürebilirim?

Örneğin, A ve B'nin koşullar olduğu ve x, y ve z'nin olası eylemler olduğu bu doğruluk tablosuna sahip olduğumu varsayalım:

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

Bu, blok halinde aşağıya dönüşebilir:

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

Bu kolay bir örnektir, ancak sık sık farklı şekillerde birleştirilen farklı çıktılar üretmesi gereken birkaç koşulum var ve mantıklarını bir if bloğunda temsil etmenin en sıkıştırılmış ve zarif yolunu bulmak zorlaşıyor.


10
bir Karnaugh haritasını ifelse çağlayanına dönüştürmek mi demek istediniz ?
cırcır ucube

@ratchet: Görünüşe göre öyle değil mi? Onları daha önce bilmiyordum. Bazı okuma yapmak zorunda kalacak ama yine de ve benim için yapacak bir uygulama, başka bir şey değilse, el yapımı sonuçları doğrulamak için güzel olurdu.
Juan

1
@jalayn çoğu karnaugh araçları dijital devre içindir; bunlar sorunun ne olduğundan farklı bir sezgisel
tarama

1
@jsoldi: Aldığınız cevaplar hangi siteye sorduğunuza bağlı olacaktır. Bazı if-then-else blokları içeren belirli bir kod parçası hakkında yorum arıyorsanız, kesinlikle Code review (beta) 'a aittir . Stackoverflow size araçları ve teknikleri öğretecek. SE, insanlar size insan anlayışı veya daha hızlı yürütme için mantık ifadelerinin yeniden yazılması konusunda endişelenmeniz gerekip gerekmediğini söyler.
rwong

2
Aracı tavsiyeler konu dışı, ama içine soruyu değiştirirseniz "Nasıl olabilir ben bunu?" konu üzerinde olacak. Bir yazılım önerisi istiyorsanız, softwarerecs.stackexchange.com adresine gitmelisiniz.
Kilian Foth

Yanıtlar:


14

Bir Karnaugh haritasından tasarlıyorsanız, kod da bu şekilde görünebilir:

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

actionMap[a][b]()

Bu hangi dil? JavaScript? Python?
TheLQ

The PQ, python değil, javascript olabilir. Ama python ile yazılmış olsaydı çok benzer olurdu
grizwako

@TheLQ: Groovy, çünkü bu günlerde yaptığım şey bu ve muhtemelen Ruby. Javascript veya Python veya LUA veya Perl kodu çok benzer olacaktır.
kevin cline

2
Bu, elbette, değerlendirme gerekmediğinde bile b'yi değerlendirme etkisine sahiptir. Belki bu bir problem, belki de değil.
Takma isim

@kevincline lütfen, oldukça lütfen, "Lua", "LUA" değil. :)
Machado

4

C # .NET, aşağıdaki gibi herhangi bir IF ELSE olmadan sonuç almak için bir Sözlük Sınıfı kullanabilirsiniz - Bu konuda güzel bir şey:

  1. Okunabilir
  2. Yeni anahtarlar benzersiz olacak (aksi takdirde bir hata alırsınız)
  3. Sıra önemli değil
  4. Giriş eklemek veya çıkarmak kolay

Dictionary Class eşdeğeri yoksa, aynı şeyi ikili arama / arama işlevinde yapabilirsiniz.

//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
Bu çözümü beğendim, yapacağım tek değişiklik Sözlük <string, string> yerine Dictionary <Tuple <bool, bool>, Tuple <bool, bool, bool> kullanmak olacaktır. O zaman Tuples bunu sizin için yapacağından, daha sonra bakmak ve sonucu çözmek için bir dize oluşturmanız gerekmez.
Lyise

@Lyise, Yorumunuz için teşekkür ederim. Kesinlikle haklısın. Bir şans bulduğumda iyi noktanı eklemeliyim.
NoChance

2

İstediğiniz bir Rete algoritmasıdır . Bu, otomatik olarak bir dizi kuralı tarar ve tanımladığınız şekilde ağaca öncelik verir.

Bunu, yürütme hızının önemli olduğu çok büyük ölçekte (milyonlarca kural) yapan bir dizi ticari "kural motoru" sistemi vardır.


2

İşte kütüphaneniz :) Ve tam K-tablosunu geçmenize gerek yok, sadece ilgilendiğiniz alanlar :) Onun VE operatörünün doğruluk tablosunda olduğunu varsayar. Daha fazla operatör kullanmak istiyorsanız, yeniden yazabilmeniz gerekir. İstediğiniz sayıda bağımsız değişkeniniz olabilir. Yazılmıştır pythonve test edilmiştir.

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

Girişleri tek bir değerle eşleyin ve ardından açın:

#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

İşlev işaretçileri içeren bir arama tablosu bazı durumlarda iyi çalışabilir. Örneğin, C'de şöyle bir şey yapabilirsiniz:

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();
}

Girdi sayısı nispeten az olduğunda bu iyi bir çözümdür, çünkü tablodaki girdi sayısı 2 ^ ^ olmalıdır, burada n girdi sayısıdır. 7 veya 8 giriş yönetilebilir, 10 veya 12 çirkinleşmeye başlar. Bu kadar çok girdiniz varsa, önce başka yollarla (Karnaugh haritaları gibi) basitleştirmeyi deneyin.


0

"Muhteşem Karnaugh" yazılımına bakın - doğruluk tablolarını örnek olarak kabul edebilir, analitik boole formülleri tanımını kabul edebilir, doğruluk tabloları oluşturmak için Lua komut dosyasını kabul edebilir. Daha sonra, "Gorgeous Karnaugh" yazılımı, manuel olarak veya "Espresso" mantık küçültücü kullanarak en aza indirebileceğiniz ve C / C ++ ve bazı donanım dilleri için çıktı üreten giriş için K-Maps'i çizer. "Muhteşem Karnaugh" için özet özellikler sayfasına bakın - http://purefractalsolutions.com/show.php?a=xgk/gkm


Bu çok ihtiyacım gibi görünüyor, ama ifbir doğruluk tablo girdikten sonra boş s dışında bir şey göstermek için C / C ++ kodu alınamadı .
Juan

Evet, mantık işlevini en aza indirmek için tasarlanmış bu araç - doğruluk tablosuna girdikten sonra mantık işlevini en aza indirmeniz gerekir (PoS / SoP - 0/1). C ++ kodu, simge durumuna küçültmeden sonra "Simge durumuna küçültme sonuçları" penceresinde bulunabilir.
Petruchio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.