[英]how to transform pairwise dependence to multiway tree
例如,存在以下依賴性:A <-B,C <-H,B <-F,B <-G,A <-C,A <-D,A <-EI將這些依賴關系轉換為像這樣的多路樹:
A
/ / \ \
B C D E
/\ /
F G H
誰能有一個好的方法?
python中的解決方案。
每個依賴項都是從子項到其父項的一條邊,例如A <- B
意味着節點B
是節點A
的子項,並且您具有從B
到A
一條邊。 就是說,您需要一個數據結構來存儲那些節點和邊緣。
第一個解決方案是簡單的命令。 我們走吧。
首先,您必須以可用格式解析依賴關系。 我提出了一種格式(父級,子級)和列表解析來解析字符串( 這很容易用任何高級語言翻譯 ):
def get_deps(dep_strings):
"""Return list of tuples (parent, child). Very rudimentary."""
return [tuple(dep_list) for dep_string in dep_strings.split(",") for dep_list in [dep_string.strip().split("<--")]]
其次,您必須遍歷依賴關系以構建樹( 這是算法的核心,並且易於翻譯成任何高級語言 ):
def parse_to_dict(dep_strings):
deps = get_deps(dep_strings)
# the dict will take associate to every parent its "children dictionaries"
d = {}
for (p, c) in deps:
if p not in d: # parent has not yet been seen
d[p] = {}
if c not in d: # child has not yet been seen
d[c] = {} # child is a leaf, until it becomes possibly a parent
d[p][c] = d[c] # hang the child to its parent.
# the dict has a key for every node, and the value is its "children dictonaries".
# usually, we don't need this direct access, thus we remove all non root elements
for _, c in deps:
del d[c]
return d
由於為每個未知節點創建一個空的dict很麻煩,因此您可以使用defaultdict
或dict.setdefault
使其更具可讀性。
...
d = defaultdict(dict) # will create an empty dict for every missing key
for (p, c) in deps:
d[p][c] = d[c] # hang the child to its parent, create dicts on demand.
要么
...
d = {}
for (p, c) in deps:
d.setdefault(p, {}) # will create an empty dict if this key is missiing
d.setdefault(c, {})
d[p][c] = d[c] # hang the child to its parent, create dicts on demand.
請注意, dict.setdefault
更靈活,因為它可以接受參數,如您將在后面看到的。
如果要構建自定義樹,則必須創建一個Node
類,例如:
class Node():
"""A very simple node class"""
def __init__(self, id):
self.__id = id
self.__children = []
def add(self, n):
self.__children.append(n)
def __str__(self):
if self.__children:
return "Node {} [{}]".format(self.__id, ", ".join(str(c) for c in self.__children))
else:
return "Leaf {}".format(self.__id)
創建樹就像使用字典一樣簡單:
...
# we still need a dict
d = {}
for (p, c) in deps:
d.setdefault(p, Node(p)) # we need to build a node with an id,
d.setdefault(c, Node(c)) # hence defaultdict is not the right tool
d[p].add(d[c])
# dict
{'A': {'B': {'F': {}, 'G': {}}, 'C': {'H': {}}, 'D': {}, 'E': {}}}
# defaultdict
defaultdict(<class 'dict'>,
{'A': {'B': {'F': {}, 'G': {}}, 'C': {'H': {}}, 'D': {}, 'E': {}}})
# dict.setdefault
{'A': {'B': {'F': {}, 'G': {}}, 'C': {'H': {}}, 'D': {}, 'E': {}}}
# Node
Node A [Node B [Leaf F, Leaf G], Node C [Leaf H], Leaf D, Leaf E]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.