Làm thế nào để biến bảng chân lý thành nhỏ nhất có thể nếu / khối khác


20

Làm thế nào tôi có thể lấy một bảng chân lý và biến nó thành một khối nếu được nén?

Chẳng hạn, giả sử tôi có bảng chân lý này trong đó A và B là điều kiện và x, y và z là các hành động có thể:

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

Điều này có thể chuyển thành bên dưới nếu khối:

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

Đây là một mẫu dễ dàng, nhưng tôi thường có một số điều kiện kết hợp theo nhiều cách khác nhau sẽ tạo ra các đầu ra khác nhau và thật khó để tìm ra cách gọn nhẹ và thanh lịch nhất để thể hiện logic của chúng trong một khối if.


10
ý bạn là biến một bản đồ Karnaugh thành một tầng thác?
ratchet freak

@ratchet: Có vẻ như tôi không làm vậy? Tôi đã không biết về họ trước đây. Sẽ phải đọc một số nhưng vẫn còn và ứng dụng sẽ làm điều đó cho tôi sẽ rất tuyệt, nếu không có gì khác, để xác minh kết quả của tôi.
Juan

1
@jalayn hầu hết các công cụ karnaugh là dành cho mạch kỹ thuật số; những người có heuristic khác với những gì câu hỏi là về
ratchet freak

1
@jsoldi: Câu trả lời bạn nhận được sẽ phụ thuộc vào trang bạn hỏi. Nếu bạn đang tìm kiếm nhận xét về một đoạn mã cụ thể có chứa một số khối if-then-other, thì nó chắc chắn thuộc về Đánh giá mã (beta) . Stackoverflow sẽ dạy cho bạn các công cụ và kỹ thuật. Trên các lập trình viên.SE, mọi người sẽ cho bạn biết liệu bạn có nên / không nên quan tâm đến việc viết lại các câu lệnh logic để hiểu con người hay để thực hiện nhanh hơn.
rwong

2
Đề xuất công cụ không có chủ đề, nhưng nếu bạn thay đổi câu hỏi thành "Làm thế nào tôi có thể làm điều này?" nó sẽ là chủ đề Nếu bạn muốn có một đề xuất phần mềm, bạn nên truy cập softwarerecs.stackexchange.com.
Kilian Foth

Câu trả lời:


14

Nếu bạn đang thiết kế từ bản đồ Karnaugh, thì mã cũng có thể trông giống như vậy:

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

actionMap[a][b]()

Ngôn ngữ này là gì? Javascript? Con trăn?
TheLQ

TheLQ, không phải python, có thể là javascript. Nhưng nó sẽ rất giống nếu được viết bằng trăn
grizwako

@TheLQ: đó là Groovy, vì đó là những gì tôi đang làm trong những ngày này và có lẽ cả Ruby nữa. Mã cho Javascript hoặc Python hoặc LUA hoặc Perl sẽ rất giống nhau.
kevin cline

2
Điều này, tất nhiên, có tác dụng đánh giá b ngay cả khi không cần đánh giá. Có lẽ đó là một vấn đề, có thể không.
Bút danh

@kevincline xin vui lòng, khá vui lòng, "Lua", không phải "LUA". :)
Machado

4

Trong C # .NET, bạn có thể sử dụng Lớp từ điển để nhận kết quả mà không cần bất kỳ ELSE nào như sau - Điều hay ho về điều này là:

  1. Nó có thể đọc được
  2. Các khóa mới sẽ là duy nhất (nếu không, bạn sẽ gặp lỗi)
  3. Trình tự không quan trọng
  4. Dễ dàng thêm hoặc xóa các mục

Nếu bạn không có lớp Từ điển tương đương, bạn có thể thực hiện tương tự trong chức năng tìm kiếm / tìm kiếm nhị phân.

//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
Tôi thích giải pháp này, thay đổi duy nhất tôi sẽ thực hiện là sử dụng Từ điển <Tuple <bool, bool>, Tuple <bool, bool, bool> thay vì Từ điển <chuỗi, chuỗi>. Sau đó, bạn không cần phải xây dựng một chuỗi để tìm kiếm và giải mã kết quả sau đó vì Tuples sẽ làm điều này cho bạn.
Lyise

@Lyise, Cảm ơn bạn đã nhận xét của bạn. Bạn hoàn toàn chính xác. Tôi nên kết hợp điểm tốt của bạn khi tôi có cơ hội.
NoChance

2

Những gì bạn muốn là một thuật toán Rete . Điều này sẽ tự động kết hợp một bộ quy tắc và ưu tiên chúng thành một cây theo cách bạn mô tả.

Có một số hệ thống "công cụ quy tắc" thương mại thực hiện điều này ở quy mô rất lớn (hàng triệu quy tắc) trong đó tốc độ thực thi là rất cần thiết.


2

Đây là thư viện của bạn :) Và bạn không cần phải vượt qua toàn bộ bảng K, chỉ các trường mà bạn quan tâm :) Nó giả sử rằng toán tử AND của nó trong bảng chân lý. Nếu bạn muốn sử dụng nhiều toán tử hơn, bạn sẽ có thể viết lại nó. Bạn có thể có bất kỳ số lượng đối số. Viết pythonvà kiểm tra.

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

Ánh xạ các đầu vào thành một giá trị duy nhất và sau đó bật 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

Một bảng tra cứu có chứa các con trỏ hàm có thể hoạt động tốt trong một số tình huống. Trong C, ví dụ, bạn có thể làm một cái gì đó như thế này:

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

Đây là một giải pháp tốt khi số lượng đầu vào tương đối nhỏ, vì số lượng mục trong bảng phải là 2 ^^ n trong đó n là số lượng đầu vào. 7 hoặc 8 đầu vào có thể quản lý được, 10 hoặc 12 bắt đầu trở nên xấu xí. Nếu bạn có nhiều đầu vào đó, trước tiên hãy cố gắng đơn giản hóa bằng các phương tiện khác (như bản đồ Karnaugh).


0

Nhìn vào phần mềm "Tuyệt đẹp Karnaugh" - nó có thể chấp nhận các bảng chân lý hoàn toàn chính xác như mẫu của bạn, chấp nhận định nghĩa công thức boolean phân tích, chấp nhận kịch bản lệnh Lua để xây dựng các bảng chân lý. Tiếp theo, phần mềm "Tuyệt đẹp Karnaugh" vẽ Bản đồ K cho đầu vào đã lấy, bạn có thể thu nhỏ thủ công hoặc sử dụng bộ giảm thiểu logic "Espresso" và tạo đầu ra cho C / C ++ và một số ngôn ngữ phần cứng. Tìm đến trang tính năng tóm tắt cho "Karnaugh tuyệt đẹp" - http://purefractalsolutions.com/show.php?a=xgk/gkm


Cái này trông rất giống với những gì tôi cần, nhưng không thể lấy mã C / C ++ để hiển thị bất cứ thứ gì ngoài ifs trống sau khi vào bảng chân lý.
Juan

Có, công cụ đó được thiết kế để giảm thiểu chức năng logic - sau khi vào bảng chân lý, bạn cần giảm thiểu chức năng logic (PoS / SoP - bằng 0/1). Mã C ++ có thể được tìm thấy trong cửa sổ "Kết quả tối thiểu hóa" sau khi thu nhỏ.
Petruchio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.