动态规划——数学模型精解

news/2024/11/16 12:06:32/文章来源:https://www.cnblogs.com/haohai9309/p/18415462

动态规划是运筹学的一个分支,主要用于求解多阶段决策过程的优化问题。1950年代初,R.E. Bellman提出了最优性原理,将复杂的多阶段问题分解为一系列单阶段问题逐步求解,开创了动态规划这一方法。1957年,他出版了《Dynamic Programming》,成为该领域的经典著作。动态规划自问世以来,在经济管理、生产调度、工程技术及最优控制等领域得到广泛应用,如最短路径、库存管理、资源分配等问题。虽然动态规划主要用于动态过程的优化,但一些静态问题(如线性规划)也可通过引入时间因素来求解。动态规划作为一种解决问题的方法,没有固定的算法或规则,需要针对具体问题进行灵活建模与求解。

一、多阶段决策问题

动态规划是一种求解多阶段决策问题的数学方法。通过将复杂的问题分解为多个相互关联的子问题,并利用其递归结构,动态规划能够有效求解最优化问题。该方法的核心思想是将每个阶段的最优决策作为后续阶段的基础,避免重复计算。

例1:一艘货轮在 A 港装货后驶往 F 港,中途须靠港加油和加淡水 3 次,从 A 港到 F港全部可能的航行路线及两港之间的距离如图所示,F 港有 3 个码头,试求最合理的停靠的码头及航线,使总路程最短。

最短路问题 多阶段决策

问题是求 A 港到 F 港最短路程,但从 A 港到 F 港不能直接到达,中途须靠港加油和加淡水 3 次,即必须经过 B1、B2,C1、C2、C3,D1、D2 中的一个港口加油和加淡水。这样的问题可看成一个多阶段决策问题,第一阶段考虑货轮到 B1 港还是到 B2 港;第二阶段考虑货轮到 C1 港、C2 港还是到 C3 港?第三阶段考虑货轮到 D1 港还是到 D2港;第四阶段考虑货轮到 F1 港、F2 港还是到 F3 港;依此类推,最后获得货轮从 A 港到 F 港的一条路径。显然这样的路径有很多,问题是选择一条最优路径,使得总的路程最短,这是一个典型的动态规划问题。

例2:资源分配问题。设有6万元资金用于4个工厂的扩建,已知每个工厂的投资收益(万吨)同投资额的大小有关。应如何确定对这4个工厂的投资额,使总投资收益最大?

工厂投资额(i) 0 1 2 3 4 5 6
1 0 20 42 60 75 85 90
2 0 25 45 57 65 70 73
3 0 18 39 61 78 90 95
4 0 28 47 65 74 80 85

可以把对4个工厂的投资依次看成4个阶段的决策过程,对第i个工厂的投资额看成第i个阶段的决策,i = 1, 2, 3, 4。第一个阶段开始时拥有的资金为6万元,即考虑工厂1投资决策时的资金额是6万元,投资工厂1的资金额为\(u_1\),所以在考虑工厂2投资时剩余的资金额为\(6 - u_1\),依此类推,第4阶段的决策是将剩余资金都投入建厂,这样第5阶段的投资额为0,即\(s_5 = 0\)

一般地,\(n\)阶段的动态规划问题可以描述为下图所示的模式,其中:

  • 状态\(s_k\) 表示第\(k\)个阶段开始时的已知决策条件;
  • \(u_k\)表示在这种决策环境下第k个阶段所采取的决策;
  • 选择这个方案获得的收益为\(v(u_k)\)
  • 该决策也决定了第$ k+1\(个阶段的状态\)s_{k+1}$;
  • 状态\(s_{k+1}\)的确定依赖于状态之间的关系方程\(T_k\),其中¥k = 1, 2, \cdots, n$。
    这种描述模式概括了动态规划问题的基本结构,其中每个阶段的决策依赖于当前状态,并影响下一个阶段的状态和可能的收益。
\(n\)阶段动态规划 动态规划的子过程

