带冷却的0-1背包变种:法术施法DPS最大化最优算法求解
最大化法术总伤害序列的最优解方案
问题重述
法师掌握若干法术,每个法术包含伤害、冷却时间、施法时间三个属性,冷却在施法开始时触发,施法过程不可中断。目标是找出能最大化总伤害的法术施放序列,该场景可归类为带冷却机制的0-1背包问题。现有方案存在以下局限性:
- Uniform Cost Search、A*、IDA*等搜索算法侧重起止点路径问题,不适合此类组合优化场景;
- 贪心算法无法保证最优解(例如Fireball、Frostbolt、Fireblast的组合中,选择低DPCT的Fireblast反而能获得更高DPS,说明需考虑法术选择的后续影响);
- 常规动态规划无法纳入冷却、施法时间因素,也无法追踪已使用的法术状态;
- 暴力DFS在法术数量达到15~25个时耗时过长,仅能作为兜底方案。
可行的最优解思路
1. 改进型状态压缩动态规划
针对常规DP的不足,重新定义状态以适配冷却和施法时间:
- 状态表示:用
dp[mask]存储两个值——完成当前法术组合的最早时间time,以及对应的最大伤害damage。其中mask是二进制位掩码,每一位代表对应法术是否已被使用。 - 状态转移:遍历每个已有的状态
mask,再遍历所有未被使用的法术i:- 若当前状态的
time满足法术i的冷却要求(未使用过则无冷却限制),则可以施放该法术:- 新掩码为
new_mask = mask | (1 << i) - 新完成时间为
new_time = time + cast_time[i] - 新伤害为
new_damage = damage + damage[i] - 若
new_mask对应的现有状态中,new_time更早且new_damage更高,或者new_time相同但new_damage更高,则更新该状态;若new_mask无对应状态,则直接添加。
- 新掩码为
- 若当前状态的
- 优化点:同一掩码下,仅保留时间更短、伤害更高的状态,其他状态无保留价值,可直接丢弃,大幅减少状态数量。
2. 分支定界法(暴力DFS的优化版)
通过剪枝逻辑减少无效搜索:
- 预计算估值:提前计算每个法术的理论最大潜在伤害(假设剩余时间内无冷却重复施放该法术的伤害)。
- 剪枝逻辑:在搜索过程中,若当前路径的已得伤害 + 剩余所有法术的理论最大伤害之和 <= 当前已知的最优解,则直接终止该分支的搜索。
- 搜索顺序优化:优先搜索伤害/施法时间比更高的法术,能更快找到较优解,从而更早触发剪枝,减少后续计算量。
3. 整数线性规划建模
适合离线计算场景,通过ILP求解器保证最优解:
- 变量定义:设
x_i为0或1,表示法术i是否被使用;t_i表示法术i的施放开始时间。 - 约束条件:
- 若
x_i=1,则t_i + cast_time[i]需符合总时间限制(若无固定总时间,需通过序列顺序约束保证时间逻辑); - 对于任意两个法术
i和j,若x_i=1且x_j=1:- 若
i在j之前施放,则t_j >= t_i + cooldown_time[i]; - 若
j在i之前施放,则t_i >= t_j + cooldown_time[j]。
- 若
- 若
- 目标函数:最大化
sum(x_i * damage[i]) - 可使用CPLEX、Gurobi等ILP求解器直接求解,适合法术数量中等的场景。
方案选择建议
- 若需代码实现且追求效率,改进型状态压缩DP是优先选择,状态剪枝后可有效处理15~25个法术的规模;
- 若追求实现简单且能接受一定计算时间,分支定界法是暴力DFS的高效替代;
- 若不限制工具且需严格最优解,整数线性规划适合离线计算场景。
内容的提问来源于stack exchange,提问作者evol1102
相关产品推荐
相关产品推荐

