Warm tip: This article is reproduced from serverfault.com, please click

python-给定跨度的最佳解析树使用最大和

(python - Best parse tree given spans using maximum sum)

发布于 2020-11-28 15:47:01

我想找到一种方法,可以通过对树的跨度总和进行评分,并选择得分最高的二叉树,以通过回溯使总和最大化。

假设,我有以下句子:

string = "Revenue was 19.9 million"

spans数组代表相应(i, j)位置上的span得分这里:j=i+1

例如,

score(0, 1)=-100.0对应跨度"Revenue"

score(0, 4)=100.0对应跨度"Revenue was 19.9 million"

score(1, 4)=100.0对应跨度"was 19.9 million"

等等 ...

                                               #  1 2 3 4
spans = [[-100.0, -100.0, -100.0,  100.0],     # 0
         [ 0,     -100.0, -100.0,  100.0],     # 1
         [ 0,       0 ,   -100.0,  100.0],     # 2
         [ 0,       0,      0,    -100.0]]     # 3
         

预期树-(Revenue (was (19.9 million)))对应的跨度(0, 4)(1, 4)(2, 4)

虽然,我得到-(Revenue was 19.9 million)与下面的代码。

我试着做:

class MaxSpanCalculator:

    def __init__(self, s, spans):
        self.sentence = s.split(" ")
        self.spans = spans
        self.splits = []

    def get_max_span_sentence(self):
        n = len(self.sentence)
        # Initialize the splits array
        for i in range(n):
            s = []
            for j in range(n):
                s.append(-1)
            self.splits.append(s)

        # Here Using spans array itself as dp array
        for l in range(1, n+1):
            i = 0
            j = i + l - 1
            while j<n:
                if i!=j:
                    for p in range(i,j):
                        if self.spans[i][j] < self.spans[i][p] + self.spans[p+1][j]:
                            self.splits[i][j] = p
                            self.spans[i][j] = self.spans[i][p] + self.spans[p+1][j]
                i = i + 1
                j = j + 1

        print("Max span value: " + str(self.spans[0][n-1]))
        print("Max span sentence is : " + self.get_sentence(0, n-1))

    def get_sentence(self, start, end):
        # print(str(start) + " " + str(end))
        if start==end: return self.sentence[start]
        if self.splits[start][end] == -1:
            return " ".join(x for x in self.sentence[start:end+1])
        return "(" + self.get_sentence(start, self.splits[start][end]) + ")" + "(" + self.get_sentence(self.splits[start][end]+1, end) + ")"
Questioner
nikinlpds
Viewed
11
btilly 2020-11-29 08:19:39

这是一个动态的编程问题。

首先,你想将文本字符串转换为单词数组。因为那是你的费用。

其次,你需要计算两个数据结构。

  1. aggregate_cost[(start, end)]是从start的时间间隔的最佳解析的总成本end
  2. best_parse[(start, end)]是从start的时间间隔的最佳解析end

与所有动态编程问题一样,有一种自上而下和自下而上的方法。无论哪种方式,关键的见解都是总成本是以下各项中最大的:

cost(start, end),
cost(start, end) + aggregate_cost[(start, i)],
cost(start, end) + aggregate_cost[(i+1, end)],
cost(start, end) + aggregate_cost[(start, i)] + aggregate_cost[(i+1, end)]

i之间的任何位置并且确定由这些你挑选(而且,当然,其总成本被选择的子区间)。startendbest_parse[(start, end)]best_parse