二、动态规划的基本概念和数学模型

动态规划是一种用于解决多阶段决策问题的数学方法,特别适合处理具有重叠子问题和最优子结构特性的复杂优化问题。其核心思想是将问题分解为多个相互关联的子问题,通过逐步解决每个子问题,从而得到全局最优解。

2.1 基本概念

  • 阶段 (Stage)
    阶段是动态规划中将问题解决过程进行自然划分的一个概念。通常基于时间或空间的顺序,在每个阶段,决策者都需要做出一个决策。阶段变量通常用 $ k $ 表示,$ k = 1, 2, \dots, n $,其中 $ n $ 代表问题的总阶段数。
  • 状态 (State)
    状态是动态规划中用于描述每个阶段开始时系统所处的状况的概念。状态变量通常用 $ x_k $ 表示,其中 $ k $ 是阶段的编号。
    -决策 (Decision)
    在动态规划的每个阶段,系统处于某个状态,决策者需要根据当前的状态来选择一个最优的决策。决策变量描述了系统在每个阶段的选择,通常记作 $ u_k(x_k) $。
  • 策略 (Policy)
    策略是动态规划中由一系列决策组成的一个完整序列。完整的策略可以记作 $ p_1^n(x_1) $,其中 $ p_1^n(x_1) $ 是从初始状态 $ x_1 $ 开始经过 $ n $ 个阶段的所有决策序列。
  • 状态转移方程 (State Transition Equation)
    状态转移方程是描述系统如何从一个阶段的状态转换到下一个阶段状态的关系式。形式通常为:$$ x_{k+1} = f(x_k, u_k(x_k))$$
  • 指标函数与最优值函数 (Objective Function & Optimal Value Function)
    指标函数用来衡量决策过程的优劣,通常以收益或成本作为标准。最优值函数 $ V_k(x_k) $ 表示从第 $ k $ 阶段的状态 $ x_k $ 开始到过程结束时的最优总收益或最小总成本。

例3:假设有一个背包,能够承受的最大重量是 $ W $,现有若干物品,每个物品有一个重量 $ w_i $ 和价值 $ v_i $。目标是选择一组物品放入背包,使得背包中的物品总价值最大。

  • 阶段:每一个物品对应一个阶段,$ k $ 阶段表示当前是否考虑第 $ k $ 个物品。
  • 状态:$ x_k $ 表示在第 $ k $ 阶段时,当前背包中的剩余承重量。
  • 决策:$ u_k(x_k) $ 表示在第 $ k $ 阶段是否选择放入物品 $ k $,决策变量是 0 或 1。
  • 状态转移方程:如果选择了物品 $ k $,下一个状态就是当前承重量减去物品 $ k $ 的重量 $ w_k $,即 $ x_{k+1} = x_k - w_k $。
  • 指标函数:指标函数是所有被选中物品的总价值,目标是最大化背包的总价值。
    通过递归求解上述问题,可以找到使得背包总价值最大化的最优策略,即哪些物品应该被放入背包。

2.2 数学模型

