线性有向无环图

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