For循环,其中索引不是从1或0开始,而是增加30而不是1

时间:2019-04-17 18:38:00

标签: julia

我有以下内容:

include("as_mod.jl")

solvetimes = 50:200
timevector = Array{Float64}(undef,length(solvetimes))

for i in solvetimes
    global T
    T = i
    include("as_dat_large.jl")
    m, x, z = build_model(true,true)
    setsolver(m, GurobiSolver(MIPGap = 2e-2, TimeLimit = 3600))
    solve(m)

    timevector[i-49] = getsolvetime(m)
end

plot(solvetimes,log.(timevector),
title  = "solvetimes vs T", xlabel = "T", ylabel = "log(t)")

只要我的求解时间矢量仅增加1,此方法就很好用。但是,我对30的增量很感兴趣,因此显然不起作用,因为我的时间矢量越界了。有什么办法解决这个问题?我阅读并尝试使用push!函数,但无济于事。

很抱歉,我的问题不好,但是我看不出如何改善它。这个问题本质上是关于for循环的,其中索引不是从1开始,而是仅以1递增直到上限,而是一个非1的增量,并且从0或1开始的递减,如果这样的话。

1 个答案:

答案 0 :(得分:4)

:50:200中的50:30:200语法在Julia中创建了一个范围对象。这些范围对象不仅可以迭代,而且可以实现方法getindex,这意味着您可以像使用数组一样简单地使用a[index]语法访问范围中的步骤。

julia> solvetimes = 50:30:200 # 50, 80, 110, 140, ...
50:30:200

julia> solvetimes[3]
110

您可以通过多种方式解决问题。

首先,您可以引入一个itercount变量来计算迭代次数,并知道将求解时间放在timevector的哪个索引上。

solvetimes = 50:30:200 # increment by 30
timevector = Vector{Float64}(undef,length(solvetimes))

itercount = 1
for i in solvetimes
    ...

    timevector[itercount] = getsolvetime(m)
    global itercount
    itercount += 1
end

其他方法是创建一个空的timevectorpush!

solvetimes = 50:30:200 # increment by 30
timevector = Float64[] # an empty Float64 vector

for i in solvetimes
    ...

    push!(timevector, getsolvetime(m)) # push the value `getsolvetime(m)` into `timevector`
end

push!操作 可能需要julia分配内存并复制数据以补偿不断增加的数组大小,因此虽然不是真正重要的问题,但效率可能不是很高。

另一种方法是从length的1迭代到solvetimes。您的循环控制变量仍按一个增量递增,但是现在它代表solvetimes中的索引,而不是时间点。

solvetimes = 50:30:200 # increment by 30
len = length(solvetimes)

timevector = Vector{Float64}(undef, len)

for i in 1:len
    global T
    T = solvetimes[i]
    ...

    timevector[i] = getsolvetime(m)
end

经过这些修改,k中第timevector个值,timevector[k]代表solvetime[k]的求解时间。

您可能还会找到其他解决问题的方法,例如使用Dict等。