最优化原理:作为整个过程的最优策略具有这样的性质:无论过去的状态和决策如何,相对于前面的决策所形成的状态而言,余下的决策序列必然构成最优子策略。也就是说,一个最优策略的子策略也是最优的。
动态规划方法建模的关键在于正确地写出基本的递推关系式和恰当的边界条件(简称基本方程)。要做到这一点,就必须将问题的过程分成几个相互联系的阶段,恰当的选取状态变量和决策变量及定义最优值函数,从而把一个大问题转化成一组同类型的子问题,然后逐个求解。即从边界条件开始,逐段递推寻优,在每一个子问题的求解中,均利用了它前面的子问题的最优化结果,依次进行,最后一个子问题所得的最优解,就是整个问题的最优解。在多阶段决策过程中,动态规划方法是既把当前一段和未来一段分开,又把当前效益和未来效益结合起来考虑的一种最优化方法。因此,每段决策的选取是从全局来考虑的,与该段的最优选择答案一般是不同的。通常需要按照以下步骤建立模型:

  • 划分阶段
    划分阶段是动态规划求解的第一步。阶段的划分通常基于时间或空间顺序。每个阶段代表决策过程中的一个步骤。例如,在路径规划问题中,每个阶段可以表示在地图上走到某一位置的时刻;在投资规划中,每个阶段可以表示某一年。
    对于静态问题,也可以人为地引入时间概念来划分阶段。将过程分成多个阶段的目的是逐步求解每个子问题,确保递推关系的建立。
  • 选择状态变量
    状态变量用于描述每个阶段系统所处的状态。状态变量应能全面反映当前阶段的系统情况,并且需要满足无后效性,即当前的状态不依赖于之前的路径。状态变量通常以 $ x_k $ 表示,表示第 $ k $ 阶段的状态。允许状态的集合称为允许状态集合,记作 $ X_k $。
    例如,在背包问题中,状态变量可以选择当前背包的剩余承重量和已经装入背包物品的总价值。
  • 确定决策变量及允许决策集合
    决策变量是每个阶段需要做出的选择,它直接影响系统从当前状态向下一阶段状态的演变。决策变量 $ u_k(x_k) $ 表示在第 $ k $ 阶段,处于状态 $ x_k $ 时的决策选择。
    决策变量的取值范围称为允许决策集合,记作 $ U_k(x_k) $。它包含所有在当前状态下可行的决策。例如,在路径规划问题中,决策变量可能表示从当前地点出发,向哪个方向行进。
  • 建立状态转移方程
    状态转移方程描述系统从当前阶段的状态演变到下一阶段的规则。给定当前阶段的状态和决策,系统会演变到下一阶段的状态,状态转移方程通常表示为:$$ x_{k+1} = f(x_k, u_k(x_k)) $$
    状态转移方程的形式因问题而异。例如,在背包问题中,若决定选择某个物品放入背包,那么下一个阶段的状态就是当前的剩余承重量减去该物品的重量。
  • 确定阶段指标函数和最优值函数,建立动态规划基本方程
    阶段指标函数用来衡量当前阶段的收益或成本,通常记作 $ g_k(x_k, u_k(x_k)) $,它表示在状态 $ x_k $ 下,做出决策 $ u_k(x_k) $ 所获得的收益或成本。
    最优值函数 $ V_k(x_k) $ 表示从第 $ k $ 阶段状态 $ x_k $ 开始,系统演变到终止状态所能获得的最大收益或最小成本。根据阶段的递推关系,可以写出动态规划的基本方程:

\[V_k(x_k) = \max_{u_k(x_k)} \{ g_k(x_k, u_k(x_k)) + V_{k+1}(x_{k+1}) \} \]

该方程表示在每个阶段,最优决策是通过比较当前阶段收益与下一阶段的最优值来递归求解的。递推过程自最后阶段向前进行,从而逐步找到整个问题的最优解。

