单调对齐搜索的目的:从起点搜索到终点的价值最大(最小)的路径,同时要满足搜索的单调性,也即一个x可以对应多个y,但是一个y不能对应多个x!(y的数量要大于x)。换一句话说就是我们等下在搜索的时候只能向下或者向右下进行搜索!这一点很重要!
假设我们有价值矩阵如下。
y\x |
0 |
1 |
2 |
0 |
0 |
1 |
5 |
1 |
5 |
6 |
5 |
2 |
7 |
5 |
4 |
3 |
3 |
8 |
10 |
4 |
4 |
2 |
4 |
显然,这里y的数量为5,x的数量为3,y的数量大于x,我们要从(0,0)找到一条到(4,2)的路径,使得价值最大。
y\x |
0 |
1 |
2 |
0 |
0 |
1 |
5 |
1 |
5 |
6 |
5 |
2 |
7 |
5 |
4 |
3 |
3 |
8 |
10 |
4 |
4 |
2 |
4 |
方式1
y\x |
0 |
1 |
2 |
0 |
0 |
1 |
5 |
1 |
5 |
6 |
5 |
2 |
7 |
5 |
4 |
3 |
3 |
8 |
10 |
4 |
4 |
2 |
4 |
方式2
同样很明显,方式1和方式2的最后价值是不一样的!
那怎么进行搜索呢?我们用一个例子来说明。
当y=0时 x只能为0(因为搜索的时候只能向下或者向右下进行搜索!)
我们有累计价值如下
y\x |
0 |
1 |
2 |
0 |
0 | ||
1 | |||
2 | |||
3 | |||
4 |
当y=1时 x只能为0 1(因为搜索的时候只能向下或者向右下进行搜索!)
我们有累计价值如下
y\x |
0 |
1 |
2 |
0 |
0 | ||
1 |
5 |
6 | |
2 | |||
3 | |||
4 |
当y=2时,x只能为0 1 2(因为搜索的时候只能向下或者向右下进行搜索!)
我们有累计价值如下
y\x |
0 |
1 |
2 |
0 |
0 | ||
1 |
5 |
6 | |
2 |
12 |
11 |
10 |
3 | |||
4 |
当y=3时,x只能为0 1 2 3(这里有问题!我们先忽略一下哈!)
我们有累计价值如下
y\x |
0 |
1 |
2 |
0 |
0 | ||
1 |
5 |
6 | |
2 |
12 |
11 |
10 |
3 |
15 |
20 |
21 |
4 |
当y=4时,x只能为0 1 2 3 4(这里有问题!我们先忽略一下哈!)
我们有累计价值如下
y\x |
0 |
1 |
2 |
0 |
0 | ||
1 |
5 |
6 | |
2 |
12 |
11 |
10 |
3 |
15 |
20 |
21 |
4 |
19 |
22 |
25 |
最终我们得到这条橙色的搜索路径,使得起点到终点的价值最大。
注意!因为搜索的时候只能向下或者向右下进行搜索!
但是这会有问题!比如当y=3的时候,你的x还是0,那么你就不可能到终点!又比如说,当一开始的矩阵是这个样子。
y\x |
0 |
1 |
2 |
0 |
0 |
1 |
1 |
1 |
10 |
1 |
1 |
2 |
10 |
1 |
1 |
3 |
10 |
1 |
1 |
4 |
10 |
1 |
1 |
然后你又追求最大值,那么你的路径就会直接到(4,1),变成这样。
y\x |
0 |
1 |
2 |
0 |
0 |
1 |
1 |
1 |
10 |
1 |
1 |
2 |
10 |
1 |
1 |
3 |
10 |
1 |
1 |
4 |
10 |
1 |
1 |
而这是不满足要求的!
所以我们需要加上这个条件。
for x in range(max(0, t_x + y - t_y), min(t_x, y + 1)):
这会使得当我们的y=3的时候,x不能取0,只能取1或者2.(因为只有这样你才可能到(4,2)这个终点对吧!)
单调对齐的代码放这里,大家可以理解一下。
index = t_x - 1
for y in range(t_y):
for x in range(max(0, t_x + y - t_y), min(t_x, y + 1)):
if x == y:
v_cur = max_neg_val
else:
v_cur = value[y - 1, x]
if x == 0:
if y == 0:
v_prev = 0.0
else:
v_prev = max_neg_val
else:
v_prev = value[y - 1, x - 1]
value[y, x] += max(v_prev, v_cur)
# 进行回溯
for y in range(t_y - 1, -1, -1):
path[y, index] = 1
if index != 0 and (
index == y or value[y - 1, index] < value[y - 1, index - 1]
):
index = index - 1
# t_y 和 t_x分别为y和x的长度