1376 lines
51 KiB
Plaintext
1376 lines
51 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"id": "e19ec4ae5347c678",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.063825Z",
|
||
"start_time": "2024-09-08T08:06:03.748257Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"import pandas as pd\n",
|
||
"\n",
|
||
"pd.options.display.max_columns = 100"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 1
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "initial_id",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.504512Z",
|
||
"start_time": "2024-09-08T08:06:04.064830Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"\n",
|
||
"df_crop_details = pd.read_excel('./data/2.xlsx', sheet_name=1)"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 2
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "1d2a51b3414be94",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.520325Z",
|
||
"start_time": "2024-09-08T08:06:04.505719Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 去除空格\n",
|
||
"df_crop_details['cropName'] = df_crop_details['cropName'].apply(lambda x: x.strip())\n",
|
||
"# CropType = [x.strip() for x in CropType]\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 3
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "514cd9136d9ca341",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.551546Z",
|
||
"start_time": "2024-09-08T08:06:04.522370Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"df_crop_planting = pd.read_excel('./data/2.xlsx', sheet_name=0)\n",
|
||
"# 照例去除一下空格\n",
|
||
"df_crop_planting['cropName'] = df_crop_planting['cropName'].apply(lambda x: x.strip())\n",
|
||
"# ffill\n",
|
||
"df_crop_planting['landName'] = df_crop_planting['landName'].ffill()\n",
|
||
"# df_crop_planting"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 4
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "1503f8b642c842db",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.583467Z",
|
||
"start_time": "2024-09-08T08:06:04.553055Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"df_land = pd.read_excel('./data/1.xlsx', sheet_name=0)\n",
|
||
"# 去除landType和landName的空格\n",
|
||
"df_land['landType'] = df_land['landType'].apply(lambda x: x.strip())\n",
|
||
"df_land['landName'] = df_land['landName'].apply(lambda x: x.strip())\n",
|
||
"# df_land"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 5
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "3cdf51a9a9d4d30f",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.598934Z",
|
||
"start_time": "2024-09-08T08:06:04.585407Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 计算利润\n",
|
||
"unit_profit_lsc = []\n",
|
||
"for line in df_crop_details.values:\n",
|
||
" s = str(line[7]).split('-')\n",
|
||
" unit_profit_lsc.append((float(s[0]) + float(s[1])) / 2 * line[5] - line[6])\n",
|
||
"df_crop_details['unitProfit'] = unit_profit_lsc\n",
|
||
"# df_crop_details"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 6
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "569016a9b90f841b",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.629979Z",
|
||
"start_time": "2024-09-08T08:06:04.599929Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"df_crop_type_land = pd.read_excel('./data/1.xlsx', sheet_name=1)\n",
|
||
"# 老规矩,去掉cropName和cropType的空格\n",
|
||
"df_crop_type_land['cropType'] = df_crop_type_land['cropType'].apply(lambda x: x.strip())\n",
|
||
"df_crop_type_land['cropName'] = df_crop_type_land['cropName'].apply(lambda x: x.strip())\n",
|
||
"# df_crop_type_land"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 7
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "a7661d84217b578c",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.646043Z",
|
||
"start_time": "2024-09-08T08:06:04.631981Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 搞一下季节和年份的集合\n",
|
||
"SeasonType = [\"单季\", \"第一季\", \"第二季\"]\n",
|
||
"SeasonDict = {\"单季\": 1, \"第一季\": 1, \"第二季\": 2}\n",
|
||
"SeasonNum = [1, 2]\n",
|
||
"years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 8
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "4a4e06a1f2d4d8ab",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.661620Z",
|
||
"start_time": "2024-09-08T08:06:04.647030Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 枚举地块类型\n",
|
||
"LandType = {\"A\": \"平旱地\", \"B\": \"梯田\", \"C\": \"山坡地\", \"D\": \"水浇地\", \"E\": \"普通大棚\", \"F\": \"智慧大棚\"}\n",
|
||
"# LandType"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 9
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "cc938565a63a8129",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.677628Z",
|
||
"start_time": "2024-09-08T08:06:04.664102Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 枚举地块\n",
|
||
"LandName = df_crop_planting['landName'].unique()\n",
|
||
"# LandName"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 10
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "dae53a6215cea525",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.693684Z",
|
||
"start_time": "2024-09-08T08:06:04.679628Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 枚举地块面积,取df_land的landName为key,landArea为value\n",
|
||
"LandArea = {x: df_land[df_land['landName'] == x]['landArea'].values[0] for x in LandName}\n",
|
||
"# LandArea"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 11
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "7a0e6cc209d93b56",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.709206Z",
|
||
"start_time": "2024-09-08T08:06:04.694711Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 读入作物名称\n",
|
||
"CropName = df_crop_details['cropName'].unique()\n",
|
||
"# CropName"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 12
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "8a280f918bb3139a",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.740752Z",
|
||
"start_time": "2024-09-08T08:06:04.710206Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 作物分类\n",
|
||
"CropType = {x: df_crop_type_land[df_crop_type_land['cropType'] == x]['cropName'].values for x in\n",
|
||
" df_crop_type_land['cropType'].values}\n",
|
||
"CropType['粮食(除了水稻)'] = CropType['粮食'][:-1] # 这样不太好,但能用\n",
|
||
"CropType['豆类'] = np.array(list(CropType['粮食(豆类)']) + list(CropType['蔬菜(豆类)']), dtype=object)\n",
|
||
"CropType['全粮食'] = np.array(list(CropType['粮食']) + list(CropType['粮食(豆类)']), dtype=object)\n",
|
||
"CropType['全粮食(除了水稻)'] = np.array(list(CropType['粮食'][:-1]) + list(CropType['粮食(豆类)']), dtype=object)\n",
|
||
"CropType['全蔬菜'] = np.array(list(CropType['蔬菜']) + list(CropType['蔬菜(豆类)']), dtype=object)\n",
|
||
"CropType['特殊蔬菜'] = np.array([\"大白菜\", \"白萝卜\", \"红萝卜\"], dtype=object)\n",
|
||
"CropType[\"普通蔬菜\"] = np.array([c for c in CropType['全蔬菜'] if c not in CropType['特殊蔬菜']], dtype=object)\n",
|
||
"CropType"
|
||
],
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"{'粮食(豆类)': array(['黄豆', '黑豆', '红豆', '绿豆', '爬豆'], dtype=object),\n",
|
||
" '粮食': array(['小麦', '玉米', '谷子', '高粱', '黍子', '荞麦', '南瓜', '红薯', '莜麦', '大麦', '水稻'],\n",
|
||
" dtype=object),\n",
|
||
" '蔬菜(豆类)': array(['豇豆', '刀豆', '芸豆'], dtype=object),\n",
|
||
" '蔬菜': array(['土豆', '西红柿', '茄子', '菠菜', '青椒', '菜花', '包菜', '油麦菜', '小青菜', '黄瓜',\n",
|
||
" '生菜', '辣椒', '空心菜', '黄心菜', '芹菜', '大白菜', '白萝卜', '红萝卜'], dtype=object),\n",
|
||
" '食用菌': array(['榆黄菇', '香菇', '白灵菇', '羊肚菌'], dtype=object),\n",
|
||
" '粮食(除了水稻)': array(['小麦', '玉米', '谷子', '高粱', '黍子', '荞麦', '南瓜', '红薯', '莜麦', '大麦'],\n",
|
||
" dtype=object),\n",
|
||
" '豆类': array(['黄豆', '黑豆', '红豆', '绿豆', '爬豆', '豇豆', '刀豆', '芸豆'], dtype=object),\n",
|
||
" '全粮食': array(['小麦', '玉米', '谷子', '高粱', '黍子', '荞麦', '南瓜', '红薯', '莜麦', '大麦', '水稻',\n",
|
||
" '黄豆', '黑豆', '红豆', '绿豆', '爬豆'], dtype=object),\n",
|
||
" '全粮食(除了水稻)': array(['小麦', '玉米', '谷子', '高粱', '黍子', '荞麦', '南瓜', '红薯', '莜麦', '大麦', '黄豆',\n",
|
||
" '黑豆', '红豆', '绿豆', '爬豆'], dtype=object),\n",
|
||
" '全蔬菜': array(['土豆', '西红柿', '茄子', '菠菜', '青椒', '菜花', '包菜', '油麦菜', '小青菜', '黄瓜',\n",
|
||
" '生菜', '辣椒', '空心菜', '黄心菜', '芹菜', '大白菜', '白萝卜', '红萝卜', '豇豆', '刀豆',\n",
|
||
" '芸豆'], dtype=object),\n",
|
||
" '特殊蔬菜': array(['大白菜', '白萝卜', '红萝卜'], dtype=object),\n",
|
||
" '普通蔬菜': array(['土豆', '西红柿', '茄子', '菠菜', '青椒', '菜花', '包菜', '油麦菜', '小青菜', '黄瓜',\n",
|
||
" '生菜', '辣椒', '空心菜', '黄心菜', '芹菜', '豇豆', '刀豆', '芸豆'], dtype=object)}"
|
||
]
|
||
},
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 13
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "bf6d61d66f06bdeb",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.756788Z",
|
||
"start_time": "2024-09-08T08:06:04.741752Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# any([x[-1] == ' ' for x in CropName])\n",
|
||
"# 居然有空格\n",
|
||
"# 现在去掉了"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 14
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "22f9730e3d9c1016",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:04.945877Z",
|
||
"start_time": "2024-09-08T08:06:04.757790Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 亩产量\n",
|
||
"unit_yield_lsc = {\n",
|
||
" l: {\n",
|
||
" 1: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['unitYield'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['unitYield'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" },\n",
|
||
" 2: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")\n",
|
||
" ]['unitYield'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")][\n",
|
||
" 'unitYield'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" }\n",
|
||
" }\n",
|
||
" for l in LandType.values()\n",
|
||
"}\n",
|
||
"\n",
|
||
"# unit_yield_lsc"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 15
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "99dbe4ca6c54db0b",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.134526Z",
|
||
"start_time": "2024-09-08T08:06:04.947314Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 亩利润\n",
|
||
"unit_profit_lsc = {\n",
|
||
" l: {\n",
|
||
" 1: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['unitProfit'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['unitProfit'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" },\n",
|
||
" 2: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")\n",
|
||
" ]['unitProfit'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")\n",
|
||
" ]['unitProfit'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" }\n",
|
||
" }\n",
|
||
" for l in LandType.values()\n",
|
||
"}\n",
|
||
"\n",
|
||
"# unit_profit_lsc"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 16
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.323451Z",
|
||
"start_time": "2024-09-08T08:06:05.135577Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 亩成本\n",
|
||
"unit_cost_lsc = {\n",
|
||
" l: {\n",
|
||
" 1: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['cost'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" ((df_crop_details['season'] == \"单季\") |\n",
|
||
" (df_crop_details['season'] == \"第一季\"))\n",
|
||
" ]['cost'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" },\n",
|
||
" 2: {\n",
|
||
" c: df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")\n",
|
||
" ]['cost'].values[0] if df_crop_details[\n",
|
||
" (df_crop_details['cropName'] == c) &\n",
|
||
" (df_crop_details['cropLandType'] == l) &\n",
|
||
" (df_crop_details['season'] == \"第二季\")\n",
|
||
" ]['cost'].values.size > 0 else 0\n",
|
||
" for c in CropName\n",
|
||
" }\n",
|
||
" }\n",
|
||
" for l in LandType.values()\n",
|
||
"}\n",
|
||
"# unit_cost_lsc"
|
||
],
|
||
"id": "1c8ad73eaea8be7a",
|
||
"outputs": [],
|
||
"execution_count": 17
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "13f2ccc7aa215d4c",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.338917Z",
|
||
"start_time": "2024-09-08T08:06:05.324337Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 每种作物的总需求\n",
|
||
"crop_demand = {\n",
|
||
" c: 0\n",
|
||
" for c in CropName\n",
|
||
"}\n",
|
||
"\n",
|
||
"# 这里需要另一张表\n",
|
||
"# 代码独立出来移到上面去了\n",
|
||
"\n",
|
||
"for line in df_crop_planting.values:\n",
|
||
" # 面积*该土地类型的亩产量 面积 地块类型字典 地块类型 季节 作物名称\n",
|
||
" crop_demand[line[2]] += line[4] * unit_yield_lsc[LandType[line[0][0]]][SeasonDict[line[5]]][line[2]]\n",
|
||
"\n",
|
||
"# crop_demand"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 18
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "5d09872708d40da4",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.386035Z",
|
||
"start_time": "2024-09-08T08:06:05.339917Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 准备开搞\n",
|
||
"from pulp import LpMaximize, LpProblem, LpVariable, lpSum, value, PULP_CBC_CMD, LpContinuous, LpBinary\n",
|
||
"import pulp"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 19
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "b6eff87c7a762769",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.401548Z",
|
||
"start_time": "2024-09-08T08:06:05.387014Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"model = LpProblem(\"Crop_Planting_Optimization_with_Specific_Rules\", LpMaximize)"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 20
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "7bfdb9425c3e9683",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.417576Z",
|
||
"start_time": "2024-09-08T08:06:05.402547Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# %timeit X = LpVariable.dicts(\"X\", (CropName, LandName, years, seasons), lowBound=0, cat=LpContinuous)\n",
|
||
"# %timeit XX = LpVariable.dicts(\"X\", [(c, l, y, s) for c in CropName for l in LandName for y in years for s in seasons],lowBound=0, cat=LpContinuous)"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 21
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "4cb129e20385a7ee",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.465493Z",
|
||
"start_time": "2024-09-08T08:06:05.418576Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"\n",
|
||
"t = []\n",
|
||
"for y in years:\n",
|
||
" for l in LandName:\n",
|
||
" for s in SeasonNum:\n",
|
||
" if l[0] in [\"A\", \"B\", \"C\"] and s == 1:\n",
|
||
" for c in CropType[\"全粮食(除了水稻)\"]:\n",
|
||
" t.append((c, l, y, s))\n",
|
||
" if l[0] == \"D\":\n",
|
||
" if s == 1:\n",
|
||
" for c in list(CropType[\"普通蔬菜\"]) + [\"水稻\"]:\n",
|
||
" t.append((c, l, y, s))\n",
|
||
" if s == 2:\n",
|
||
" for c in CropType[\"特殊蔬菜\"]:\n",
|
||
" t.append((c, l, y, s))\n",
|
||
" if l[0] == \"E\":\n",
|
||
" if s == 1:\n",
|
||
" for c in list(CropType[\"普通蔬菜\"]):\n",
|
||
" t.append((c, l, y, s))\n",
|
||
" if s == 2:\n",
|
||
" for c in CropType[\"食用菌\"]:\n",
|
||
" t.append((c, l, y, s))\n",
|
||
" if l[0] == \"F\":\n",
|
||
" for s in SeasonNum:\n",
|
||
" for c in CropType[\"普通蔬菜\"]:\n",
|
||
" t.append((c, l, y, s))\n",
|
||
"\n",
|
||
"\n",
|
||
"# X"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 22
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.496947Z",
|
||
"start_time": "2024-09-08T08:06:05.466594Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 地块l在y年的s季的种植c的量\n",
|
||
"X = LpVariable.dicts(\"X\", t,\n",
|
||
" lowBound=0,\n",
|
||
" cat=LpContinuous\n",
|
||
" )"
|
||
],
|
||
"id": "ca23e006a68f2993",
|
||
"outputs": [],
|
||
"execution_count": 23
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "9dab983ca7b3b607",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.528472Z",
|
||
"start_time": "2024-09-08T08:06:05.497934Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 地块l在y年的s季是否种植了c\n",
|
||
"# Y = LpVariable.dicts(\"crop_plant_bool\", (CropName, LandName, years, SeasonType), cat=LpBinary)\n",
|
||
"# Y = LpVariable.dicts(\"Y\", [(c, l, y, s) for c in CropName for l in LandName for y in years for s in SeasonNum],\n",
|
||
"# cat=LpBinary)\n",
|
||
"Y = LpVariable.dicts(\"Y\", t, cat=LpBinary)\n",
|
||
"\n",
|
||
"# Y"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 24
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.543616Z",
|
||
"start_time": "2024-09-08T08:06:05.530473Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# def is_feasible(c, l, y, s):\n",
|
||
"# if l[0] in [\"A\", \"B\", \"C\"] and (c not in CropType[\"全粮食(除了水稻)\"]):\n",
|
||
"# return False\n",
|
||
"# if l[0] == \"D\" and (c not in CropType[\"全蔬菜\"] and c!=\"水稻\"):\n",
|
||
"# return False\n",
|
||
"# if l[0] == 'E' and s==2 and (c not in CropType[\"食用菌\"]):\n",
|
||
"# return False\n",
|
||
"# if l[0] == 'F' and (c not in CropType[\"全蔬菜\"]):\n",
|
||
"# return False\n",
|
||
"# return True"
|
||
],
|
||
"id": "28c6686374b8ed76",
|
||
"outputs": [],
|
||
"execution_count": 25
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.559071Z",
|
||
"start_time": "2024-09-08T08:06:05.545501Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"tt = set(t)\n",
|
||
"\n",
|
||
"\n",
|
||
"def is_feasible(c, l, y, s):\n",
|
||
" return (c, l, y, s) in tt"
|
||
],
|
||
"id": "bf16c7f3ea10152f",
|
||
"outputs": [],
|
||
"execution_count": 26
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.745561Z",
|
||
"start_time": "2024-09-08T08:06:05.560052Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 确保与X进行01约束\n",
|
||
"# for c in CropName:\n",
|
||
"# for l in LandName:\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonNum:\n",
|
||
"# # if 1:\n",
|
||
"# if is_feasible(c, l, y, s):\n",
|
||
"# # 如果种植了作物,则种植面积大于0\n",
|
||
"# model += X[c, l, y, s] <= 100 * Y[c, l, y, s], f\"PlantingConstraint1_{c}_{l}_{y}_{s}\"\n",
|
||
"# # 如果未种植作物,则种植面积为0\n",
|
||
"# model += X[c, l, y, s] >= 0.001 * Y[c, l, y, s], f\"PlantingConstraint2_{c}_{l}_{y}_{s}\"\n",
|
||
"\n",
|
||
"\n",
|
||
"min_area = 0.2\n",
|
||
"for c in CropName:\n",
|
||
" for l in LandName:\n",
|
||
" for y in years:\n",
|
||
" for s in SeasonNum:\n",
|
||
" if is_feasible(c, l, y, s):\n",
|
||
" model += X[c, l, y, s] <= LandArea[l] * Y[c, l, y, s], f\"LandAreaConstraint_{c}_{l}_{y}_{s}\"\n",
|
||
" model += X[c, l, y, s] >= min_area * (\n",
|
||
" 1 if Y[c, l, y, s] else 0), f\"MinAreaConstraint_{c}_{l}_{y}_{s}\""
|
||
],
|
||
"id": "603175d36624172f",
|
||
"outputs": [],
|
||
"execution_count": 27
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.839721Z",
|
||
"start_time": "2024-09-08T08:06:05.748539Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 目标函数:总利润 = sum(x[i]*profit[c,l,s])\n",
|
||
"# model += lpSum( # 地块类型 季节 作物类型\n",
|
||
"# X[c, l, y, s] * unit_profit_lsc[LandType[l[0]]][s][c]\n",
|
||
"# for c, l, y, s in t\n",
|
||
"# ), \"total_profit\"\n",
|
||
"\n",
|
||
"# 定义超过需求的变量\n",
|
||
"# Excess = LpVariable.dicts(\"Excess\", [(c, y) for c in CropName for y in years], lowBound=0)\n",
|
||
"\n",
|
||
"# 初始化总目标函数的表达式\n",
|
||
"total_profit = lpSum([]) # 空的lpSum用于初始化\n",
|
||
"\n",
|
||
"# 累积每个作物、每个年份的利润和惩罚\n",
|
||
"for c in CropName:\n",
|
||
" for y in years:\n",
|
||
" # 计算利润部分\n",
|
||
" profit_term = lpSum(\n",
|
||
" X[c, l, y, s] * unit_profit_lsc[LandType[l[0]]][s][c]\n",
|
||
" for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
" )\n",
|
||
" \n",
|
||
" # 惩罚超过需求的部分:将每个地块、每个季节的单位成本与种植量相乘\n",
|
||
" penalty_term = lpSum(\n",
|
||
" X[c, l, y, s] * unit_cost_lsc[LandType[l[0]]][s][c]\n",
|
||
" for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
" ) - crop_demand[c] * lpSum(\n",
|
||
" unit_cost_lsc[LandType[l[0]]][s][c]\n",
|
||
" for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
" )\n",
|
||
" \n",
|
||
" # 累积到总目标函数中\n",
|
||
" total_profit += profit_term - penalty_term\n",
|
||
"\n",
|
||
"# 一次性将目标函数添加到模型中\n",
|
||
"model += total_profit, \"total_profit\"\n",
|
||
"# # 累积每个作物、每个年份的利润和惩罚\n",
|
||
"# for c in CropName:\n",
|
||
"# for y in years:\n",
|
||
"# # 计算利润部分,单位利润减去单位成本\n",
|
||
"# profit_term = lpSum(\n",
|
||
"# X[c, l, y, s] * (unit_profit_lsc[LandType[l[0]]][s][c])\n",
|
||
"# for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
"# )\n",
|
||
"# \n",
|
||
"# # 惩罚超过需求的部分\n",
|
||
"# penalty_term = Excess[c, y] * lpSum(unit_cost_lsc[LandType[l[0]]][s][c] for l in LandName for s in SeasonNum if\n",
|
||
"# is_feasible(c, l, y, s))\n",
|
||
"# \n",
|
||
"# # 累积到总目标函数中\n",
|
||
"# total_profit += profit_term - penalty_term\n",
|
||
"# \n",
|
||
"# # 一次性将目标函数添加到模型中\n",
|
||
"# model += total_profit, \"total_profit\"\n",
|
||
"# \n",
|
||
"# \n",
|
||
"# # 目标函数:利润部分和惩罚部分\n",
|
||
"# for c in CropName:\n",
|
||
"# for y in years:\n",
|
||
"# # 计算利润部分,单位利润减去单位成本\n",
|
||
"# profit_term = lpSum(\n",
|
||
"# X[c, l, y, s] * (unit_profit_lsc[LandType[l[0]]][s][c])\n",
|
||
"# for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
"# )\n",
|
||
"# \n",
|
||
"# # 惩罚超过需求的部分\n",
|
||
"# penalty_term = Excess[c, y] * lpSum(unit_cost_lsc[LandType[l[0]]][s][c] for l in LandName for s in SeasonNum if\n",
|
||
"# is_feasible(c, l, y, s)) # penalty_cost_per_unit 是每单位超过需求的惩罚成本\n",
|
||
"# \n",
|
||
"# # 添加到目标函数中\n",
|
||
"# model += profit_term - penalty_term, f\"total_profit_{c}_{y}\"\n"
|
||
],
|
||
"id": "4505b0f2fe6bf93d",
|
||
"outputs": [],
|
||
"execution_count": 28
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.855563Z",
|
||
"start_time": "2024-09-08T08:06:05.840637Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# # 添加需求约束\n",
|
||
"# for c in CropName:\n",
|
||
"# for y in years:\n",
|
||
"# model += lpSum(\n",
|
||
"# X[c, l, y, s] for l in LandName for s in SeasonNum if is_feasible(c, l, y, s)\n",
|
||
"# ) <= crop_demand[c] + Excess[c, y], f\"demand_constraint_{c}_{y}\""
|
||
],
|
||
"id": "a2fe5874538f1596",
|
||
"outputs": [],
|
||
"execution_count": 29
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.870378Z",
|
||
"start_time": "2024-09-08T08:06:05.856571Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 约束,启动!\n",
|
||
"# 条件1:每年的所有季节中每种作物的种植量必须小于需求量\n",
|
||
"# for c in CropName:\n",
|
||
"# for y in years:\n",
|
||
"# model += lpSum(X[c, l, y, s] * unit_yield_lsc[LandType[l[0]]][s][c] for l in LandName for s in SeasonNum if\n",
|
||
"# is_feasible(c, l, y, s)) <= \\\n",
|
||
"# crop_demand[c], f\"CropDemandConstraint_{c}_{y}\""
|
||
],
|
||
"id": "1f185c0856fbcf27",
|
||
"outputs": [],
|
||
"execution_count": 30
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "7e13de7700d38f19",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.901626Z",
|
||
"start_time": "2024-09-08T08:06:05.871321Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件2: 每年每季每块地的种植面积不能超过该地块的总面积\n",
|
||
"for l in LandName:\n",
|
||
" for y in years:\n",
|
||
" for s in SeasonNum:\n",
|
||
" model += lpSum(X[c, l, y, s] for c in CropName if is_feasible(c, l, y, s)) <= LandArea[\n",
|
||
" l], f\"LandAreaConstraint_{l}_{y}_{s}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 31
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "1f6ac4323825f28b",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.917541Z",
|
||
"start_time": "2024-09-08T08:06:05.902521Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件3: 平旱地、梯田和山坡地每年适宜单季种植[粮食类作物(水稻除外)]。因为除了[粮食类作物(水稻除外)]以外的作物似乎已经被上面的产量和利润的0给约束了,所以大概不需要做限制了吧\n",
|
||
"for l in LandName:\n",
|
||
" if l[0] in [\"A\", \"B\", \"C\"]: # [\"平旱地\", \"梯田\", \"山坡地\"]\n",
|
||
" for y in years:\n",
|
||
" model += lpSum(\n",
|
||
" Y[c, l, y, 2] for c in CropName if is_feasible(c, l, y, 2)) == 0, f\"SingleSeasonConstraint1_{y}_{l}\"\n",
|
||
" # model += lpSum(Y[c, l, y, 1] for c in CropType[\"全粮食(除了水稻)\"] if is_feasible(c, l, y, 1)) >= 1, f\"SingleSeasonConstraint2_{y}_{l}\"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 32
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "c0e9b6b37092f0e7",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.933622Z",
|
||
"start_time": "2024-09-08T08:06:05.918440Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件4: 水浇地每年可以单季种植水稻或两季种植蔬菜作物。\n",
|
||
"for l in LandName:\n",
|
||
" if l[0] == \"D\":\n",
|
||
" for y in years:\n",
|
||
" for c in CropType[\"全蔬菜\"]:\n",
|
||
" if is_feasible(c,l,y,2):\n",
|
||
" model += Y[\"水稻\", l, y, 1] + Y[c, l, y, 2] <= 1, f\"IrrigatedConstraint0_{l}_{y}_{c}\"\n",
|
||
"\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] in [\"D\"]:\n",
|
||
"# model += lpSum(Y[c, l, y, s] for c in CropType[\"全粮食(除了水稻)\"] for y in years for s in SeasonNum) == 0, f\"IrrigatedConstraint3_{l}\"\n",
|
||
"\n",
|
||
"# if l[0] != \"D\": # [\"水浇地\"]\n",
|
||
"# continue\n",
|
||
"# for y in years:\n",
|
||
"# model += (\n",
|
||
"# (lpSum(Y[\"水稻\", l, y, \"单季\"]) != 0) and\n",
|
||
"# (lpSum(\n",
|
||
"# Y[c, l, y, s]\n",
|
||
"# for c in CropType['全蔬菜']\n",
|
||
"# for s in [\"第一季\", \"第二季\"]\n",
|
||
"# ) == 0)\n",
|
||
"# ) or (\n",
|
||
"# (lpSum(Y[\"水稻\", l, y, \"单季\"]) == 0) and\n",
|
||
"# (lpSum(\n",
|
||
"# Y[c, l, y, s]\n",
|
||
"# for c in CropType['全蔬菜']\n",
|
||
"# for s in [\"第一季\", \"第二季\"]\n",
|
||
"# ) != 0)\n",
|
||
"# ), f\"irrigatedConstraint_{l}_{y}\"\n",
|
||
"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 33
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "8f8da502641f32fa",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.948896Z",
|
||
"start_time": "2024-09-08T08:06:05.934627Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件5: 若在某块水浇地种植两季蔬菜,第一季可种植多种蔬菜(大白菜、白萝卜和红萝卜除外);第二季只能种植大白菜、白萝卜和红萝卜中的一种(便于管理)。\n",
|
||
"# 感觉没必要,因为前面有field和profit为0的惩罚\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] != \"D\": # [\"水浇地\"]\n",
|
||
"# continue\n",
|
||
"# for c in CropType['全蔬菜']:\n",
|
||
"# for y in years:\n",
|
||
"# if c not in CropType['特殊蔬菜']:\n",
|
||
"# if is_feasible(c, l, y, 2):\n",
|
||
"# model += Y[c, l, y, 2] == 0, f\"SpecialCropConstraint_{l}_{c}_{y}_第二季\"\n",
|
||
"# else:\n",
|
||
"# if is_feasible(c, l, y, 1):\n",
|
||
"# model += Y[c, l, y, 1] == 0, f\"SpecialCropConstraint_{l}_{c}_{y}_第一季\"\n",
|
||
" # if c not in CropType['特殊蔬菜']:\n",
|
||
" # model += lpSum(Y[c, l, y, 2] for y in years) == 0, f\"SpecialCropConstraint_{l}_{c}_第二季\"\n",
|
||
" # else:\n",
|
||
" # model += lpSum(Y[c, l, y, 1] for y in years) == 0, f\"SpecialCropConstraint_{l}_{c}_第一季\"\n",
|
||
"\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] != \"D\": # [\"水浇地\"]\n",
|
||
"# continue\n",
|
||
"# for y in years:\n",
|
||
"# model += lpSum(Y[\"水稻\", l, y, s] for s in [\"第一季\", \"第二季\"]) == 0, f\"SpecialCropConstraint1_{l}_{y}\"\n",
|
||
"# model += (lpSum(Y[c, l, y, s] for s in [\"第一季\", \"第二季\"] for c in CropType['全蔬菜']) >= 0) and (\n",
|
||
"# lpSum(Y[\"水稻\", l, y, \"单季\"]) == 0), f\"SpecialCropConstraint2_{l}_{y}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 34
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "df2d7e8918382a0",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.964928Z",
|
||
"start_time": "2024-09-08T08:06:05.950903Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件6: 根据季节性要求,大白菜、白萝卜和红萝卜只能在水浇地的第二季种植。\n",
|
||
"# for c in CropType[\"特殊蔬菜\"]:\n",
|
||
"# # for l in LandName:\n",
|
||
"# # if l[0] != \"D\": # [\"水浇地\"]\n",
|
||
"# # model += lpSum(Y[c, l, y, s] for y in years for s in SeasonNum for l in LandName if\n",
|
||
"# # l[0] != \"D\") == 0, f\"SpecialCropConstraint_{c}\"\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] != \"D\": # [\"水浇地\"]\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonNum:\n",
|
||
"# if is_feasible(c, l, y, s):\n",
|
||
"# model += Y[c, l, y, s] == 0, f\"SpecialCropConstraint_{c}_{l}_{y}_{s}\"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 35
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "1d402d3df13f6732",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.980443Z",
|
||
"start_time": "2024-09-08T08:06:05.965932Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件7: 大棚没有单季。普通大棚每年种植两季作物,第一季可种植多种蔬菜(大白菜、白萝卜和红萝卜除外),第二季只能种植食用菌。\n",
|
||
"# for l in LandName:\n",
|
||
"# for y in years:\n",
|
||
"# for c in CropName:\n",
|
||
"# if l[0] in [\"E\", \"F\"]: # 大棚\n",
|
||
"# model += lpSum(Y[c, l, y, \"单季\"]) == 0, f\"SpecialCropConstraint_{c}_{y}_{l}\"\n",
|
||
"\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] == \"E\": # [\"普通大棚\"]\n",
|
||
"# # model += lpSum(Y[c, l, y, 1] for c in CropType[\"特殊蔬菜\"] for y in years) == 0, f\"SpecialCropConstraint_{l}\"\n",
|
||
"# # model += lpSum(Y[c, l, y, 2] for c in CropName if c not in CropType[\"食用菌\"] for y in\n",
|
||
"# # years) == 0, f\"SpecialCropConstraint1__{l}\"\n",
|
||
"# for y in years:\n",
|
||
"# for c in CropType[\"特殊蔬菜\"]:\n",
|
||
"# if is_feasible(c, l, y, 1):\n",
|
||
"# model += Y[c, l, y, 1] == 0, f\"SpecialCropConstraint1_{l}_{y}_{c}\"\n",
|
||
"# for c in CropName:\n",
|
||
"# if c not in CropType[\"食用菌\"]:\n",
|
||
"# if is_feasible(c, l, y, 2):\n",
|
||
"# model += Y[c, l, y, 2] == 0, f\"SpecialCropConstraint2_{l}_{y}_{c}\"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 36
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "930ab378623172ec",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:05.996056Z",
|
||
"start_time": "2024-09-08T08:06:05.982444Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件8: 食用菌类只能在普通大棚第二季的时候种植\n",
|
||
"# for c in CropType[\"食用菌\"]:\n",
|
||
"# # model += lpSum(Y[c, l, y, s] for y in years for l in LandName if l[0] != \"E\" for s in\n",
|
||
"# # SeasonNum) == 0, f\"SpecialCropConstraint2_{c}\"\n",
|
||
"# # model += lpSum(Y[c, l, y, 1] for l in LandName if l[0] == \"E\" for y in years) == 0, f\"SpecialCropConstraint3_{c}\"\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonNum:\n",
|
||
"# model += lpSum(Y[c, l, y, s] for l in LandName if l[0] != \"E\" if\n",
|
||
"# is_feasible(c, l, y, s)) == 0, f\"SpecialCropConstraint2_{y}_{c}_{s}\"\n",
|
||
"# model += lpSum(Y[c, l, y, 1] for l in LandName if l[0] == \"E\" if\n",
|
||
"# is_feasible(c, l, y, 1)) == 0, f\"SpecialCropConstraint3_{y}_{c}\"\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] != \"E\":\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonType:\n",
|
||
"# model += lpSum(Y[c, l, y, s] for c in CropType[\"食用菌\"]) == 0, f\"SpecialCropConstraint1_{l}_{y}_{s}\"\n",
|
||
"# else:\n",
|
||
"# for y in years:\n",
|
||
"# model += lpSum(Y[c, l, y, \"第一季\"] for c in CropType[\"食用菌\"]) == 0, f\"SpecialCropConstraint2_{l}_{y}\"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 37
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "bda8b4c538a097bc",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.011840Z",
|
||
"start_time": "2024-09-08T08:06:05.997121Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件9: 智慧大棚每年都可种植两季蔬菜(大白菜、白萝卜和红萝卜除外)\n",
|
||
"# for l in LandName:\n",
|
||
"# if l[0] == 'F':\n",
|
||
"# # model += lpSum(Y[c, l, y, s] for c in CropType[\"特殊蔬菜\"] for y in years for s in\n",
|
||
"# # SeasonNum) == 0, f\"SpecialCropConstraint4_{l}\"\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonNum:\n",
|
||
"# model += lpSum(Y[c, l, y, s] for c in CropType[\"特殊蔬菜\"] if\n",
|
||
"# is_feasible(c, l, y, s)) == 0, f\"SpecialCropConstraint1_{l}_{y}_{s}\"\n",
|
||
" # for y in years:\n",
|
||
" # model += lpSum(Y[c, l, y, \"第一季\"] for c in CropType[\"全蔬菜\"] if\n",
|
||
" # c not in CropType[\"特殊蔬菜\"]) >= 0, f\"SpecialCropConstrain3_{l}_{y}\"\n",
|
||
" # model += lpSum(Y[c, l, y, \"第二季\"] for c in CropType[\"全蔬菜\"] if\n",
|
||
" # c not in CropType[\"特殊蔬菜\"]) >= 0, f\"SpecialCropConstraint4_{l}_{y}\"\n",
|
||
" # model += lpSum(\n",
|
||
" # Y[c, l, y, s] for c in CropType[\"特殊蔬菜\"] for s in SeasonType) == 0, f\"SpecialCropConstraint5_{l}_{y}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 38
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "e8fb2dea1326a05b",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.043385Z",
|
||
"start_time": "2024-09-08T08:06:06.013345Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件10: 别种得太碎了,啥意思? 每种作物不超过4块地吧。\n",
|
||
"for c in CropName:\n",
|
||
" for y in years:\n",
|
||
" for s in SeasonNum:\n",
|
||
" model += lpSum(\n",
|
||
" Y[c, l, y, s] for l in LandName if is_feasible(c, l, y, s)) <= 3, f\"MaxCropTypeConstraint_{c}_{y}_{s}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 39
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.074027Z",
|
||
"start_time": "2024-09-08T08:06:06.044845Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 条件11: 每块地最大种植作物种类数3\n",
|
||
"for l in LandName:\n",
|
||
" for y in years:\n",
|
||
" for s in SeasonNum:\n",
|
||
" model += lpSum(\n",
|
||
" Y[c, l, y, s] for c in CropName if is_feasible(c, l, y, s)) <= 3, f\"MaxLandConstraint_{l}_{y}_{s}\""
|
||
],
|
||
"id": "b8d9ae82090818ec",
|
||
"outputs": [],
|
||
"execution_count": 40
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "49f1490823c6af3c",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.152311Z",
|
||
"start_time": "2024-09-08T08:06:06.075083Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件12: 最小种植面积:0.2吧\n",
|
||
"for l in LandName:\n",
|
||
" for y in years:\n",
|
||
" for s in SeasonNum:\n",
|
||
" for c in CropName:\n",
|
||
" if is_feasible(c, l, y, s):\n",
|
||
" model += X[c, l, y, s] >= 0.2 * (\n",
|
||
" 1 if X[c, l, y, s] else 0), f\"MinCropAreaConstraint_{c}_{l}_{y}_{s}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 41
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "bdf1048b83723f91",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.230187Z",
|
||
"start_time": "2024-09-08T08:06:06.153299Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件13 : 最重要的,不能重复种植同一块地同一年同一季的同一作物\n",
|
||
"# 每种作物在同一地块(含大棚)都不能连续重茬种植\n",
|
||
"\n",
|
||
"for l in LandName:\n",
|
||
" for c in CropName:\n",
|
||
" for y in years[1:]: # 单季不能连年种植 同一年不能连续种植 跨年也不能连续种植\n",
|
||
" if is_feasible(c, l, y - 1, 1) and is_feasible(c, l, y - 1, 2):\n",
|
||
" model += Y[c, l, y - 1, 1] + Y[c, l, y - 1, 2] <= 1, f\"RepeatPlantingConstraint_{c}_{l}_{y}\"\n",
|
||
" model += Y[c, l, y - 1, 2] + Y[c, l, y, 1] <= 1, f\"RepeatPlantingConstraint1_{c}_{l}_{y}\"\n",
|
||
" if is_feasible(c, l, y - 1, 1) and is_feasible(c, l, y, 1):\n",
|
||
" if l[0] in [\"A\", \"B\", \"C\"]: # and c in CropType[\"全粮食\"]:\n",
|
||
" model += Y[c, l, y - 1, 1] + Y[c, l, y, 1] <= 1, f\"RepeatPlantingConstraint2_{c}_{l}_{y}\"\n",
|
||
" elif l[0] == \"D\" and c == \"水稻\":\n",
|
||
" model += Y[c, l, y - 1, 1] + Y[c, l, y, 1] <= 1, f\"RepeatPlantingConstraint3_{c}_{l}_{y}\"\n",
|
||
"\n",
|
||
" # if y < years[-1]:\n",
|
||
" # model += Y[c, l, y, \"单季\"] + Y[c, l, y + 1, \"单季\"] <= 1, f\"SingleSeasonConstraint1_{c}_{l}_{y}\"\n",
|
||
" # model += Y[c, l, y, \"第一季\"] + Y[c, l, y + 1, \"第二季\"] <= 1, f\"DoubleSeasonConstraint1_{c}_{l}_{y}\"\n",
|
||
" # model += Y[c, l, y, \"第一季\"] + Y[c, l, y, \"第二季\"] <= 1, f\"DoubleSeasonConstraint2_{c}_{l}_{y}\"\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 42
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "50da0aff9c68ae24",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:06.245603Z",
|
||
"start_time": "2024-09-08T08:06:06.230862Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 条件14:从 2023 年开始,要求每个地块(含大棚) 在三年内至少种植一次豆类作物\n",
|
||
"for l in LandName:\n",
|
||
" for y in years[2:]: # 只需循环到倒数第三年,因为要考虑三年周期\n",
|
||
" # 在 y-2 到 y+2 之间的三年内,至少有一次豆类作物\n",
|
||
" model += lpSum(X[c, l, y_r, s]\n",
|
||
" for c in CropType['豆类']\n",
|
||
" for y_r in range(y - 2, y + 1)\n",
|
||
" for s in SeasonNum if is_feasible(c, l, y_r, s)) >= LandArea[l], f\"BeanConstraint_{l}_{y}\"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"# 条件13: 最重要的,从 2023 年开始要求每个地块(含大棚) 的所有土地三年内至少种植一次豆类作物\n",
|
||
"# CropType['豆类']\n",
|
||
"# for l in LandName:\n",
|
||
"# for y in years[:-2]:\n",
|
||
"# model += lpSum(Y[c,l,y_r,s] for c in CropType['豆类'] for y_r in range(y,y+3) for s in SeasonType)>=1, f\"BeanConstraint_{l}_{y}\"\n",
|
||
"# model += lpSum(X[c, l, y_r, s] for c in CropType['豆类'] for y_r in range(y, y + 3) for s in SeasonType) >= \\\n",
|
||
"# LandArea[l], f\"BeanConstraint_{l}_{y}\"\n",
|
||
"# model += lpSum(Y[c, l, y_r, \"单季\"] for c in CropType['豆类'] for y_r in\n",
|
||
"# range(y - 2, y + 1)) >= 1, f\"BeanConstraint1_{l}_{y}\"\n",
|
||
"# model += lpSum(Y[c, l, y_r, s] for c in CropType['豆类'] for y_r in range(y - 2, y + 1) for s in\n",
|
||
"# [\"第一季\", \"第二季\"]) >= 1, f\"BeanConstraint2_{l}_{y}\""
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 43
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "d4792a1210afca3b",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:15.814241Z",
|
||
"start_time": "2024-09-08T08:06:06.246550Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"%%time\n",
|
||
"model.solve(\n",
|
||
" pulp.GUROBI_CMD(msg=True,\n",
|
||
" timeLimit=7200,\n",
|
||
" threads=20,\n",
|
||
" options=[(\"Method\", 2), (\"MIPGap\", 0.0001)]))\n",
|
||
"\n",
|
||
"# model.solve()\n",
|
||
"# 创建求解器实例\n",
|
||
"# solver = pulp.PULP_CBC_CMD(\n",
|
||
"# timeLimit=120,\n",
|
||
"# threads=4,\n",
|
||
"# )\n",
|
||
"# solver.solve(model)\n",
|
||
"# print(Y)\n",
|
||
"\n"
|
||
],
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPU times: total: 0 ns\n",
|
||
"Wall time: 9.56 s\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"1"
|
||
]
|
||
},
|
||
"execution_count": 44,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 44
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:15.829436Z",
|
||
"start_time": "2024-09-08T08:06:15.815222Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# for c in CropName:\n",
|
||
"# for l in LandName:\n",
|
||
"# for y in years:\n",
|
||
"# for s in SeasonNum:\n",
|
||
"# print(f\"Y[({c}, {l}, {y}, {s})] = {pulp.value(Y[(c, l, y, s)])}\")"
|
||
],
|
||
"id": "c64b04effa808515",
|
||
"outputs": [],
|
||
"execution_count": 45
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "cb3f4e95111e3292",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:16.238091Z",
|
||
"start_time": "2024-09-08T08:06:15.830431Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"# 输出文件名,包含起始年份和结束年份\n",
|
||
"output_filename = f\"planting_plan_{years[0]}-{years[-1]}.xlsx\"\n",
|
||
"\n",
|
||
"with pd.ExcelWriter(output_filename) as writer:\n",
|
||
" for y in years:\n",
|
||
"\n",
|
||
" # 用于存储需要交换的DataFrame\n",
|
||
" sheets_to_swap = {}\n",
|
||
"\n",
|
||
" for s in SeasonNum:\n",
|
||
" # 创建一个空的 DataFrame,横轴为作物名称,纵轴为地块名称\n",
|
||
" result_table = pd.DataFrame(columns=CropName, index=LandName)\n",
|
||
"\n",
|
||
" # 填充表格数据\n",
|
||
" for l in LandName:\n",
|
||
" for c in CropName:\n",
|
||
" # 获取变量 X[c, l, y, s] 的值\n",
|
||
" if is_feasible(c, l, y, s):\n",
|
||
" crop_value = value(X[c, l, y, s])\n",
|
||
" if crop_value is not None and crop_value > 0:\n",
|
||
" result_table.at[l, c] = crop_value # 填入结果\n",
|
||
"\n",
|
||
" # 用 0 填充空值\n",
|
||
" result_table.fillna(0, inplace=True)\n",
|
||
" sheet_name = f\"{y}_Season_第{s}季\"\n",
|
||
" result_table.to_excel(writer, sheet_name=sheet_name)\n",
|
||
"\n",
|
||
"print(f\"结果已保存到文件:{output_filename}\")\n"
|
||
],
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"结果已保存到文件:planting_plan_2024-2030.xlsx\n"
|
||
]
|
||
}
|
||
],
|
||
"execution_count": 46
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"id": "ebbf10d3",
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:16.687917Z",
|
||
"start_time": "2024-09-08T08:06:16.239987Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"import pandas as pd\n",
|
||
"\n",
|
||
"# 假设以下变量已经定义\n",
|
||
"# years, SeasonNum, CropName, LandName, X, value, output_filename\n",
|
||
"\n",
|
||
"with pd.ExcelWriter(output_filename) as writer:\n",
|
||
" for y in years:\n",
|
||
" # 用于存储需要交换的DataFrame\n",
|
||
" sheets_to_swap = {}\n",
|
||
"\n",
|
||
" for s in SeasonNum:\n",
|
||
" # 创建一个空的 DataFrame,横轴为作物名称,纵轴为地块名称\n",
|
||
" result_table = pd.DataFrame(columns=CropName, index=LandName)\n",
|
||
"\n",
|
||
" # 填充表格数据\n",
|
||
" for l in LandName:\n",
|
||
" for c in CropName:\n",
|
||
" # 获取变量 X[c, l, y, s] 的值\n",
|
||
" if is_feasible(c, l, y, s):\n",
|
||
" crop_value = value(X[c, l, y, s])\n",
|
||
" if crop_value is not None and crop_value > 0:\n",
|
||
" result_table.at[l, c] = crop_value # 填入结果\n",
|
||
"\n",
|
||
" # 用 0 填充空值\n",
|
||
" result_table.fillna(0, inplace=True)\n",
|
||
"\n",
|
||
" # 对DataFrame中的所有数值进行四舍五入,保留两位小数\n",
|
||
" result_table = result_table.round(2)\n",
|
||
"\n",
|
||
" sheet_name = f\"{y}_Season_第{s}季\"\n",
|
||
" result_table.to_excel(writer, sheet_name=sheet_name)\n"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 47
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2024-09-08T08:06:16.703415Z",
|
||
"start_time": "2024-09-08T08:06:16.688918Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": "",
|
||
"id": "ab1fd16df70c4293",
|
||
"outputs": [],
|
||
"execution_count": 47
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.9.17"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|