{ "cells": [ { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:53.146868Z", "start_time": "2024-09-07T07:39:52.630439Z" } }, "cell_type": "code", "source": "import pandas as pd", "id": "e19ec4ae5347c678", "outputs": [], "execution_count": 1 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:53.919487Z", "start_time": "2024-09-07T07:39:53.146868Z" } }, "cell_type": "code", "source": [ "\n", "df_crop_details = pd.read_excel('./data/2.xlsx', sheet_name=1)" ], "id": "initial_id", "outputs": [], "execution_count": 2 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:53.935294Z", "start_time": "2024-09-07T07:39:53.919487Z" } }, "cell_type": "code", "source": [ "# 去除空格\n", "df_crop_details['cropName'] = df_crop_details['cropName'].apply(lambda x: x.strip())\n", "# CropType = [x.strip() for x in CropType]\n" ], "id": "1d2a51b3414be94", "outputs": [], "execution_count": 3 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:53.998096Z", "start_time": "2024-09-07T07:39:53.936656Z" } }, "cell_type": "code", "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" ], "id": "514cd9136d9ca341", "outputs": [ { "data": { "text/plain": [ " landName cropNum cropName cropType plantArea season\n", "0 A1 6 小麦 粮食 80.0 单季\n", "1 A2 7 玉米 粮食 55.0 单季\n", "2 A3 7 玉米 粮食 35.0 单季\n", "3 A4 1 黄豆 粮食(豆类) 72.0 单季\n", "4 A5 4 绿豆 粮食(豆类) 68.0 单季\n", ".. ... ... ... ... ... ...\n", "82 F3 28 小青菜 蔬菜 0.3 第二季\n", "83 F3 30 生菜 蔬菜 0.3 第二季\n", "84 F4 19 芸豆 蔬菜(豆类) 0.6 第一季\n", "85 F4 34 芹菜 蔬菜 0.3 第二季\n", "86 F4 23 菠菜 蔬菜 0.3 第二季\n", "\n", "[87 rows x 6 columns]" ], "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
landNamecropNumcropNamecropTypeplantAreaseason
0A16小麦粮食80.0单季
1A27玉米粮食55.0单季
2A37玉米粮食35.0单季
3A41黄豆粮食(豆类)72.0单季
4A54绿豆粮食(豆类)68.0单季
.....................
82F328小青菜蔬菜0.3第二季
83F330生菜蔬菜0.3第二季
84F419芸豆蔬菜(豆类)0.6第一季
85F434芹菜蔬菜0.3第二季
86F423菠菜蔬菜0.3第二季
\n", "

87 rows × 6 columns

\n", "
" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 4 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.013672Z", "start_time": "2024-09-07T07:39:53.998096Z" } }, "cell_type": "code", "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" ], "id": "3cdf51a9a9d4d30f", "outputs": [ { "data": { "text/plain": [ " no cropNum cropName cropLandType season unitYield cost price \\\n", "0 1 1 黄豆 平旱地 单季 400 400 2.50-4.00 \n", "1 2 2 黑豆 平旱地 单季 500 400 6.50-8.50 \n", "2 3 3 红豆 平旱地 单季 400 350 7.50-9.00 \n", "3 4 4 绿豆 平旱地 单季 350 350 6.00-8.00 \n", "4 5 5 爬豆 平旱地 单季 415 350 6.00-7.50 \n", ".. ... ... ... ... ... ... ... ... \n", "120 103 30 生菜 智慧大棚 第二季 4500 2200 5.40-7.20 \n", "121 104 31 辣椒 智慧大棚 第二季 1800 1300 7.20-10.20 \n", "122 105 32 空心菜 智慧大棚 第二季 11000 5500 3.60-7.20 \n", "123 106 33 黄心菜 智慧大棚 第二季 5400 2750 4.80-6.00 \n", "124 107 34 芹菜 智慧大棚 第二季 6000 1200 3.80-5.80 \n", "\n", " unitProfit \n", "0 900.00 \n", "1 3350.00 \n", "2 2950.00 \n", "3 2100.00 \n", "4 2451.25 \n", ".. ... \n", "120 26150.00 \n", "121 14360.00 \n", "122 53900.00 \n", "123 26410.00 \n", "124 27600.00 \n", "\n", "[125 rows x 9 columns]" ], "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nocropNumcropNamecropLandTypeseasonunitYieldcostpriceunitProfit
011黄豆平旱地单季4004002.50-4.00900.00
122黑豆平旱地单季5004006.50-8.503350.00
233红豆平旱地单季4003507.50-9.002950.00
344绿豆平旱地单季3503506.00-8.002100.00
455爬豆平旱地单季4153506.00-7.502451.25
..............................
12010330生菜智慧大棚第二季450022005.40-7.2026150.00
12110431辣椒智慧大棚第二季180013007.20-10.2014360.00
12210532空心菜智慧大棚第二季1100055003.60-7.2053900.00
12310633黄心菜智慧大棚第二季540027504.80-6.0026410.00
12410734芹菜智慧大棚第二季600012003.80-5.8027600.00
\n", "

125 rows × 9 columns

\n", "
" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 5 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.029719Z", "start_time": "2024-09-07T07:39:54.013672Z" } }, "cell_type": "code", "source": [ "# 搞一下季节和年份的集合\n", "SeasonType = [\"单季\", \"第一季\", \"第二季\"]\n", "SeasonDict = {\"单季\": 1, \"第一季\": 1, \"第二季\": 2}\n", "SeasonNum = [1, 2]\n", "years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]" ], "id": "a7661d84217b578c", "outputs": [], "execution_count": 6 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.045394Z", "start_time": "2024-09-07T07:39:54.029719Z" } }, "cell_type": "code", "source": [ "# 枚举地块类型\n", "LandType = {\"A\": \"平旱地\", \"B\": \"梯田\", \"C\": \"山坡地\", \"D\": \"水浇地\", \"E\": \"普通大棚\", \"F\": \"智慧大棚\"}\n", "# LandType" ], "id": "4a4e06a1f2d4d8ab", "outputs": [], "execution_count": 7 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.061240Z", "start_time": "2024-09-07T07:39:54.045394Z" } }, "cell_type": "code", "source": [ "# 枚举地块\n", "LandName = df_crop_planting['landName'].unique()\n", "# LandName" ], "id": "cc938565a63a8129", "outputs": [], "execution_count": 8 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.076622Z", "start_time": "2024-09-07T07:39:54.062582Z" } }, "cell_type": "code", "source": [ "# 读入作物名称\n", "CropName = df_crop_details['cropName'].unique()\n", "# CropName" ], "id": "7a0e6cc209d93b56", "outputs": [], "execution_count": 9 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.092071Z", "start_time": "2024-09-07T07:39:54.081006Z" } }, "cell_type": "code", "source": [ "any([x[-1] == ' ' for x in CropName])\n", "# 居然有空格\n", "# 现在去掉了" ], "id": "bf6d61d66f06bdeb", "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 10 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.491091Z", "start_time": "2024-09-07T07:39:54.093999Z" } }, "cell_type": "code", "source": [ "# 亩产量\n", "unit_yield_lsc = {\n", " l: {\n", " s: {\n", " c: df_crop_details[\n", " (df_crop_details['cropName'] == c) &\n", " (df_crop_details['cropLandType'] == l) &\n", " (df_crop_details['season'] == s)\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'] == s)\n", " ]['unitYield'].values.size > 0 else 0\n", " for c in CropName\n", " } for s in SeasonType\n", " }\n", " for l in LandType.values()\n", "}\n", "\n", "# unit_yield" ], "id": "22f9730e3d9c1016", "outputs": [], "execution_count": 11 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:54.993663Z", "start_time": "2024-09-07T07:39:54.493875Z" } }, "cell_type": "code", "source": [ "# 亩利润\n", "unit_profit_lsc = {\n", " l: {\n", " s: {\n", " c: df_crop_details[\n", " (df_crop_details['cropName'] == c) &\n", " (df_crop_details['cropLandType'] == l) &\n", " (df_crop_details['season'] == s)\n", " ]['unitProfit'].values[0]\n", " if df_crop_details[\n", " (df_crop_details['cropName'] == c) &\n", " (df_crop_details['cropLandType'] == l) &\n", " (df_crop_details['season'] == s)\n", " ]['unitYield'].values.size > 0 else 0\n", " for c in CropName\n", " } for s in SeasonType\n", " }\n", " for l in LandType.values()\n", "}\n", "\n", "# unit_profit" ], "id": "99dbe4ca6c54db0b", "outputs": [], "execution_count": 12 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.009266Z", "start_time": "2024-09-07T07:39:54.993663Z" } }, "cell_type": "code", "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]]][line[5]][line[2]]\n", "\n", "# crop_demand" ], "id": "13f2ccc7aa215d4c", "outputs": [], "execution_count": 13 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.056963Z", "start_time": "2024-09-07T07:39:55.009266Z" } }, "cell_type": "code", "source": [ "# 准备开搞\n", "from pulp import LpMaximize, LpProblem, LpVariable, lpSum, value, LpInteger, PULP_CBC_CMD, LpContinuous, LpBinary\n" ], "id": "5d09872708d40da4", "outputs": [], "execution_count": 14 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.072925Z", "start_time": "2024-09-07T07:39:55.058097Z" } }, "cell_type": "code", "source": "model = LpProblem(\"Crop_Planting_Optimization_with_Specific_Rules\", LpMaximize)", "id": "b6eff87c7a762769", "outputs": [], "execution_count": 15 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.088872Z", "start_time": "2024-09-07T07:39:55.075153Z" } }, "cell_type": "code", "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)" ], "id": "7bfdb9425c3e9683", "outputs": [], "execution_count": 16 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.393238Z", "start_time": "2024-09-07T07:39:55.091269Z" } }, "cell_type": "code", "source": [ "# 地块l在y年的s季的种植c的量\n", "# X = LpVariable.dicts(\"crop_plant_area\", (CropName, LandName, years, SeasonType), lowBound=0, cat=LpContinuous)\n", "X = LpVariable.dicts(\"X\", [(c, l, y, s)\n", " for c in CropName\n", " for l in LandName\n", " for y in years\n", " for s in SeasonType],\n", " lowBound=0,\n", " cat=LpContinuous\n", " )\n", "# X" ], "id": "4cb129e20385a7ee", "outputs": [], "execution_count": 17 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:55.696316Z", "start_time": "2024-09-07T07:39:55.393238Z" } }, "cell_type": "code", "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 SeasonType],\n", " cat=LpBinary)\n", "\n", "# Y" ], "id": "9dab983ca7b3b607", "outputs": [], "execution_count": 18 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:57.605199Z", "start_time": "2024-09-07T07:39:55.697108Z" } }, "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 SeasonType:\n", " # 如果种植了作物,则种植面积大于0\n", " model += X[c, l, y, s] <= 10000000 * Y[c, l, y, s], f\"PlantingConstraint1_{c}_{l}_{y}_{s}\"\n", " # 如果未种植作物,则种植面积为0\n", " model += X[c, l, y, s] >= 0.000001 * Y[c, l, y, s], f\"PlantingConstraint2_{c}_{l}_{y}_{s}\"" ], "id": "603175d36624172f", "outputs": [], "execution_count": 19 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:40:30.545252Z", "start_time": "2024-09-07T07:40:30.317563Z" } }, "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 in CropName\n", " for l in LandName\n", " for y in years\n", " for s in SeasonType\n", ")\n" ], "id": "4505b0f2fe6bf93d", "outputs": [], "execution_count": 21 }, { "metadata": { "ExecuteTime": { "end_time": "2024-09-07T07:39:58.955478Z", "start_time": "2024-09-07T07:39:58.955478Z" } }, "cell_type": "code", "source": [ "# 每个季节每种作物的种植量必须小于需求量\n", "for c in CropName:\n", " " ], "id": "1f185c0856fbcf27", "outputs": [], "execution_count": null } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }