Julia - 如何分类 UnitRanges 并防止不良类型性能

Julia - How to cat UnitRanges and prevent bad type performance

对于一个变量 i 我有两个 UnitRanges 1:i-1i+1:n 我只想要一个 UnitRange 来连接它们。我目前的解决方法是 vcat(1:i-1, i+1:n) 但它会导致 Array{Int} 而不是 UnitRange{Int}.

这最终将在下一个最小示例中使用@code_warntype 给出红色性能类型:

using Gurobi, JuMP
function minimal_example()  
    milp = Model(() -> Gurobi.Optimizer())
    @variable(milp, x[i=1:n, j=vcat(1:i-1, i+1:n)], Bin)
end
@code_warntype minimal_example() 

键入性能结果:

Variables
  #self#::Core.Compiler.Const(minimal_example, false)
  #9::var"#9#13"
  #10::var"#10#14"{Model}
  #11::var"#11#15"
  #12::var"#12#16"
  milp::Model
  ##1226::JuMP.Containers.SparseAxisArray
  x::JuMP.Containers.SparseAxisArray

Body::JuMP.Containers.SparseAxisArray
1 ─       (#9 = %new(Main.:(var"#9#13")))
│   %2  = #9::Core.Compiler.Const(var"#9#13"(), false)
│         (milp = Main.Model(%2))
│         JuMP._valid_model(milp, :milp)
│         JuMP._error_if_cannot_register(milp, :x)
│   %6  = JuMP.Containers.container::Core.Compiler.Const(JuMP.Containers.container, false)
│   %7  = Main.:(var"#10#14")::Core.Compiler.Const(var"#10#14", false)
│   %8  = Core.typeof(milp)::Core.Compiler.Const(Model, false)
│   %9  = Core.apply_type(%7, %8)::Core.Compiler.Const(var"#10#14"{Model}, false)
│         (#10 = %new(%9, milp))
│   %11 = #10::var"#10#14"{Model}
│   %12 = JuMP.Containers.nested::Core.Compiler.Const(JuMP.Containers.nested, false)
│         (#11 = %new(Main.:(var"#11#15")))
│   %14 = #11::Core.Compiler.Const(var"#11#15"(), false)
│         (#12 = %new(Main.:(var"#12#16")))
│   %16 = #12::Core.Compiler.Const(var"#12#16"(), false)
│   %17 = (%12)(%14, %16)::Core.Compiler.Const(JuMP.Containers.NestedIterator{Tuple{var"#11#15",var"#12#16"},JuMP.Containers.var"#20#22"}((var"#11#15"(), var"#12#16"()), JuMP.Containers.var"#20#22"()), false)
│         (##1226 = (%6)(%11, %17))
│   %19 = JuMP.object_dictionary(milp)::Dict{Symbol,Any}
│   %20 = ##1226::JuMP.Containers.SparseAxisArray
│         Base.setindex!(%19, %20, :x)
│         (x = ##1226)
│   %23 = ##1226::JuMP.Containers.SparseAxisArray
└──       return %23

我在 UnitRanges 上搜索了 Julia 的文档页面,但找不到告诉我应该如何分类它们的位置。

我尝试了其他方法,例如

没有成功。

A​​ UnitRange 仅由其起点和终点定义。您提议的范围将跳过范围内的数字之一。所以,很明显,结果不能是 UnitRange,甚至不能是 StepRange.

我不知道有任何标准库范围执行此操作,因此您可能必须创建自己的自定义 SkipRange(或其他一些适当的名称。)

我想这应该可行(@code_warntype 中不再是红色)

function minimal_example(n)
    milp = Model()
    x = Array{VariableRef}(undef, n, n)
    for i in 1:n
        x[i, 1:i-1] = @variable(milp, [1:i-1], Bin)
        x[i, i+1:n] = @variable(milp, [i+1:n], Bin)
    end
    x
end

你真的应该测试不同的选项,看看什么最适合你的情况