将AMPL饮食规划模型转换为OR-Tools代码,解决变量与约束编写问题
变量定义修正
你当前的Buy变量定义不符合AMPL模型逻辑,硬编码了上下界为0和1000,没有使用模型定义的f_min、f_max参数,修正如下:
- 如果购买量是整数(比如按整份、整单位采购),保留
IntVar:
Buy = {} for f_ in FOOD: Buy[f_] = solver.IntVar(f_min[f_], f_max[f_], f'Buy[{f_}]')
- 如果购买量是连续数值(比如可以买1.5千克),替换为
NumVar:
Buy = {} for f_ in FOOD: Buy[f_] = solver.NumVar(f_min[f_], f_max[f_], f'Buy[{f_}]')
约束添加修正
你当前的约束写了两层循环逻辑错误,不需要遍历食物j,只需要对每个营养i,计算所有食物对应的营养摄入总和,再限制总和在n_min[i]和n_max[i]区间内即可,修正如下:
## 约束定义 for i in NUTR: # 计算当前营养i的总摄入量 total_nutr = solver.Sum(amt[i, j] * Buy[j] for j in FOOD) # 同时限制上下界,匹配AMPL的Diet约束 solver.Add(total_nutr >= n_min[i]) solver.Add(total_nutr <= n_max[i])
完整可运行参考代码片段
from ortools.linear_solver import pywraplp # 这里先初始化求解器,根据你的需求选择求解器后端,线性规划用GLOP,整数规划用CBC solver = pywraplp.Solver.CreateSolver('CBC') # 如果是连续变量就换成'GLOP' # ------------ 以下是你的参数定义部分(需要你提前赋值NUTR、FOOD、cost、f_min、f_max、n_min、n_max、amt) ------------ # NUTR = 你的营养集合 # FOOD = 你的食物集合 # cost = {food: 成本值} # f_min = {food: 最小购买量} # f_max = {food: 最大购买量} # n_min = {nutr: 营养最低摄入} # n_max = {nutr: 营养最高摄入} # amt = {(nutr, food): 单位食物的营养含量} # ------------ 变量定义 ------------ Buy = {} for f_ in FOOD: # 连续变量用NumVar,整数变量用IntVar Buy[f_] = solver.IntVar(f_min[f_], f_max[f_], f'Buy[{f_}]') # ------------ 目标函数 ------------ Total_Cost = solver.Sum([cost[j_] * Buy[j_] for j_ in FOOD]) solver.Minimize(Total_Cost) # ------------ 约束定义 ------------ for i in NUTR: total_nutr = solver.Sum(amt[i, j] * Buy[j] for j in FOOD) solver.Add(total_nutr >= n_min[i]) solver.Add(total_nutr <= n_max[i]) # ------------ 求解 ------------ status = solver.Solve() if status == solver.OPTIMAL: print('最优解找到:') for f_ in FOOD: print(f'购买{f_}: {Buy[f_].solution_value()} 单位') print(f'总成本: {solver.Objective().Value()}') else: print('没有找到可行解')
内容的提问来源于stack exchange,提问作者user903772
相关产品推荐
相关产品推荐

