这次国赛选了B题,虽然拉了但是在做的过程中有一些小理解,想在这里分享出来。
-
对于求解最优序列的问题,序列中的每一个位置的点有自己的状态,最优序列即为求得最优的状态序列,这涉及三部分内容:
- 定义状态
- 定义状态的分数
- 定义状态转移
-
定义状态: 把一个点的状态抽象为一个k维向量(x1,x2,...,xk)(x_1,x_2,...,x_k)(x1,x2,...,xk),该向量的每一维度都代表该状态的不同维度,这些维度的取值合在一起构成了这个内容的状态;
需要注意的是,任何一个状态都有其最基础的一个维度:时间维度,这个时间也可以理解为其在状态序列中的位置;
以B题第一关为例,向量有四个维度分别是时间,玩家位置,玩家消耗的水,玩家消耗的食物,基础维度时间即代表该玩家是在沙漠上的第几天。每一个维度都有不同取值,代表了不同的状态。 -
定义状态的分数: 即为每一个状态x=(x1,x2,...,xk)x = (x_1,x_2,...,x_k)x=(x1,x2,...,xk)维护一个分数ω\omegaω,分数高代表这个状态更优,记f(x)=x.ωf(x) = x.\omegaf(x)=x.ω;
值得注意的是,每一个状态的分数都与其前序状态密切相关;以B题第一关为例,这个ω\omegaω就是该状态下玩家剩余的资金,其与玩家前一天剩余的资金密切相关。 -
定义状态转移: 首先,定义当前状态xcx_cxc,xc∈(c,∗,∗,...,∗)x_c \in (c,*,*,...,*)xc∈(c,∗,∗,...,∗),c∈0,1,2,...,Tc \in {0,1,2,...,T}c∈0,1,2,...,T,那么有xc+1=Next(xc)x_{c+1} = Next(x_c)xc+1=Next(xc),其中Next(xc)Next(x_c)Next(xc)代表xcx_cxc的下一个状态
假设xc+1=(x1′,x2′,...,xk′)x_{c+1} = (x_1',x_2',...,x_k')xc+1=(x1′,x2′,...,xk′),考虑∃xc′≠xc\exists x_c' \neq x_c∃xc′=xc,并且Next(xc′)=xc+1Next(x_c') = x_{c+1}Next(xc′)=xc+1,这便是子问题之间的重复性,带有这个特征的问题可以使用动态规划算法求解:
即令xcˉ={xc∣xc∈(c,∗,∗,...,∗)∧Next(xc)=xc+1}\bar{x_c} = \{x_c| x_c \in (c,*,*,...,*) \wedge Next(x_c) = x_{c+1}\}xcˉ={xc∣xc∈(c,∗,∗,...,∗)∧Next(xc)=xc+1},那么有xc+1=argmax(f(xcˉ)+Cost(xc→xc+1))(*)x_{c+1} = argmax(f(\bar{x_c}) + Cost(x_c \rightarrow x_{c+1})) \tag{*}xc+1=argmax(f(xcˉ)+Cost(xc→xc+1))(*)其中Cost(xc→xc+1)Cost(x_c \rightarrow x_{c+1})Cost(xc→xc+1)代表从xcx_cxc转移到xc+1x_{c+1}xc+1带来的分数变化,每一个分数不同的xcx_cxc都可能转移到分数不同的xc+1x_{c+1}xc+1,即
f(xc)+Cost(xc→xc+1)=f(xc+1)f(x_c) + Cost(x_c \rightarrow x_{c+1}) = f(x_{c+1})f(xc)+Cost(xc→xc+1)=f(xc+1)
因此,(∗)(*)(∗)式可以转化为
xc+1=argmax(f(xc+1ˉ))x_{c+1} = argmax(f(\bar{x_{c+1}}))xc+1=argmax(f(xc+1ˉ))
其中xc+1ˉ=Next(xcˉ)\bar{x_{c+1}} = Next(\bar{x_c})xc+1ˉ=Next(xcˉ),argmax(ω)argmax(\omega)argmax(ω)代表选出ω\omegaω最大的xcx_cxc
之后重复上述转移过程,每一个xcx_cxc都会是具有最高分数的,即最优的,最后有
xT=argmax(f(xTˉ))x_{T} = argmax(f(\bar{x_{T}}))xT=argmax(f(xTˉ))
xTx_{T}xT即为序列的最终位置的最优状态,根据此状态回溯其前序状态,则可以得到序列中每一个位置的最优状态与其转移。 -
动态规划是用于求解会有状态重合的时候的算法,可以把O(D2∗D3∗...∗Dk)TO(D_2 * D_3 *...*D_k)^TO(D2∗D3∗...∗Dk)T的复杂度降低到O(D2∗D3∗...∗T)O(D_2 * D_3 * ... *T)O(D2∗D3∗...∗T),其中DiD_iDi是xxx中第i+1i+1i+1维的维度,这里不知道说的对不对,希望大佬指正
-
可以拓展到各种优化算法上,遗传、蚁群等等感觉都差不多,只是定义状态的分数和转移有一点不同,但感觉殊途同归。