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