线性有向无环图
Linear Directed Acyclic Graph
我有一个 OCR 任务,我在其中过度分割了图像。现在我想构建一个数据结构(各种有向无环图)来获取所有可能的图像组合。
示例:
我先把它分成四个部分,a[3]、b[4 的左半部分]、c[4 的右半部分]、d[2]。现在我将它们以不同的方式组合起来。例如,获取以下路径。
0) a, b, c, d (基本配置)
1) a, bc, d (正确配置)
2) ab, c, d
3) a, b, cd
等
我希望在 Python 中实现这一点。有现成的包吗?如果不是,最好的数据结构是什么? DAG是最接近的吗?是否有多种DAG效果更好?
谢谢,
好的,我有答案了。可以这样实现。
import random
def combine(wt1, wt2):
return random.random() < .1, (wt1+wt2)//2
class Linetree():
def __init__(self, wts):
self.nodes = []
for i, wt in enumerate(wts):
self.nodes.append([[i+1, wt]])
self.nodes.append([])
self.processed = []
self.checked = []
def processnode(self, idx):
if idx in self.processed:
return
ichild = 0
while ichild < len(self.nodes[idx]):
chidx, chwt = self.nodes[idx][ichild]
self.processnode(chidx)
igrandchild = 0
while igrandchild < len(self.nodes[chidx]):
grchidx, grchwt = self.nodes[chidx][igrandchild]
if (idx, grchidx) in self.checked:
igrandchild += 1
continue
tocombine, newwt = combine(chwt, grchwt)
self.checked.append((idx, grchidx))
if tocombine:
self.nodes[idx].append([grchidx, newwt])
igrandchild += 1
ichild += 1
self.processed.append(idx)
def build(self):
self.processnode(0)
def get_paths(self, n=0):
if len(self.nodes[n]) == 0:
yield [n]
for ch, wt in self.nodes[n]:
for sub_path in self.get_paths(ch):
yield [n] + sub_path
def pathwt(self, path):
ret = 0
for i in range(len(path)-1):
for child, wt in self.nodes[path[i]]:
if child == path[i+1]:
ret += wt
break
else:
raise ValueError(str(path))
return ret
def __str__(self):
ret = ""
for i, children in enumerate(self.nodes):
ret += "\nNode {}: ".format(i)
for child in children:
ret += "{}, ".format(child)
return ret
def main():
wts = range(10, 80, 10)
print(list(enumerate(wts)))
lt = Linetree(wts)
print(lt.nodes)
print(lt)
lt.build()
print(lt)
paths = lt.get_paths()
for path in paths:
print(path, lt.pathwt(path))
main()
我有一个 OCR 任务,我在其中过度分割了图像。现在我想构建一个数据结构(各种有向无环图)来获取所有可能的图像组合。
示例:
我先把它分成四个部分,a[3]、b[4 的左半部分]、c[4 的右半部分]、d[2]。现在我将它们以不同的方式组合起来。例如,获取以下路径。
0) a, b, c, d (基本配置)
1) a, bc, d (正确配置)
2) ab, c, d
3) a, b, cd
等
我希望在 Python 中实现这一点。有现成的包吗?如果不是,最好的数据结构是什么? DAG是最接近的吗?是否有多种DAG效果更好?
谢谢,
好的,我有答案了。可以这样实现。
import random
def combine(wt1, wt2):
return random.random() < .1, (wt1+wt2)//2
class Linetree():
def __init__(self, wts):
self.nodes = []
for i, wt in enumerate(wts):
self.nodes.append([[i+1, wt]])
self.nodes.append([])
self.processed = []
self.checked = []
def processnode(self, idx):
if idx in self.processed:
return
ichild = 0
while ichild < len(self.nodes[idx]):
chidx, chwt = self.nodes[idx][ichild]
self.processnode(chidx)
igrandchild = 0
while igrandchild < len(self.nodes[chidx]):
grchidx, grchwt = self.nodes[chidx][igrandchild]
if (idx, grchidx) in self.checked:
igrandchild += 1
continue
tocombine, newwt = combine(chwt, grchwt)
self.checked.append((idx, grchidx))
if tocombine:
self.nodes[idx].append([grchidx, newwt])
igrandchild += 1
ichild += 1
self.processed.append(idx)
def build(self):
self.processnode(0)
def get_paths(self, n=0):
if len(self.nodes[n]) == 0:
yield [n]
for ch, wt in self.nodes[n]:
for sub_path in self.get_paths(ch):
yield [n] + sub_path
def pathwt(self, path):
ret = 0
for i in range(len(path)-1):
for child, wt in self.nodes[path[i]]:
if child == path[i+1]:
ret += wt
break
else:
raise ValueError(str(path))
return ret
def __str__(self):
ret = ""
for i, children in enumerate(self.nodes):
ret += "\nNode {}: ".format(i)
for child in children:
ret += "{}, ".format(child)
return ret
def main():
wts = range(10, 80, 10)
print(list(enumerate(wts)))
lt = Linetree(wts)
print(lt.nodes)
print(lt)
lt.build()
print(lt)
paths = lt.get_paths()
for path in paths:
print(path, lt.pathwt(path))
main()