簡體   English   中英

具有 Boolean 功能的真值表

[英]Truth table with Boolean Functions

我正在嘗試使用 python 中的 PANDAS 生成真值表。 我得到了一個 Boolean 網絡,它有 3 個外部節點(U1、U2、U3)和 6 個內部節點(v1、v2、v3、v4、v5、v6)。 我創建了一個表,其中包含 2^3 = 8 的 3 個外部節點的所有可能組合。

import pandas as pd
import itertools

in_comb = list(itertools.product([0,1], repeat = 3))
df = pd.DataFrame(in_comb)
df.columns = ['U1','U2','U3']
df.index += 1
U1 U2 U3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 1 0
1 0 1
1 1 1

而且我還創建了同一張表,但包含 6 個內部節點的所有可能組合,即 2^6 = 64 個組合。

還給出了每個節點的功能

v1(t+1) = U1(t)
v2(t+1) = v1(t) and U2(t)
v3(t+1) = v2(t) and v5(t)
v5(t+1) = not U3(t)
v6(t+1) = v5(t) or v3(t) 

真值表必須使用 PANDAS 完成,並且它必須顯示所有可能的組合。

例如。

v1 v2 v3 v4 v5 v6 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 000010 000000 000010
0 0 0 0 0 1
0 0 0 0 1 0
0 0 0 0 1 1

上表是最終產品應該如何的示例。 其中 [0 0 0] 是外部節點的第一個組合。

我對如何計算每個基因的功能以及如何過濾數據並最終得到一個像這里這樣的新表感到困惑。

在這里,我附上我要解決的問題的圖像:

問題圖片

您似乎錯過了這樣一個事實,即您的網絡不僅有 3 個輸入,因為“舊狀態”也被認為是一個輸入 - 這就是反饋組合網絡所做的,它將舊的 state + 輸入變為新的 state(經常輸出)。

這意味着您有 3+6 個輸入,用於 2^9=512 個組合。 打印時不太容易理解,但仍然可以。 我修改了你的代碼來打印這個(注意我對 pandas 很陌生,所以這個代碼肯定可以改進)

import pandas as pd
import pandas as pd
import itertools

#list of (u, v) pairs (3 and 6 elements)
# uses bools instead of ints
inputs = list((row[0:3],row[3:]) for row in itertools.product([False,True], repeat = 9))

def new_state(u, v):
    # implement the itnernal nodes
    return (
        u[0],
        v[0] and u[1],
        v[1] and v[4],
        v[2],
        not u[2],
        v[4] or v[2]
    )

new_states = list(new_state(u, v) for u,v in inputs)
# unzip inputs to (u,v), add new_states
raw_rows = zip(*zip(*inputs), new_states)

def format_boolvec(v):
    """Format a tuple of bools like (False, False, True, False) into a string like "0010" """
    return "".join('1' if b else '0' for b in v)

formatted_rows = list(map(lambda row: list(map(format_boolvec, row)), raw_rows))

df = pd.DataFrame(formatted_rows)
df.columns = ['U', "v(t)", "v(t+1)"]
df.index += 1

df

它的核心是 function new_state ,它采用(u, v)對輸入和舊 state 並產生新的 state。 這是您的規范的直接翻譯。

我修改了您的itertools.product行以使用bool s,產生長度為 9 的結果並將它們拆分為 3+6 長度的元組。 為了仍然以您的格式打印,我添加了format_boolvec(v) function。 除此之外,它應該很容易理解,但如果您需要更多解釋,請隨時發表評論。

要查找從給定開始 state 到給定結束 state 的輸入序列,您可以自己手動完成,但這很乏味。 我建議使用易於實現的圖形算法,因為我們也知道所需路徑的長度,因此我們不需要像 Bellman-Ford 或 Dijkstra 之類的任何花哨算法 - 我們只需要生成所有長度 = 3 的路徑和篩選端點。

# to find desired inputs
# treat each state as a node in a graph
# (think of visual graph transition diagrams)
# and add edges between them labeled with the inputs
# find all l=3 paths, and check the end nodes

nodes = {format_boolvec(prod): {} for prod in itertools.product([False,True], repeat = 6)}

for index, row in df.iterrows():
    nodes[row['v(t)']][row['U']] = row['v(t+1)']

# we now built the graph, only need to find a path from start state to end state

def prefix_paths(prefix, paths):
    # aux helper function for all_length_n_paths
    for path, endp in paths:
        yield ([prefix]+path, endp)

def all_length_n_paths(graph, start_node, n):
    """Return all length n paths from a given starting point
    Yield tuples (path, endpoint) where path is a list of strings of the inputs, and endpoint is the end of the path.
    Uses internal recursion to generate paths"""
    if n == 0:
        yield ([], start_node)
        return
    for inp, nextstate in graph[start_node].items():
        yield from prefix_paths(inp, all_length_n_paths(graph, nextstate, n-1))


# just iterate over all length=3 paths starting at 101100 and print it if it end's up at 011001
for path, end in all_length_n_paths(nodes, "101100", 3):
    if end=="011001":
        print(path)

這段代碼也應該很容易理解,也許除了迭代器語法。

結果不僅僅是一個,而是三個不同的路徑:

['100', '110', '011']
['101', '110', '011']
['111', '110', '011']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM