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

Julia JuMP变量数组索引报错求解:排列优化场景

Ah, I’ve run into this exact headache when working with permutation problems in JuMP! The core issue here is that JuMP’s VariableRef objects (the variables you declare with @variable) aren’t concrete integer values—they’re symbolic placeholders for the values the solver will compute later. You can’t use them to index into an array like a[b[1]] because the solver has no idea what b[1] will be while you’re building the model.

Here’s how to fix this by modeling the permutation with binary assignment variables, which is the standard approach for these problems:

Step 1: Replace the permutation variable with binary assignment variables

Instead of trying to declare b directly as a permutation, define a binary matrix x where x[i,j] = 1 means the i-th position in your permutation uses the j-th element of a (i.e., b[i] = j). This lets us translate permutation logic into linear constraints that JuMP understands.

Step 2: Add permutation constraints

We need two sets of constraints to enforce that x represents a valid permutation:

  • Each position in the permutation selects exactly one element: for every i, sum(x[i,j] for j in 1:n) = 1
  • Each element is used exactly once across all positions: for every j, sum(x[i,j] for i in 1:n) = 1

Step 3: Rewrite your objective/constraints using x

Any expression that would have used a[b[i]] can be rewritten as sum(a[j] * x[i,j] for j in 1:n). When x[i,j] = 1, this sum picks out exactly a[j]—which is exactly what a[b[i]] would be if b[i] = j.

Full Example Code

Let’s say we want to maximize the sum of the permuted elements (adjust the objective to fit your specific problem):

using JuMP, GLPK # Swap GLPK for your preferred solver (e.g., Gurobi, CPLEX)

function optimize_permutation(a::Vector{<:Real})
    n = length(a)
    model = Model(GLPK.Optimizer)
    
    # Binary variable: x[i,j] = 1 if permutation position i uses element j of a
    @variable(model, x[1:n, 1:n], Bin)
    
    # Enforce permutation rules
    # Each position has exactly one element
    @constraint(model, [i in 1:n], sum(x[i,j] for j in 1:n) == 1)
    # Each element is used exactly once
    @constraint(model, [j in 1:n], sum(x[i,j] for i in 1:n) == 1)
    
    # Rewrite objective: replace a[b[i]] with sum(a[j] * x[i,j])
    # Example: maximize the total sum of the permuted array
    @objective(model, Max, sum(a[j] * x[i,j] for i in 1:n for j in 1:n))
    
    # Solve the model
    optimize!(model)
    
    # Recover the permutation b from the solved x variables
    b = zeros(Int, n)
    for i in 1:n
        for j in 1:n
            if value(x[i,j]) ≈ 1.0 # Account for floating point precision
                b[i] = j
                break
            end
        end
    end
    
    return b, objective_value(model)
end

# Test with a sample array
a = [3, 1, 4, 2]
optimal_b, obj_val = optimize_permutation(a)
println("Optimal permutation: ", optimal_b)
println("Objective value: ", obj_val)

Notes for More Complex Goals

If your problem involves more complex logic (like minimizing the difference between adjacent permuted elements), you can extend this approach:

  • For an expression like abs(a[b[i+1]] - a[b[i]]), rewrite it as sum(abs(a[k] - a[j]) * x[i,j] * x[i+1,k] for j in 1:n for k in 1:n)
  • If you need to linearize absolute values or product terms, you can add auxiliary variables and constraints (standard MIP linearization techniques apply)

Alternative: All-Different Constraints

Some solvers support direct "all-different" constraints for integer variables, which let you declare b as an integer array with @constraint(model, all_different(b)). However, binary assignment variables are more universally supported across solvers and often more efficient for larger n.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:37:35