You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pulp建模非方阵时遭遇索引越界问题求助

Fixing the IndexError in Your Pulp Model with Non-Square Matrices

Hey there! Let's break down why you're hitting that IndexError: list index out of range and get your model working with non-square matrices like your target 365×24 setup.

The Root Cause

The problem lies in how you're constructing your Excel data matrices (TEST, YAPR, MAPR) versus how you're accessing them later.

Looking at your matrix-building code:

TEST = [[sheet11.cell_value(i,j) for i in range(YPER)] for j in range(HE)]

This creates a column-first matrix: the outer loop iterates over columns (j, 0-5 for HE=6), and the inner loop over rows (i, 0-4 for YPER=5). The result is a 6-row × 5-column structure where TEST[j][i] maps to Excel's cell (i,j).

But later in your constraint, you're trying to access it as TEST[i][j]—treating it like a row-first matrix. Since each sublist in TEST only has 5 elements (one per row), when j hits 5 (the 6th column), you're trying to access an index that doesn't exist in the sublist, hence the error.

The Fix

You have two straightforward options, but the first is more intuitive and aligns with standard row-first thinking:

Option 1: Build Row-First Matrices

Adjust your list comprehensions to iterate over rows first, then columns. This creates a YPER×HE matrix (5×6 for your test case) where TEST[i][j] directly maps to Excel's cell (i,j):

# Build matrices row-first to match your variable indexing
TEST = [[sheet11.cell_value(i,j) for j in range(HE)] for i in range(YPER)]
YAPR = [[sheet12.cell_value(i,j) for j in range(HE)] for i in range(YPER)]
MAPR = [[sheet13.cell_value(i,j) for j in range(HE)] for i in range(YPER)]

Option 2: Adjust Indexing When Accessing Matrices

If you prefer to keep the column-first matrix build, swap the indices when accessing the values in your constraint:

model += pulp.lpSum([YAHL[i][j] + MAHL[i][j]]) == TEST[j][i]

But Option 1 is cleaner and less prone to future mix-ups, especially as you scale to larger matrices like 365×24.

Bonus: Simplify Your Constraint

You can also remove the unnecessary brackets around TEST[i][j]—you're comparing a scalar sum to a single value, no need for a list:

for i,j in yearlyhours:
    model += pulp.lpSum([YAHL[i][j] + MAHL[i][j]]) == TEST[i][j]

Full Modified Code

Here's the complete fixed code for your test case:

from pulp import *
import pandas as pd
import numpy as np
import xlrd

model = pulp.LpProblem("Basic Model", pulp.LpMinimize)
YPER = 5
HE = 6
yearlyhours = [(i,j) for i in range(YPER) for j in range(HE)]

book = xlrd.open_workbook('Stack.xlsx')
sheet11 = book.sheet_by_name('Sheet11')
sheet12 = book.sheet_by_name('Sheet12')
sheet13 = book.sheet_by_name('Sheet13')

# Fixed: build row-first matrices
TEST = [[sheet11.cell_value(i,j) for j in range(HE)] for i in range(YPER)]
YAPR = [[sheet12.cell_value(i,j) for j in range(HE)] for i in range(YPER)]
MAPR = [[sheet13.cell_value(i,j) for j in range(HE)] for i in range(YPER)]

YAHL = pulp.LpVariable.dicts("YAHL", (range(YPER), range(HE)), lowBound=0, cat='Continuous')
MAHL = pulp.LpVariable.dicts("MAHL", (range(YPER), range(HE)), lowBound=0, cat='Continuous')

##OBJECTIVE##
model += pulp.lpSum([YAPR[i][j] * YAHL[i][j] + MAPR[i][j] * MAHL[i][j] for i in range(YPER) for j in range(HE)]), 'Sum_of_Value'

# Fixed constraint indexing and simplified syntax
for i,j in yearlyhours:
    model += pulp.lpSum([YAHL[i][j] + MAHL[i][j]]) == TEST[i][j]

LpSolverDefault.msg = 1
model.writeLP('Opt.lp')
model.solve()

print("Status:", LpStatus[model.status])
obj = value(model.objective)
print("Total Cost: ${:.2f}".format(obj))
print('\n')

Scaling to 365×24

This fix will work seamlessly for your 365×24 matrix—just update YPER = 365 and HE = 24, and the row-first matrix structure will align perfectly with your variables and constraints, no more index errors.

内容的提问来源于stack exchange,提问作者bathtub2007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:35:34