Algorithm 在维护顺序的同时,将两个已排序列表中的加权项配对

Algorithm 在维护顺序的同时,将两个已排序列表中的加权项配对,algorithm,language-agnostic,combinatorics,Algorithm,Language Agnostic,Combinatorics,我正在寻找解决此问题的算法: 我有两个包含项目的列表,例如: A = {a, b, c, d} B = {e, f, g} 还有一张表,告诉我一个列表中的每个项目与另一个列表中的项目的匹配程度。例如: A = {a, b, c, d} B = {e, f, g} E F G A. 10 2. 1. B 1. 0 2. C 2. 0 0 D 1. 20 0 介绍 您可以使用动态规划来解决您的问题,元素dp[i][j]表示到当前位置i,j为止可能达到的最大总和i对应于一个列表中的i-th元素,而

我正在寻找解决此问题的算法:

我有两个包含项目的列表,例如:

A = {a, b, c, d}
B = {e, f, g}
还有一张表,告诉我一个列表中的每个项目与另一个列表中的项目的匹配程度。例如:

A = {a, b, c, d}
B = {e, f, g}
E F G A. 10 2. 1. B 1. 0 2. C 2. 0 0 D 1. 20 0 介绍 您可以使用动态规划来解决您的问题,元素
dp[i][j]
表示到当前位置
i,j
为止可能达到的最大总和
i
对应于一个列表中的
i
-th元素,而
j
-对应于另一个数组中的
j
-th元素

流动 < >我将< <强> Python <强> >编写算法,尽管相同的算法在java或C++等其他语言中的性能会更好。然而,使用Python,它更具可读性(imho)

准备工作 为简洁起见,我假设您的表始终至少有
2
行和列

匹配表和匹配表的大小可以表示为:

n, m = 4, 3 # n stands for number of rows, and m - columns
matches = [[10, 2, 1],
  [1, 0, 2],
  [2, 0, 0],
  [1, 20, 0]]
创建一个
dp
数组,该数组最初包含与
匹配项相同的元素:

dp = matches
求最大和 <>现在,为了计算<代码> dp[i] [j] < /代码>,我们必须考虑<代码> 4 情况:

  • dp[i][j]
    可以是最大值
  • dp[i][j-1]
    是一个最大值
  • dp[i-1][j]
    是最大的
  • dp[i-1][j-1]+dp[i][j]
    是最大值
  • 因此,可以按如下方式进行:

    for j in range(m):
        for i in range(n):
            top = -1
            if i > 0:
                top = dp[i - 1][j]
            left = -1
            if j > 0:
                left = dp[i][j - 1]
            topLeft = -1
            if i > 0 and j > 0:
                topLeft = dp[i - 1][j - 1]
    
            dp[i][j] = max(topLeft + dp[i][j], top, left, dp[i][j])
    
    很好,如果您打印出
    dp[n-1][m-1]
    ,您将看到根据您的任务的最大总和

    以最大和打印序列 基本上,您必须执行相反的过程来打印序列。您应该从dp[n-1][m-1]
    开始,因为它表示最大和

    所以,向左走,检查左边的元素是否与最大值不同。如果不同,则当前元素仅当不等于上面的元素时才属于序列(这意味着
    dp[i-1][j-1]+dp[i][j]
    dp[i][j]
    是最大的)

    另一个选项是最左边的元素也是最大元素。然后,找到原点最大元素并停止该过程

    因此,对上一行重复主程序,直到构建序列

    solution = []
    i = n - 1
    j = m - 1
    done = False
    while i >= 0 and not done:
        current_max = dp[i][j]
        while j > 0:
            if dp[i][j - 1] != current_max:
                break
            j -= 1
    
        if j <= 0:
            while i > 0 and dp[i][0] == dp[i - 1][0]:
                i -= 1
            solution.append((i, j))
            done = True
            break
    
        if i == 0 or dp[i][j] != dp[i - 1][j]:
            solution.append((i, j))
            j -= 1
    
        i -= 1
    
    solution=[]
    i=n-1
    j=m-1
    完成=错误
    当i>=0且未完成时:
    当前_max=dp[i][j]
    当j>0时:
    如果dp[i][j-1]!=当前_最大值:
    打破
    j-=1
    如果j 0和dp[i][0]==dp[i-1][0]:
    i-=1
    解决方案。附加((i,j))
    完成=正确
    打破
    如果i==0或dp[i][j]!=dp[i-1][j]:
    解决方案。附加((i,j))
    j-=1
    i-=1
    
    完整代码
    #n-行
    #m柱
    n、 m=4,3
    匹配项=[[10,2,1],
    [1, 0, 2],
    [2, 0, 0],
    [1, 20, 0]]
    A=['A','b','c','d']
    B=['e','f','g']
    dp=匹配项
    对于范围内的j(m):
    对于范围(n)中的i:
    top=-1
    如果i>0:
    top=dp[i-1][j]
    左=-1
    如果j>0:
    左=dp[i][j-1]
    左上=-1
    如果i>0且j>0:
    左上角=dp[i-1][j-1]
    dp[i][j]=max(左上角+dp[i][j],左上角,dp[i][j])
    打印(dp[n-1][m-1])
    解决方案=[]
    i=n-1
    j=m-1
    完成=错误
    当i>=0且未完成时:
    当前_max=dp[i][j]
    当j>0时:
    如果dp[i][j-1]!=当前_最大值:
    打破
    j-=1
    如果j 0和dp[i][0]==dp[i-1][0]:
    i-=1
    解决方案。附加((i,j))
    完成=正确
    打破
    如果i==0或dp[i][j]!=dp[i-1][j]:
    解决方案。附加((i,j))
    j-=1
    i-=1
    而len(溶液)>0:
    i、 j=solution.pop()
    打印(“(%s,%s)”(A[i],B[j]))