pandas 在我的pyomo模型中没有正确的结果

wfypjpf4  于 2023-10-14  发布在  其他
关注(0)|答案(1)|浏览(77)

任务:拉里·爱迪生是巴克利学院计算机中心的主任。他现在需要安排中心的人员配备。从早上8点到午夜开放。Larry在一天中的不同时间监控了中心的使用情况,并确定需要以下数量的计算机顾问:轮班时间最少顾问人数A上午8点-中午4点B中午4点-下午4点8点C下午4点-下午8点10点D下午8点-午夜6点
可以雇用两种类型的计算机顾问:全职和兼职。专职顾问在下列任一班次连续工作8小时:上午(8 AM - 4 PM)、下午(中午- 8 PM)和晚上(4 PM -午夜)。全职顾问的工资为每小时40欧元。可以雇用兼职顾问从事上表所列四个班次中的任何一个。兼职顾问的工资为每小时30欧元。另一项要求是,在每段时间内,必须至少有两名全职咨询人与一名兼职咨询人值班。
Larry想确定每班应该有多少全职和兼职工人工作,以尽可能低的成本满足上述要求。用索引变量建立线性规划模型,并使用Pyomo求解。确保解决方案只能采用整数值,因为不可能只在轮班的一部分雇用工人。
写一个函数:
命名为model_larry_edison,没有参数返回pyomo模型模型应该有:一个目标,名为工资,最小化必须支付的工资金额。两个变量:full_time有三个指数,每个全时轮班一个指数,表明该轮班有多少全时工人值班。part-time有四个指数,每个非全时轮班一个指数,表明该轮班有多少非全时工人值班。八个约束四(A_total,B_total,C_total,D_total),确保满足每个4小时轮班所需的顾问人数。四个(A_ratio、B_ratio、C_ratio、D_ratio),确保在每4小时轮班中,全职顾问的数量至少是兼职顾问数量的两倍。

def model_larry_edison():

  salary_df_ft = pd.DataFrame()
  salary_df_ft.at["FT1", "Salary"] = 40
  salary_df_ft.at["FT2", "Salary"] = 40
  salary_df_ft.at["FT3", "Salary"] = 40

  salary_df_pt = pd.DataFrame()
  salary_df_pt.at["PT1", "Salary"] = 30
  salary_df_pt.at["PT2", "Salary"] = 30
  salary_df_pt.at["PT3", "Salary"] = 30
  salary_df_pt.at["PT4", "Salary"] = 30

  salary_ft = salary_df_ft.astype(int)
  salary_pt = salary_df_pt.astype(int)

  model = pyo.ConcreteModel('ProductionPlan')

  model.salary_ft = pyo.Set(initialize = salary_ft.index)
  model.salary_pt = pyo.Set(initialize = salary_pt.index)

  model.full_time = pyo.Var(model.salary_ft, bounds=(0,None))
  model.part_time = pyo.Var(model.salary_pt, bounds=(0,None))

  model.wage = pyo.Objective(expr = 320*(model.full_time["FT1"]+model.full_time["FT2"]+model.full_time["FT3"]) + 120*(model.part_time["PT1"]+model.part_time["PT2"]+model.part_time["PT3"]+model.part_time["PT4"]), sense=pyo.minimize)

  model.A_total = pyo.Constraint(expr = (model.full_time["FT1"] + model.part_time["PT1"]) >= 4)
  model.B_total = pyo.Constraint(expr = (model.full_time["FT1"] + model.full_time["FT2"] + model.part_time["PT2"]) >= 8)
  model.C_total = pyo.Constraint(expr = (model.full_time["FT2"] + model.full_time["FT3"] + model.part_time["PT3"]) >= 10)
  model.D_total = pyo.Constraint(expr = (model.full_time["FT3"] + model.part_time["PT4"]) >= 6)
  model.A_ratio = pyo.Constraint(expr = model.full_time["FT1"] >= 2*model.part_time["PT1"])
  model.B_ratio = pyo.Constraint(expr = (model.full_time["FT1"] + model.full_time["FT2"]) >= 2*model.part_time["PT2"])
  model.C_ratio = pyo.Constraint(expr = (model.full_time["FT2"] + model.full_time["FT3"]) >= 2*model.part_time["PT3"])
  model.D_ratio = pyo.Constraint(expr = model.full_time["FT3"] >= 2*model.part_time["PT4"])

  return model
model = model_larry_edison()
results = pyo.SolverFactory('cbc').solve(model)
print(model.wage())

预期结果是4160,但我得到4106.666666

kknvjkwl

kknvjkwl1#

你走在正确的道路上。
你应该问问自己:“我如何获得目标的分数值.?
答案是你没有将变量限制为整数!
尝试将变量声明更改为:

model.full_time = pyo.Var(model.salary_ft, domain=pyo.NonNegativeIntegers) #bounds=(0,None))
  model.part_time = pyo.Var(model.salary_pt, domain=pyo.NonNegativeIntegers) #bounds=(0,None))

在此之前/之后(以及在此之前/之后):养成打印模型(带变量)和答案(插入值)的习惯。它对于故障排除非常有价值:

model.pprint()   # the model
model.display()  # the model with the values plugged in

相关问题