profilBlog Server 测试服

cover

碧蓝档案活动刷本最优化计算

未分类
编辑

使用最少的体力获取指定需要的资源

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} 次")