碧蓝档案活动刷本最优化计算
使用最少的体力获取指定需要的资源
import re
from scipy import optimize
import numpy as np
# 完成前置任务后的初始资源数 [货币1, 货币2, 抽奖券, 活动点数]
init_items = np.array([1849, 1830, 2588, 0])
# 商店 1 需要的资源
store1 = """
1x90 3x95 12x30 60x12
10x30 30x18 100x12 300x4
5x45 15x22 50x12 200x6
5x45 15x22 50x12 200x6
200x10 200x10 300x1 2000x1
"""
# 商店 2 需要的资源
store2 = """
1x180 3x95 15x30 60x12
5x50 15x38 50x25 300x15
5x45 15x22 50x12 200x6
200x10 200x10 300x1 2000x1
"""
# 抽奖池消耗资源
item3 = 8 * 1800
# 活动点数总需求
item4 = 0
# 奖励倍率 [货币1, 货币2, 抽奖券, 活动点数]
multiplier = np.array([1.85, 1.85, 1.8, 1])
# 战斗获得的资源基础值 [货币1, 货币2, 抽奖券, 活动点数]
battle1 = np.array([
6, 6, 20, 0
])
battle2 = np.array([
32, 0, 0, 0
])
battle3 = np.array([
0, 32, 0, 0
])
battle4 = np.array([
0, 0, 32, 0
])
cost = np.array([
20, 20, 20, 20
])
item1 = 0
item2 = 0
for entry in re.findall(r"(\d+)\s?[x*]\s?(\d+)", store1):
item1 += int(entry[0]) * int(entry[1])
for entry in re.findall(r"(\d+)\s?[x*]\s?(\d+)", store2):
item2 += int(entry[0]) * int(entry[1])
# 各个物品的需求量
items = np.array([item1, item2, item3, item4])
# 系数矩阵
A = np.array([battle1, battle2, battle3, battle4])
A = np.ceil(A * multiplier).T
# battle1_item1 * multiplier1 * battle1_count + battle2_item1 * multiplier1 * battle2_count + ... >= item1
# battle1_item2 * multiplier2 * battle1_count + battle2_item2 * multiplier2 * battle2_count + ... >= item2
# ...
# 目标函数 20 * battle1_count + 20 * battle2_count + ... -> min 即消耗体力数的最小值
result = optimize.linprog(cost, A_ub=-A, b_ub=-items, method="highs")
(battle1_count, battle2_count, battle3_count, battle4_count) = np.ceil(result.x).astype(int)
all_cost = np.sum(np.ceil(cost * result.x)).astype(int)
print(f"消耗体力数: {all_cost: 8}")
print(f"关卡 1 刷 {battle1_count: 5} 次")
print(f"关卡 2 刷 {battle2_count: 5} 次")
print(f"关卡 3 刷 {battle3_count: 5} 次")
print(f"关卡 4 刷 {battle4_count: 5} 次")