背景
最优组合问题:如何搭配背包里的种子,能够最大性价比地获取想要的属性果实。
机制
本机制整理来源于贴吧、游民星空和b站。
这个视频解说会很详细《火纹:风花雪月》栽培、种植详细讲解(附作业本)_单机游戏热门视频
- 一次性最多可以种5个种子。
- 收获的产物的种类取决于种子以及种子的搭配。
- 收获质量受种子的隐藏值和培育等级影响。
- 收获数量取决于种子数量和培育等级。
- 收获物品会有属性果和非属性果的其他产物,但是我们只关心属性果。
-
种植方法 培育等级 注入魔力 0 水灌溉 1 委托苗间 2 播撒骨粉 3 铺土壤 4 天马恩惠 5 - 收获数=5+种子数+培育等级+5(如果是大地祝福节日)
- 除初学者用种子,所有种子都可能培育出加属性的果实,但每个种子出的属性果不同。
- 不是每一种搭配都能收获属性果。
-
种子名称 数值1 数值2 属性 草本植物种子 3 0 力量 美朵拉西方产种子 9 0 HP 根茎植物种子 1 0 守备 蔬菜种子 9 0 魔防 芙朵拉北方产种子 5 0.8 魅力 摩尔菲斯蜜李种子 6 2.4 技巧 芙朵拉南方产种子 1 0.8 魔力 摩尔菲斯产种子 11 0.8 技巧 萨拉德寒冰菜种子 3 2.4 速度 蛇果种子 7 3.2 幸运 阿鲁比聂产种子 8 0.8 魅力 芙朵拉东方产种子 6 0.8 守备 白芷种子 10 3.2 力量 果树种子 8 0 幸运 红色花朵种子 0 1.6 魔防 白色花朵种子 5 1.6 魅力 蓝色花朵种子 2 1.6 HP 紫色花朵种子 4 1.6 力量 黄色花朵种子 7 1.6 魔力 绿色花朵种子 10 1.6 技巧 水蓝色花朵种子 1 1.6 速度 初学者用种子 0 0 无 - 属性果只会产出一个。
- 如果不同种子对应的属性果不是同一个,那就会从这些属性果中随机一个。
- 属性果的收获概率依据搭配种子的累计收获概率计算。如5个种子的收获概率都是10%,那么这种搭配组合下,能够出属性果的概率是50%。
- 种子的收获概率受到评价公式的影响,评价值越高,收获概率越高。
- 评价值=(12-(sum“数值1”÷12的余数))*5+sum“数值2”+( 培育等级+5)*2
- 每个种子的收获概率有以下对应:
评价值 收获概率(%) 0~20 1 21~40 3 41~60 5 61~80 10 81~90 15 91~100 20
根据上述规则构建代码:
import pandas as pd
import numpy as np
import pulp
# 1. 输入
# 预期属性
a = '力量'
# 培育等级
L = 5
# df = pd.read_csv('种子栽培.csv', header=0) #see种子栽培csv
df = pd.read_excel('./seednew.xlsx')
# user = pd.read_csv('user1.csv', header=0) #随便弄的一个用户
df_bag = df.loc[df['背包个数'].replace(0,np.nan).dropna().index]
df_bag_a = set(df_bag['属性'])
if a not in df_bag_a:
print(f'背包里没有{a}种子')
print(f'可以尝试其它属性:{df_bag_a}')
seed_num = df_bag['背包个数'].sum()
if seed_num<= 5:
print('种子数较少,不需要寻优')
weight_ratios = [(w,1-w) for w in [0,0.2,0.4,0.6,0.8,1]]
pareto_solutions = []
for main_weight,additional_weight in weight_ratios:
problem = pulp.LpProblem('seed_selection',pulp.LpMaximize)
x = [pulp.LpVariable(f'x{i}',lowBound=0,upBound=df_bag['背包个数'][i],cat='Integer') for i in df_bag.index]
problem += pulp.lpSum([
main_weight*((12-(x[ind]* df_bag['数值1'][i])/12)*5
+x[ind]* df_bag['数值2'][i]
+(L+5)+2) for ind,i in enumerate(df_bag.index)]) +\
pulp.lpSum([x[ind]*additional_weight for ind,i in enumerate(df_bag.index) if df_bag['属性'][i]==a])
problem += pulp.lpSum([x[i]for i in range(len(df_bag))])== 5
#求解问题
problem.solve()
if pulp.LpStatus[problem.status] == 'Optimal':
solution = [x[i].varValue for i in range(len(df_bag))]
pareto_solutions.append((solution,pulp.value(problem.objective)))
# 输出结果
for idx,(solution,objective) in enumerate(pareto_solutions):
print(f'\n搭配{idx+1}:')
for ind,seed_best_num in enumerate(solution):
if seed_best_num:
print(f'{df_bag.iloc[ind,0]}的个数:{int(seed_best_num)}')
使用这个excel文件,可以修改自己的背包种子数,代码的a变量替换为自己想要的属性
如果用预设值优化,最终结果如下(越靠后的搭配,出指定属性的概率越高,越靠前的搭配,越容易出属性果):
搭配1:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1
搭配2:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1
搭配3:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1
搭配4:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1
搭配5:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1
搭配6:
根茎植物种子的个数:3
紫色花朵种子的个数:1
水蓝色花朵种子的个数:1