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

如何在CPLEX Docplex MILP模型中编写适配任意n与A场景的约束#18代码?

Fixing Index Out-of-Bounds Error in CPLEX Docplex Constraint #18 for Generalized n Values

Let's break down and fix your issue step by step:

Root Cause of the Error

The index 2 is out of bounds error happens because you're using range_A = range(len(A)) (the full length of your entire set A) to iterate over z_temp and c_temp, which only correspond to a single element in A. For example, when A contains [1,3], z_temp has a length of 2—but range_A for n=3 is range(4), so when i reaches 2 or 3, you're trying to access an index that doesn't exist in z_temp.

Solution Steps

1. Fix the Storage of Set A

Avoid using np.array for storing mixed scalars and lists (it creates an object-type array that's harder to work with). Use a standard Python list instead:

# n=3
A = [1,2,3,[1,3]]
# n=4
A = [1,2,3,4,[1,3],[1,4],[2,4]]  # Fixed [2,5] to [2,4] since n=4
# n=5
A = [1,2,3,4,5,[1,3],[1,4],[1,5],[2,4],[2,5],[3,5],[1,3,5]]

2. Rewrite Constraint #18 with Robust Logic

For each element in A, first normalize it to a list (whether it's a single step or a multi-step group), then iterate only over the length of that specific element. This eliminates index out-of-bounds issues and makes the code work for any n.

Here's the corrected constraint #18 code:

# constraint 18 - generalized version
for item in A:
    # Convert single integers to a list for uniform processing
    idx_list = [item] if isinstance(item, int) else item
    
    # Validate step numbers to avoid future index errors
    for idx in idx_list:
        if idx > n:
            raise ValueError(f"Step {idx} in A exceeds total steps n={n}")
    
    # Get corresponding z variables and c values (convert 1-based to 0-based index)
    z_temp = [z[idx-1] for idx in idx_list]
    c_temp = [c[idx-1] for idx in idx_list]
    
    # Calculate sums specific to this element in A
    sum_z = sum(z_temp)
    sum_c_term = sum(2*w + v + ci for ci in c_temp)
    
    # Note: Double-check the (n + 1 - 2 * len(A)) term in your formula
    # For n=3, this gives 4 - 8 = -4, which likely doesn't make sense for a time value
    # You may want to replace this with (n + 1 - len(idx_list)) to use the size of the current group
    time_term = (n + 1 - 2 * len(A)) * (2*v + 2*w) + sum_c_term
    
    mdl.add_constraint(1 + sum_z >= y * time_term)

3. Full Corrected Code

import cplex
from docplex.mp.model import Model
import numpy as np

mdl = Model(name='Marking Optimization')
inf = cplex.infinity
n = 3 # number of steps
A = [1,2,3,[1,3]] # Use Python list instead of np.array
p = np.array([40,100,60]) #processing time for PM1 (second)
c = np.array([20,100,50])
v = 3 #robot moving time (second)
w = 5 #loading or unloading time (second)
m = np.array([1,2,1])

# y = 1/obj_lambda
y = mdl.continuous_var(lb = 0, ub=inf, name='y')
z = np.empty((n,), dtype= object)
for i in range(n):
    z[i] = mdl.integer_var(lb = 0, ub=inf, name='z' + str(i + 1))

# constraint 15
mdl.add_constraint(1 >= y*(n+1)*(2*v + 2*w))

# constraint 16
for i in range(n):
    mdl.add_constraint(1 >= y*(1/m[i])*(p[i] + c[i] + 2*w))

# constraint 17
for i in range(n):
    mdl.add_constraint(m[i] - z[i] >= y*(p[i] + 3*v + 4*w))

#constraint 18 - corrected
for item in A:
    idx_list = [item] if isinstance(item, int) else item
    for idx in idx_list:
        if idx > n:
            raise ValueError(f"Step {idx} in A exceeds total steps n={n}")
    z_temp = [z[idx-1] for idx in idx_list]
    c_temp = [c[idx-1] for idx in idx_list]
    sum_z = sum(z_temp)
    sum_c_term = sum(2*w + v + ci for ci in c_temp)
    time_term = (n + 1 - 2 * len(A)) * (2*v + 2*w) + sum_c_term
    mdl.add_constraint(1 + sum_z >= y * time_term)

#constraint 19A
for i in range(n):
    mdl.add_constraint(z[i] >= 0)

#constraint 19B
for i in range(n):
    mdl.add_constraint(z[i] <= m[i] -1)

mdl.maximize(y)
mdl.print_information()
solver = mdl.solve() #(log_output=True)
if solver is not None:
    mdl.print_solution()
else:
    print("Solver error occurred")
obj_lambda = 1/y.solution_value if solver else None

Key Notes

  • The code now handles any valid n and corresponding set A, as long as all step numbers in A are ≤ n.
  • I added a validation check to catch invalid step numbers in A before they cause index errors.
  • Important: The term (n + 1 - 2 * len(A)) in your original formula produces negative values for your test cases (e.g., n=3 gives -4). This is likely a mistake—double-check your mathematical model to ensure this term correctly represents the intended logic (e.g., using the size of the current group len(idx_list) instead of len(A)).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:52:47