简单介绍一下我自己:博主专注建模五年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。现提供免费的思路和部分源码,以后的数模比赛只要我还有时间肯定会第一时间写出免费开源思路。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码且完全免费。希望有需求的小伙伴不要错过笔者精心打造的文章。
数学建模的基本步骤大致如下:
我们依旧按如上步骤完成对C题的解析作答。
某乡村地处华北山区,常年温度偏低,大多数耕地每年只能种植一季农作物。该乡村现有露天耕地 1201 亩,分散为 34 个大小不同的地块,包括平旱地、梯田、山坡地和水浇地 4 种类型。平旱地、梯田和山坡地适宜每年种植一季粮食类作物;水浇地适宜每年种植一季水稻或两季蔬菜。该乡村另有 16 个普通大棚和 4 个智慧大棚,每个大棚耕地面积为 0.6 亩。普通大棚适宜每年种植一季蔬菜和一季食用菌,智慧大棚适宜每年种植两季蔬菜。同一地块(含大棚)每季可以合种不同的作物。
详见附件 1。
根据农作物的生长规律,每种作物在同一地块(含大棚)都不能连续重茬种植,否则会减产;因含有豆类作物根菌的土壤有利于其他作物生长,从 2023 年开始要求每个地块(含大棚)的所有土地三年内至少种植一次豆类作物。同时,种植方案应考虑到方便耕种作业和田间管理,譬如:每种作物每季的种植地不能太分散,每种作物在单个地块(含大棚)种植的面积不宜太小,等等。2023年的农作物种植和相关统计数据见附件 2。
请建立数学模型,研究下列问题:
假定各种农作物未来的预期销售量、种植成本、亩产量和销售价格相对于 2023 年保持稳定,每季种植的农作物在当季销售。如果某种作物每季的总产量超过相应的预期销售量,超过部分不能正常销售。请针对以下两种情况,分别给出该乡村 2024~2030 年农作物的最优种植方案,将结果分别填入 result1_1.xlsx 和 result1_2.xlsx 中(模板文件见附件 3)。
(1) 超过部分滞销,造成浪费;
(2) 超过部分按 2023 年销售价格的 50%降价出售。
本问题针对华北山区低温环境下的农作物种植规划与布局。在该地区,常规露天耕地每年只能种一季粮食类作物,而水浇地可以种水稻或两季蔬菜;大棚(普通与智慧大棚)则可多季种植特定作物。如何在有限的耕地和设施条件下,合理安排不同作物的轮作、搭配以及分布,从而达到最大化经济收益、满足作物轮作要求、保证土壤肥力与可持续发展成为一个重要的问题。
这是一道典型的农业经济数学建模问题,涉及多目标优化、种植规划和约束条件设计。首先,让我们梳理问题的关键信息和约束条件:
耕地资源:
种植约束:
附件1中列出作物编号、名称、类型及适宜种植耕地类型、季节限制,以及若干说明性约束。下面对关键信息进行提炼:
作物分类及种植季节限制:
蔬菜类作物: 分为豆类蔬菜(豇豆、刀豆、芸豆)和其他蔬菜类(土豆、西红柿、茄子、菠菜、青椒、菜花、包菜、油麦菜、小青菜、黄瓜、生菜、辣椒、空心菜、黄心菜、芹菜、大白菜、白萝卜、红萝卜)。
食用菌类作物(38-41号:榆黄菇、香菇、白灵菇、羊肚菌): 只能在普通大棚的第二季种植。
种植季节定义(参考注释):
特殊要求:
(1) 平旱地、梯田、山坡地:
(2) 水浇地:
(3) 普通大棚:
(4) 智慧大棚:
(5) 豆类轮作要求(来自上一轮描述,不在附件1中直接重复,但已知题意中提及三年内至少有一季豆类作物)
(6) 不连续重茬要求(同一地块不能连续种同一种作物)
(7) 同一季同一地块可以混合种不同作物(合种),但需满足最低面积分配要求等(题中可能会有后续约束)。
根据附件1与附件2,我们有以下信息:
地块类型与适宜作物(见附件1解析):
产量、成本、价格(见附件2):
$$
Y{j,i,s},C{j,i,s},P_{j}
$$
分别表示某作物j在地块类型与季节条件下的亩产量、成本和价格。
实际实现中,需先根据地块类型和季节,将附件2中的数据匹配到对应的i和s,然后再求解。
$Uj,s,t≥0$:该季该年作物 j 的产量超过预期销售量部分(斤)$U{j,s,t} \geq 0$: $\text{该季该年作物 } j \text{ 的产量超过预期销售量部分(斤)}$
$Wj,s,t≥0$:该季该年作物 j 的产量低于预期销售量部分(斤)$W{j,s,t} \geq 0$: $\text{该季该年作物 } j \text{ 的产量低于预期销售量部分(斤)}$
在最优解中,$U{j,s,t} $和 $W{j,s,t} $不会同时为正值。
$xi,j,s,t=0$若组合$ (i,j,s) $不可行$x_{i,j,s,t} = 0$ $\quad \text{若组合 }(i,j,s)\text{ 不可行}$
例如:平旱地、梯田、山坡地只种一季粮食类作物;水浇地两季蔬菜时第一季不种 35-37号作物,第二季只能种 35-37号之一;普通大棚第二季只能种食用菌;智慧大棚两季皆可种蔬菜(除35-37号)等。
产量定义与超产/不足部分:
总产量:
超出预期量:
未达预期量:
问题1要求求解两种情景下的最优种植方案。
记:
情形(1):超过部分滞销无收益
收益 = 正常价出售 $\min(Q{j,s,t},D{j,s,t})$ 的产量,超过部分无收益。
因此,
目标函数:
情形(2):超过部分按半价出售
若超产量为$U_{j,s,t}$,则该部分以$0.5P_j $出售。
同时,当 $Q{j,s,t}<D{j,s,t}$ 时,有不足部分 $W{j,s,t}$,正常价出售的数量为 $D{j,s,t}-W_{j,s,t}$。
综合可得:
目标函数:
这里将给出建模的基础代码结构和思路。后续可根据附件数据整理出相应的参数字典或数据表,再读入模型。
# 设定跨季约束需要知道上一季对应关系,如一年两季则上一季可能为(s-1,t)或跨年
# 对于季的衔接,这里假设S=[1,2], 则(s=1,t=2025)上一季为(s=2,t=2024)等
def prev_season(s, t):
# 返回上一季的(s', t')
if s == 1:
return (2, t-1)
else:
return (1, t)
# -----------------------------------------
# 建立模型
model = pyo.ConcreteModel("Farming_Optimization")
# 定义变量
model.x = pyo.Var(I, J, S, T, domain=pyo.NonNegativeReals) # x_{i,j,s,t}
model.U = pyo.Var(J, S, T, domain=pyo.NonNegativeReals) # U_{j,s,t}
model.W = pyo.Var(J, S, T, domain=pyo.NonNegativeReals) # W_{j,s,t}
# 二元变量 y_{i,j,s,t} 用于表示是否种植,用大M法或逻辑约束
# 为简化,这里直接定义y为二元变量
model.y = pyo.Var(I, J, S, T, domain=pyo.Binary)
# -----------------------------------------
# 约束条件
# 1. 土地利用约束
def land_use_rule(model, i, s, t):
return sum(model.x[i,j,s,t] for j in J) <= A[i]
model.LandUse = pyo.Constraint(I, S, T, rule=land_use_rule)
# 2. 适宜性与季节性约束
def feasibility_rule(model, i, j, s, t):
if no_plant[(i,j,s)]:
return model.x[i,j,s,t] == 0
return pyo.Constraint.Skip
model.Feasibility = pyo.Constraint(I, J, S, T, rule=feasibility_rule)
# 3. 不连续重茬约束
# 需要确保若上一季同地块同作物种了,则本季不种同作物
def no_repeated_rule(model, i, j, s, t):
s_prev, t_prev = prev_season(s, t)
if t_prev < min(T):
return pyo.Constraint.Skip
return model.y[i,j,s,t] + model.y[i,j,s_prev,t_prev] <= 1
model.NoRepeated = pyo.Constraint(I, J, S, T, rule=no_repeated_rule)
# x与y的关联:当x>0时 y=1,否则y=0
# 可以用如下方式: x[i,j,s,t] <= A[i]*y[i,j,s,t]
def x_y_link_rule(model, i, j, s, t):
return model.x[i,j,s,t] <= A[i]*model.y[i,j,s,t]
model.XYLink = pyo.Constraint(I, J, S, T, rule=x_y_link_rule)
# 4. 三年豆类轮作约束
# 对任意 i,t,连续三年内至少一季种豆类
# 以3年为一个窗口 t, t+1, t+2
def bean_rotation_rule(model, i, start_t):
# start_t从2024到2028
# 三年窗口 = start_t, start_t+1, start_t+2
# bean类作物某一季y=1则满足
years = [start_t, start_t+1, start_t+2]
return sum(model.y[i,j,s,t_] for t_ in years for s in S for j in bean_crops) >= 1
model.BeanRotation = pyo.Constraint(I, [t for t in T if t <= 2028], rule=bean_rotation_rule)
# 5. 产量与超/不足定义
# Q_{j,s,t} = sum_i Y_{j,i,s} x_{i,j,s,t}
def Q_expr(model, j, s, t):
return sum(Y[(j,i,s)]*model.x[i,j,s,t] for i in I)
model.Q = pyo.Expression(J, S, T, rule=Q_expr)
# 超出部分: U_{j,s,t} >= Q_{j,s,t}-D_{j,s,t}
def U_rule(model, j, s, t):
return model.U[j,s,t] >= model.Q[j,s,t] - D[(j,s,t)]
model.UConstraint = pyo.Constraint(J, S, T, rule=U_rule)
# 不足部分: W_{j,s,t} >= D_{j,s,t}-Q_{j,s,t}
def W_rule(model, j, s, t):
return model.W[j,s,t] >= D[(j,s,t)] - model.Q[j,s,t]
model.WConstraint = pyo.Constraint(J, S, T, rule=W_rule)
# -----------------------------------------
# 目标函数
# 对于问题1,我们有两种情景:
# 情形(1): 超出部分无收益
# Revenue = sum_{t,s,j} P_j*(D_{j,s,t}-U_{j,s,t})
# 情形(2): 超出部分半价出售
# Revenue = sum_{t,s,j} [P_j(D_{j,s,t}-W_{j,s,t}) + 0.5P_j U_{j,s,t}]
# 我们可以先定义一个参数 scenario 表示选择场景
scenario = 1 # 改为2即可切换情形(2)
def obj_rule(model):
if scenario == 1:
# 情形(1)
revenue = sum(P[j]*(D[(j,s,t)] - model.U[j,s,t]) for j in J for s in S for t in T)
else:
# 情形(2)
revenue = sum(P[j]*(D[(j,s,t)] - model.W[j,s,t]) + 0.5*P[j]*model.U[j,s,t] for j in J for s in S for t in T)
cost = sum(C[(j,i,s)]*model.x[i,j,s,t] for i in I for j in J for s in S for t in T)
return revenue - cost
model.OBJ = pyo.Objective(rule=obj_rule, sense=pyo.maximize)
# -----------------------------------------
# 求解模型
solver = pyo.SolverFactory('gurobi') # 或 cplex/glpk
results = solver.solve(model, tee=True)
# 输出结果到文件
# 假设需要将 x_{i,j,s,t} 的结果输出到 result1_1.xlsx 或 result1_2.xlsx
# 使用pandas写入excel是常规手段,此处仅示意:
import pandas as pd
solution_x = []
for i in I:
for j in J:
for s in S:
for t in T:
val = pyo.value(model.x[i,j,s,t])
if val > 1e-6: # 若有正种植面积
solution_x.append([i,j,s,t,val])
目前此题先到此,后续再整合完成其他问题解答,内容有点过多需要深刻理解。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。