在 Python 中执行 MILP 时使用逻辑将决策变量与自身进行比较

问题描述 投票:0回答:1

我正在用 Python 做一个优化问题,我试图在我的 MILP 问题中添加另一个决策变量。我需要做的是添加一个效果链接成本,它应该来自问题中的其他决策变量之一 (

E_import
)。效果链接的计算方式是取一个月内
E_import
的3个最大和,然后计算3个和的平均值。这 3 个总和应该都在不同的日期(所以你可以称它们为 day-maxes)。我试图从中获取的决策变量在所有月份的每一天的每一小时都有一行。我想返回 12 个数字的总和(每个月一个)。 然而,我正在努力的是试图让 Python 对最大数量的
E_import
.

进行排名

这是我使用的代码:

import pandas as pd
import pulp

df = pd.read_excel("1 (KWh & dayahead).xlsx", sheet_name="KWh prod")

# getting the values from the excel sheet
E_Consum = df.iloc[:, 0].values.tolist()
timeperiods = df.iloc[:, 1].values.tolist()
C_elspot = df.iloc[:, 2].values.tolist()
FCR_price = df.iloc[:, 3].values.tolist()
PV_prod = df.iloc[:, 4].values.tolist()
month_nr = df.iloc[:, 5].values.tolist()
days = df.iloc[:, 6].values.tolist()

# Creating optimization problem
problem = pulp.LpProblem("Minimization problem", pulp.LpMinimize)

# Defining the length of the optimization
num_periods = len(timeperiods)

# adding decision variables
E_import = pulp.LpVariable.dicts("E_import", range(num_periods), lowBound=0, cat=pulp.LpContinuous)
E_export = pulp.LpVariable.dicts("E_export", range(num_periods), lowBound=0, cat=pulp.LpContinuous)
SOC = pulp.LpVariable.dicts("SOC", range(num_periods + 1), lowBound=0, upBound=SOC_max)
x_import = pulp.LpVariable.dicts("phi_import", range(num_periods), cat=pulp.LpBinary)
x_export = pulp.LpVariable.dicts("phi_export", range(num_periods), cat=pulp.LpBinary)
monthly_max_E_import = pulp.LpVariable.dicts("monthly_max_E_import", range(12), lowBound=0)

# adding the E_import and E_export to df
df["E_import"] = [E_import[t] for t in range(num_periods)]
df["E_export"] = [E_export[t] for t in range(num_periods)]

# Loop over the months
for month in df['Month'].unique():
    # Subset the E_import column for this month
    e_import_month = df.loc[df['Month'] == month, 'E_import']
    # Create a new column that combines the Day and E_import values
    day_e_import = df.loc[df['Month'] == month, ['Day', 'E_import']]
    day_e_import['Day_E_import'] = day_e_import['Day'].astype(str) + '_' +     day_e_import['E_import'].astype(str)
    # Sort the E_import column and the Day_E_import column based on the sorted indices
***    sorted_indices = e_import_month.argsort()[::-1]***
    e_import_month_sorted = e_import_month.iloc[sorted_indices]
    day_e_import_sorted = day_e_import['Day_E_import'].iloc[sorted_indices]
    # Loop over the sorted Day_E_import column to find the top 3 values with no more than one value per    day
    top_values = []
    for day_e_import_value in day_e_import_sorted:
        day, e_import = day_e_import_value.split('_')
        e_import = float(e_import)
        if day not in [t[0] for t in top_values]:
            top_values.append((day, e_import))
            if len(top_values) == 3:
                break
    # Calculate the average of the top 3 values
    top_values_avg = sum([t[1] for t in top_values]) / len(top_values)
    # Assign the average value to the monthly_max_E_import series
    monthly_max_E_import[month] = top_values_avg

我突出显示了出现错误的行,错误显示为:

TypeError: '<' not supported between instances of 'LpVariable' and 'LpVariable'
。一段时间以来,我一直试图解决这个问题,并咨询了不同的网站和编码 AI 来帮助我,但我很难找到一种方法来解决这个问题。在这一点上,我不确定这是否是一种可行的方法。非常感谢任何帮助。

python integer linear-programming pulp mixed
1个回答
0
投票

您不能对决策变量使用排序函数,因为 LP/MIP 求解器不知道这一点。它们只能使用线性约束,即

  Ax = b

(或<=, >=)。

可以将排序表示为一组线性约束。请参阅 https://yetanothermathprogrammingconsultant.blogspot.com/2016/12/sorting-inside-mip-model.html 了解一些相关说明。最好的三个可能更容易,但同样,您需要将其写为线性约束。最小化向量中最大的 k 的总和在某种程度上很容易(LP 可表示)。

这不是很微不足道。恐怕,我不明白你到底想在这里建模什么,所以我不能提供更精确的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.