例4:假设有一个城市网络,网络中的城市通过道路连接,每条道路有一个正数权重,表示两座城市之间的距离。目标是从起点城市(比如 A)到终点城市(比如 E),找到经过的总距离最短的路径。这个问题可以用动态规划来求解。

  • 阶段:阶段是指每一次从一个城市到达另一个城市的过程。在这个问题中,阶段的划分可以基于城市的访问顺序。第 \(k\) 阶段表示正在访问网络中的第 \(k\) 个城市。例如,从起点城市 A 开始,经过第一个城市到达第二个城市,直到到达终点 E,每个阶段对应城市的访问顺序。
  • 状态:状态描述每个阶段所处的城市。状态变量 \(x_k\) 表示在第 \(k\) 阶段所处的城市。每个城市对应一个状态,状态的集合就是所有可能访问的城市集合。例如,若 A、B、C、D、E 为五个城市,则状态集合 \(X_k = \{A, B, C, D, E\}\)。其中 \(x_k\) 表示在第 \(k\) 阶段处于哪个城市,例如 \(x_3 = C\) 表示第 3 阶段处于城市 C。
  • 决策:在每个阶段,给定当前所在城市,决策变量是指下一步选择前往哪个城市。决策变量 \(u_k(x_k)\) 表示当前状态 \(x_k\) 下的决策,即从当前城市前往的下一个城市。允许决策集合是当前城市可以前往的所有邻接城市的集合。例如,如果从城市 A 出发可以前往 B、C,那么决策变量 \(u_k(A)\) 可以是 B 或 C。
  • 状态转移方程:状态转移方程描述了从当前城市(状态)前往下一城市的演变规则。在这个问题中,状态转移方程表示从当前城市 \(x_k\),通过选择决策 \(u_k(x_k)\),到达下一个城市 \(x_{k+1}\)。假设从城市 \(x_k\) 到城市 \(x_{k+1}\) 的距离为 \(d(x_k, x_{k+1})\),那么状态转移方程可以表示为:$$x_{k+1} = u_k(x_k)$$,也就是说,给定当前状态(城市)和决策(选择的下一城市),系统将转移到下一个状态(下一个城市)。
  • 阶段指标函数和最优值函数
    阶段指标函数 \(g_k(x_k, u_k(x_k))\) 表示从当前城市 \(x_k\) 出发,通过选择决策 \(u_k(x_k)\) 后到达下一城市所消耗的距离。在最短路径问题中,阶段指标函数就是两座城市之间的距离。最优值函数 \(V_k(x_k)\) 表示从城市 \(x_k\) 开始,到达终点城市所能走的最短距离。根据递推关系,动态规划的基本方程可以写为:$$V_k(x_k) = \min_{u_k(x_k)} { g_k(x_k, u_k(x_k)) + V_{k+1}(x_{k+1}) }$$,其中,\(g_k(x_k, u_k(x_k))\) 表示当前阶段的距离,而 \(V_{k+1}(x_{k+1})\) 表示从下一城市到终点的最短路径。

三、动态规划的Python求解

3.1 案例

例5:一家公司有1000辆运输卡车,要求在未来5年制定一个分配方案,以在高负荷(每天行驶500km)和低负荷(每天行驶300km)运输之间平衡卡车的分配,从而最大化公司的利润。高负荷与低负荷运输条件下的年利润和年损坏率不同,应用动态规划来解决这个多阶段决策问题。

动态规划数学模型

  • 阶段划分
    问题分为5个阶段,每个阶段代表一年。每年公司可以决定有多少辆车进行高负荷运输,剩下的车则进行低负荷运输。
  • 状态变量
    状态变量 $ x_k $ 表示在第 $ k $ 年剩余的完好卡车数量。初始状态为 $ x_0 = 1000 $,表示公司开始时有1000辆完好的卡车。
  • 决策变量
    决策变量 $ u_k $ 表示在第 $ k $ 年选择进行高负荷运输的卡车数量,剩余的 $ x_k - u_k $ 辆车将进行低负荷运输。
  • 状态转移方程
    卡车在一年中的损坏率不同,状态转移方程为:$$ x_{k+1} = x_k - 0.3 \cdot u_k - 0.1 \cdot (x_k - u_k)$$,表示在第 $ k $ 年结束时剩下的完好卡车数量。
  • 收益函数
    每年的总利润为高负荷和低负荷运输的总收益之和:$$ R_k(u_k) = 25 \cdot u_k + 16 \cdot (x_k - u_k)$$
  • 数学模型
    • \(f(k, x_k\)表示从第\(k\)年开始,剩余\(x_k\)辆完好卡车时的最大利润。
    • 递推关系:

    \[f(k, x_k) = \max_{u_k} \left[ 25 \cdot u_k + 16 \cdot (x_k - u_k) + f(k+1, \text{remaining_trucks}) \right] \]

    其中,\(\text{remaining_trucks} = 0.7 \cdot u_k + 0.9 \cdot (x_k - u_k)\)表示经过一年后剩余的完好卡车数量。

3.2 Python程序

from mip import Model, xsum, maximize, INTEGERdef optModel(m, n, g, h, a, b):# 使用CBC求解器model = Model("truck_load_distribution", solver_name="CBC")# 定义变量:x1代表高负荷运输的卡车数量,x2代表低负荷运输的卡车数量x1 = [model.add_var(var_type=INTEGER) for i in range(n)]  # 高负荷运输卡车数量x2 = [model.add_var(var_type=INTEGER) for i in range(n)]  # 低负荷运输卡车数量# 设置目标函数,最大化5年内的总利润model.objective = maximize(xsum(x1[i] * g + x2[i] * h for i in range(n)))# 初始条件:第一年初的卡车总数为1000辆model += x1[0] + x2[0] == m# 状态转移方程:每一年剩余的卡车数量for i in range(1, n):model += x1[i] + x2[i] == x1[i - 1] * a + x2[i - 1] * b# 运行优化求解model.verbose = 0model.optimize()# 输出优化结果:最大利润和每年高、低负荷运输的卡车分配print("5年内的最大总利润:", model.objective_value)lis1 = []lis2 = []for i in range(n):lis1.append(int(x1[i].x))lis2.append(int(x2[i].x))print("每年高负荷运输的卡车数量:", lis1)print("每年低负荷运输的卡车数量:", lis2)# 修改为提供的参数
if __name__ == '__main__':# 参数:初始卡车数量、年份、每辆车的高负荷利润、低负荷利润、高负荷损坏率、低负荷损坏率m = 1000               # 初始卡车数量n = 5                  # 5年high_profit = 25        # 高负荷运输的年利润(万元)low_profit = 16         # 低负荷运输的年利润(万元)high_damage = 0.3       # 高负荷运输的年损坏率low_damage = 0.1        # 低负荷运输的年损坏率# 调用优化模型optModel(m, n, high_profit, low_profit, 1 - high_damage, 1 - low_damage)
5年内的最大总利润: 74740.0
每年高负荷运输的卡车数量: [0, 0, 795, 570, 399]
每年低负荷运输的卡车数量: [1000, 900, 15, 0, 0]

总结

动态规划是一种通过将复杂问题分解为多个相互关联的子问题,从而逐步求解全局最优解的数学方法。其核心思想是利用递推关系,通过解每个子问题来最终解决原问题。动态规划的基本要素包括以下几方面:

阶段:动态规划将问题划分为多个阶段,每个阶段代表问题解决过程中的一个步骤。每个阶段的结果会影响下一阶段的决策。
状态:状态是每个阶段所处的具体情况。每个状态能够总结之前的决策过程,描述系统在该阶段的特定情形。
决策:在每个阶段中,针对当前状态,决策者需要选择最佳的行动(决策)来影响下一阶段的状态。
策略:策略是指由一系列决策组成的序列,从初始状态开始一直到最终状态,动态规划通过分析不同策略来找到最优解。
状态转移方程:状态转移方程描述了在做出某个决策后,系统如何从一个状态转移到下一个状态。它是动态规划的递推基础。
指标函数:指标函数衡量决策的优劣,通常是与目标相关的收益、成本或效用。动态规划的目标是最大化(或最小化)该函数的值。

动态规划广泛应用于多领域优化问题,如路径规划(最短路径问题)、资源分配(如企业资源优化)、背包问题(选择最优的物品组合以最大化收益)等。它通过记忆子问题的最优解,避免了重复计算,提高了求解效率。尤其在解决具有重叠子问题和最优子结构的问题时,动态规划展现出显著的优势。

参考资料

  1. 第九章 (一)动态规划
  2. 多阶段决策过程的最优化问题(动态规划)
  3. 第四章:动态规划

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/797845.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#实现系统登录

1, 新建窗口frm_Loginusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace WindowsFormsA…

深度学习(FCN)

FCN是全卷积网络,用于做图像语义分割。通常将一般卷积网络最后的全连接层换成上采样或者反卷积网络,对图像的每个像素做分类,从而完成图像分割任务。 网络结构如下:这里并没有完全按照原始网络结构实现,而是尝试upsample和convTranspose2d结合的方式,看看有什么效果。 下…

多线程五-线程通信之wait与notify

wait与notify用于syncronized的线程间通信的一种,wait用来阻塞线程并释放锁,notify用来唤醒线程。他们与condition作用基本一致,但是由于syncronized为jdk实现,阅读源码有难度,所以通过了解其原理,用来帮助我们后续理解condition的源码。 可以通过下面一张图来理解:下面…

帝国cms忘记了后台密码怎么办

如果你忘记了帝国CMS(EmpireCMS)的后台管理员密码,可以通过以下步骤来重置密码: 方法 1: 通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。 登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。 打…

如何恢复对帝国CMS的访问,忘记账号密码的解决方案

如果你忘记了帝国CMS的后台管理员账号和密码,可以通过以下步骤来恢复对系统的访问: 方法 1: 通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。 登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。 …

编程日记 后端tags过滤器

编程日记 后端tags过滤器这样查出来了所有的信息,不对 检查是这个地方有问题改掉 @Overridepublic List<User> searchUsersByTags(List<String> tagNameList) {//1.先查询所有用户QueryWrapper<User> queryWrapper = new QueryWrapper<>();List<Us…

PbootCms忘记后台管理员密码这样找回

如果你忘记了PbootCMS后台管理员的密码,可以通过以下步骤来重置密码: 方法 1: 使用官方提供的密码重置工具下载密码重置工具:下载官方提供的密码重置工具 resetpw.php。 将 resetpw.php 文件上传到网站根目录。访问重置工具:在浏览器中访问 http://[您的域名]/resetpw.php。…

织梦CMS 忘记后台管理员密码的一种解决方法

如果你忘记了织梦CMS(Dedecms)的后台管理员密码,并且拥有对MySQL数据库的操作权限,可以按照以下步骤重置密码: 步骤 1: 登录 MySQL 数据库打开 MySQL 客户端,如 phpMyAdmin 或命令行工具。 登录 MySQL 数据库:sqlmysql -u 用户名 -p输入密码后登录。步骤 2: 选择对应的数…

编程日记 后端使用redis

编程日记 后端使用redis 问题:在写伙伴匹配系统的时候,要使用redis存储数据,需要在xml文件中设置spring.session.tore-type=redis 但是3.x版本的spring不再有这个参数。 那么怎么设置是否使用redis存储呢?只要导入了org.springframework.session包那就启用,不导入就不启用…

帝国cms网站忘记登陆账号密码怎么办

如果你忘记了帝国CMS的登录账号和密码,可以尝试以下方法来恢复访问权限:通过官方提供的找回功能:访问帝国CMS的登录页面。 查看是否有“忘记密码”链接。 点击此链接,并按照提示通过注册时绑定的邮箱或手机号来找回密码。手动重置数据库中的密码:使用数据库管理工具(如ph…

phpcmsV9 管理员密码丢失或忘记了怎么办

如果你在本地测试安装phpcmsV9时忘记了管理员密码,可以通过以下步骤手动重置密码: 方法/步骤打开数据库管理工具使用如phpMyAdmin这样的数据库管理工具连接到你的本地数据库。 通常,你可以通过访问 http://localhost/phpmyadmin/ 来打开phpMyAdmin。选择数据库和表选择你的p…

如何重置帝国CMS的忘记密码

重置帝国CMS的后台管理员密码可以通过以下方法实现: 方法一:使用官方提供的密码重置工具 如果帝国CMS官方提供了密码重置工具,可以使用该工具来重置密码:下载重置工具:从帝国CMS官方网站或其他可信来源下载官方提供的密码重置工具。 上传文件:将下载的重置工具文件上传到…