66666

import numpy as np  
import pandas as pd  
from pulp import *  
  
# 1. 读取当前目录中的Excel文件  
try:  
    data1 = pd.read_excel('附件1.xlsx')  
    data2 = pd.read_excel('附件2.xlsx')  
except Exception as e:  
    print(f"Error reading Excel files: {e}")  
    exit()  
  
# 2. 清理列名,确保列名正确  
data1.columns = data1.columns.str.strip()  
data2.columns = data2.columns.str.strip()  
  
# 3. 获取地块和作物信息  
plots = data1['地块名称'].unique()  
crops = data2['作物名称'].unique()  
  
# 4. 提取相关的参数  
yield_per_mu = data2.set_index('作物名称')['种植面积/亩'].to_dict()  
planting_cost = {crop: np.random.uniform(100, 200) for crop in crops}  # 假设种植成本  
expected_sales = {crop: np.random.uniform(50, 100) for crop in crops}  # 假设预期销售量  
price_per_unit = {crop: np.random.uniform(1, 5) for crop in crops}  # 假设销售价格  
  
# 获取地块的面积  
land_area = data1.set_index('地块名称')['地块面积/亩'].to_dict()  
  
# 5. 定义蒙特卡洛模拟的不确定性  
def simulate_uncertainty(base_value, percentage_range):  
    return base_value * np.random.uniform(1 - percentage_range, 1 + percentage_range)  
  
# 6. 进行线性规划的求解  
def optimize_planting(yield_per_mu, planting_cost, expected_sales, price_per_unit):  
    model = LpProblem("Crop_Planning", LpMaximize)  
      
    # 决策变量,定义每年每块地每种作物的种植面积  
    plant_area = LpVariable.dicts("Plant_Area",   
                                  ((year, plot, crop) for year in range(2024, 2031) for plot in plots for crop in crops),  
                                  lowBound=0, cat='Continuous')  
      
    # 引入一个辅助变量,表示实际销售量,等于产量和预期销售量的最小值  
    sales_amount = LpVariable.dicts("Sales_Amount",   
                                    ((year, plot, crop) for year in range(2024, 2031) for plot in plots for crop in crops),  
                                    lowBound=0, cat='Continuous')  
      
    # 目标函数:最大化总收益  
    model += lpSum(  
        [(sales_amount[(year, plot, crop)] * simulate_uncertainty(price_per_unit.get(crop, 0), 0.05) -   
          plant_area[(year, plot, crop)] * simulate_uncertainty(planting_cost.get(crop, 0), 0.05))  
         for year in range(2024, 2031) for plot in plots for crop in crops]  
    )  
      
    # 约束条件:  
    # 1. 每块地的种植面积不能超过该地块的实际面积  
    for year in range(2024, 2031):  
        for plot in plots:  
            model += lpSum([plant_area[(year, plot, crop)] for crop in crops]) <= land_area[plot]  
      
    # 2. 不重茬约束:同一地块连续两年不能种同一种作物  
    for year in range(2025, 2031):  
        for plot in plots:  
            for crop in crops:  
                model += plant_area[(year, plot, crop)] + plant_area[(year - 1, plot, crop)] <= land_area[plot] / 2  # 修正为小于等于地块面积的一半(假设)  
      
    # 3. 三年内必须种植一次豆类作物  
    bean_crops = ['大豆', '绿豆']  
    for plot in plots:  
        for t in range(2024, 2029, 3):  
            model += lpSum([plant_area[(year, plot, crop)] for year in range(t, t + 3) for crop in bean_crops if crop in crops]) >= 1  
      
    # 4. 实际销售量应该等于产量和预期销售量的最小值  
    for year in range(2024, 2031):  
        for plot in plots:  
            for crop in crops:  
                # 实际销售量不能超过产量  
                model += sales_amount[(year, plot, crop)] <= plant_area[(year, plot, crop)] * simulate_uncertainty(yield_per_mu.get(crop, 0), 0.1)  
                # 实际销售量不能超过预期销售量  
                model += sales_amount[(year, plot, crop)] <= expected_sales.get(crop, 0)  
      
    # 求解模型  
    model.solve()  
      
    # 检查求解状态,确保模型成功求解  
    if LpStatus[model.status] != 'Optimal':  
        print(f'Error: Model did not find an optimal solution. Status: {LpStatus[model.status]}')  
        return None  
      
    # 输出结果(可选)  
    # for v in model.variables():  
    #     if v.varValue is not None and v.varValue > 0:  
    #         print(f'{v.name} = {v.varValue}')  
      
    # 返回总收益  
    return value(model.objective)  
  
# 7. 运行模拟  
results = []  
for simulation in range(100):  
    print(f'Running simulation {simulation + 1}')  
    total_profit = optimize_planting(yield_per_mu, planting_cost, expected_sales, price_per_unit)  
    if total_profit is not None:  
        results.append(total_profit)  
  
# 输出平均收益和方差(如果有成功的模拟)  
if results:  
    print(f'Average Profit: {np.mean(results)}')  
    print(f'Profit Standard Deviation: {np.std(results)}')  
else:  
    print('No successful simulations found.')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值