import pandas as pd
import os
import matplotlib.pyplot as plt
import pulp
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来显示负号
pd.set_option('display.max_columns', None) # 显示所有列
pd.set_option('display.max_rows', None) # 显示所有行
# pd.set_option('max_colwidth', 400)
# 读取上传的Excel文件 附件1和附件2
path = r'E:\2024全国大学生数学建模\C题'
file_1_path = os.path.join(path, '附件1.xlsx')
file_2_path = os.path.join(path, '附件2.xlsx')
countryside_existing_areas = pd.read_excel(file_1_path, sheet_name='乡村的现有耕地')
countryside_planting_crops = pd.read_excel(file_1_path, sheet_name='乡村种植的农作物')
planting_situation_2023 = pd.read_excel(file_2_path, sheet_name='2023年的农作物种植情况')
relevant_data_statistics_2023 = pd.read_excel(file_2_path, sheet_name='2023年统计的相关数据')
# 处理planting_situation_2023表格中的异常数据
for i, x in enumerate(planting_situation_2023['种植地块']):
if pd.isna(x):
planting_situation_2023['种植地块'][i] = planting_situation_2023['种植地块'][i-1]
# print('planting_situation_2023[种植地块]: \n', planting_situation_2023['种植地块'])
# print('----------------------------------------------------')
# 在planting_situation_2023中增加一列'地块类型'
planting_situation_2023 = pd.merge(planting_situation_2023, countryside_existing_areas[['种植地块', '地块类型']], on='种植地块', how='left')
print('planting_situation_2023: \n', planting_situation_2023)
print('----------------------------------------------------')
# print('relevant_data_statistics_2023: \n', relevant_data_statistics_2023)
# print('----------------------------------------------------')
# 首先将销售价格区间取平均值,方便计算
# 提取统计数据表中的销售单价信息,并将其从字符串转为数字区间的平均值
relevant_data_statistics_2023['销售单价/(元/斤)'] = relevant_data_statistics_2023['销售单价/(元/斤)'].apply(
lambda x: sum([float(i) for i in x.split('-')]) / 2 if '-' in str(x) else float(x)
)
# print('relevant_data_statistics_2023: \n', relevant_data_statistics_2023)
# print('----------------------------------------------------')
# 提取需要的字段并建立映射,准备进行模型计算
# 每种作物的亩产量
crop_yield = relevant_data_statistics_2023.set_index(['作物名称', '地块类型', '种植季次'])['亩产量/斤'].to_dict()
# 每种作物的种植成本
crop_cost = relevant_data_statistics_2023.set_index(['作物名称', '地块类型', '种植季次'])['种植成本/(元/亩)'].to_dict()
# 每种作物的销售价格
crop_price = relevant_data_statistics_2023.set_index(['作物名称', '地块类型', '种植季次'])['销售单价/(元/斤)'].to_dict()
# 每一块田的面积
every_area = countryside_existing_areas['地块面积/亩']
# print(every_area[0])
# print('crop_yield: \n', crop_yield)
# print('----------------------------------------------------')
# print('crop_cost: \n', crop_cost)
# print('----------------------------------------------------')
# print('crop_price: \n', crop_price)
# print('----------------------------------------------------')
model = pulp.LpProblem("Maximize_Total_income", pulp.LpMaximize)
x = pulp.LpVariable.dicts("x", [(i, j, k, t) for i in range(1, 42) for j in range(1, 55) for k in range(1, 3) for t in range(1, 8)],
lowBound=0, cat='Continuous')
# 决策变量b[(i, j, t)],决定干田上是否种植豆类(如果种植,该块干田全部种植豆类)
b1 = pulp.LpVariable.dicts("b1", [(i, j, t) for i in range(1, 6) for j in range(1, 27) for t in range(1, 6)],
lowBound=0, cat='Binary')
# 决策变量z[(i, j, t)],决定第j块干田第t年是否种植第i种作物(任意一块干田不能连续两年种植同一种作物)
b2 = pulp.LpVariable.dicts("b2", [(i, j, t) for i in range(1, 16) for j in range(1, 27) for t in range(1, 7)],
lowBound=0, cat='Binary')
# 决策变量u[(i, j, t)],决定第j块水浇地第t年是否种植水稻(水稻只能种植一季)
b3 = pulp.LpVariable.dicts("b3", [(i, j, t) for i in range(16, 17) for j in range(27, 35) for t in range(1, 7)],
lowBound=0, cat='Binary')
# 决策变量b4[(i, j, t)],决定水浇地上是否种植豆类(任意一块水浇地最近三年之内要种植过豆类)
b4 = pulp.LpVariable.dicts("b4", [(i, j, t) for i in range(17, 20) for j in range(27, 35) for t in range(1, 6)],
lowBound=0, cat='Binary')
# 决策变量b5[(i, j, t)],决定同年的两季智慧大棚是否种植第i种作物(智能大棚两季不能种植同一种作物)
b5 = pulp.LpVariable.dicts("b5", [(i, j, t) for i in range(17, 35) for j in range(51, 55) for t in range(1, 7)],
lowBound=0, cat='Binary')
# 决策变量b6[(i, j, t)],决定隔年的两季智慧大棚是否种植第i种作物(智能大棚两季不能种植同一种作物)
b6 = pulp.LpVariable.dicts("b6", [(i, j, t) for i in range(17, 35) for j in range(51, 55) for t in range(1, 7)],
lowBound=0, cat='Binary')
# 决策变量b7[(i, j, t)],决定智慧大棚是否种植豆类(任意一块水浇地最近三年之内要种植过豆类)
b7 = pulp.LpVariable.dicts("b7", [(i, j, k, t) for i in range(17, 20) for j in range(51, 55) for k in range(1, 3) for t in range(1, 6)],
lowBound=0, cat='Binary')
# ******************干田约束**********************
# 任意一块干田上作物的面积应小于该块干田的面积
for j in range(1, 27):
for k in range(1, 2):
for t in range(1, 8):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(1, 16)) <= every_area[j - 1]
# 任意一块干田最近三年之内要种植过豆类
for i in range(1, 6):
for j in range(1, 27):
for k in range(1, 2):
for t in range(1, 6):
model += pulp.lpSum(x[(i, j, k, t)] for t in range(t, t+3)) >= 0.001
# 同上
for i in range(1, 6):
for j in range(1, 27):
for k in range(1, 2):
for t in range(1, 8):
model += x[(i, j, k, t)] == b1[(i, j, t)] * every_area[j - 1]
# 任意一块干田不能连续两年种植同一种作物
for i in range(1, 16):
for j in range(1, 27):
for k in range(1, 2):
for t in range(1, 7):
model += x[(i, j, k, t)] <= every_area[j - 1] * b2[(i, j, t)]
model += x[(i, j, k, t+1)] <= every_area[j - 1] * (1 - b2[(i, j, t)])
# 水稻只能种植一季
for i in range(16, 17):
for j in range(27, 35):
for k in range(1, 2):
for t in range(1, 7):
model += x[(i, j, k, t)] <= every_area[j - 1] * b3[(i, j, t)]
model += x[(i, j, k, t + 1)] <= every_area[j - 1] * (1 - b3[(i, j, t)])
# 任意一块水浇地最近三年之内要种植过豆类
for i in range(17, 20):
for j in range(27, 35):
for k in range(1, 2):
for t in range(1, 6):
model += pulp.lpSum(x[(i, j, k, t)] for t in range(t, t+3)) >= 0.001
# 同上
for i in range(17, 20):
for j in range(27, 35):
for k in range(1, 2):
for t in range(1, 8):
model += x[(i, j, k, t)] == b4[(i, j, t)] * every_area[j - 1]
# 任意一块水浇地上作物的面积应小于该块水浇地的面积(第一季)
for j in range(27, 35):
for k in range(1, 2):
for t in range(1, 8):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(17, 35)) <= every_area[j - 1]
# 任意一块水浇地上作物的面积应小于该块水浇地的面积(第二季)(水浇地两季作物不同)
for j in range(27, 35):
for k in range(2, 3):
for t in range(1, 8):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(35, 38)) <= every_area[j - 1]
# 任意一块普通大棚作物的面积应小于该块普通大棚的面积(第一季)
for j in range(17, 35):
for k in range(1, 2):
for t in range(1, 8):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(17, 35)) <= every_area[j - 1]
# 任意一块普通大棚作物的面积应小于该块普通大棚的面积(第二季)(普通大棚两季作物不同)
for j in range(35, 51):
for k in range(2, 3):
for t in range(1, 8):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(38, 42)) <= every_area[j - 1]
# 任意一块智能大棚作物的面积应小于该块智能大棚的面积(两季)
for j in range(51, 55):
for k in range(1, 3):
for t in range(1, 7):
model += pulp.lpSum(x[(i, j, k, t)] for i in range(17, 35)) <= every_area[j - 1]
# 智能大棚两季不能种植同一种作物
for i in range(17, 35):
for j in range(51, 55):
for t in range(1, 7):
# 智能大棚隔年的两季不能种植同一种作物
model += x[(i, j, 2, t)] <= every_area[j - 1] * b6[(i, j, t)]
model += x[(i, j, 1, t+1)] <= every_area[j - 1] * (1 - b6[(i, j, t)])
# 同上
for i in range(17, 35):
for j in range(51, 55):
for t in range(1, 8):
# 智能大棚同年的两季不能种植同一种作物
model += x[(i, j, 1, t)] <= every_area[j - 1] * b5[(i, j, t)]
model += x[(i, j, 2, t)] <= every_area[j - 1] * (1 - b5[(i, j, t)])
# 任意一块智慧大棚最近三年之内要种植过豆类
for i in range(17, 20):
for j in range(51, 55):
for t in range(1, 6):
model += pulp.lpSum(x[(i, j, 1, t)] for t in range(t, t+3)) + pulp.lpSum(x[(i, j, 2, t)] for t in range(t, t+3)) >= 0.001
# 接上,任意一块智慧大棚若种植豆类应种满
for i in range(17, 20):
for j in range(51, 55):
for k in range(1, 3):
for t in range(1, 8):
model += x[(i, j, k, t)] == every_area[j - 1] * b7[(i, j, k, t)]
for i in range(1, 16):
for j in range(51, 55):
for k in range(1, 3):
for t in range(1, 8):
pass
02-23
3万+
01-17
5343
03-08
2793
07-30
4116