# Problem construction advice in JuMP for speed

**URL:** <https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump\
**Created:** [October 21, 2019, 9:09pm UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148 "2019-10-21T21:09:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bhalonen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bhalonen/32/9848_2.png) [@bhalonen](https://discourse.julialang.org/u/bhalonen)\
**Post date:** [October 21, 2019, 9:09pm UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148/1 "2019-10-21T21:09:35Z")

</div>

I know that parallelization of problem construction has been advised against, so I am curious on what advice there is. Problem construction takes a significant amount of time on my problem, and is time significant operation.

What can I change about my problem set up to make this construct faster. Alternatively, is it possible to parallelize?  
The loop that takes a lot of time is this runnable subset.

```julia
using JuMP
struct TransporterProblem
	durationLookUp
	numberOfStations 
	moveWhen
	followedByTime
	order
	moveCommandCount
end 
moveCommandCount = 28
numberReachableStations = 6
model = Model()
@variable(model, order[1:moveCommandCount, 1:moveCommandCount,1:numberReachableStations, 1:numberReachableStations], Bin)	
@variable(model, moveWhen[1:moveCommandCount] >= 0.0 )
durationLookUp = rand(numberReachableStations, numberReachableStations)
followedByTime = rand(moveCommandCount)
transporterProblem = TransporterProblem(durationLookUp, numberReachableStations, moveWhen, followedByTime, order, moveCommandCount )
function moveDuration(moveIdx::Integer, transporterProblem::TransporterProblem)
	sum(
		sum(sum(transporterProblem.order[moveIdx,:, idxFrom,idxTo])* transporterProblem.durationLookUp[idxFrom, idxTo] 
			for idxFrom in 1:transporterProblem.numberOfStations
		) 
	for idxTo in 1:transporterProblem.numberOfStations
	)
end

function beginningOfOrderedOp(moveOrderIdx::Integer, transporterProblem::TransporterProblem)
	transporterProblem.moveWhen[moveOrderIdx]
end

foreach(1:moveCommandCount-1) do orderIdx
    println(orderIdx)
    spaceMove = 1.0
    @constraint(model, 
        beginningOfOrderedOp(orderIdx,transporterProblem)+
        sum( sum(order[moveIdx, orderIdx,:,:])*
        (moveDuration(moveIdx, transporterProblem) + transporterProblem.followedByTime[moveIdx])
        for moveIdx in 1:moveCommandCount) + spaceMove
            <= beginningOfOrderedOp(orderIdx+1,transporterProblem)
        )
end

```

---

<div class="post-metadata">

**Author:** ![bhalonen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bhalonen/32/9848_2.png) [@bhalonen](https://discourse.julialang.org/u/bhalonen)\
**Post date:** [October 22, 2019, 1:37am UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148/2 "2019-10-22T01:37:51Z")

</div>

I found a way, really banging my head now.  
If I look up on the right index my problem construction time really collapses.

```julia
using JuMP
struct TransporterProblem
	durationLookUp
	numberOfStations 
	moveWhen
	followedByTime
	order
	moveCommandCount
end 
moveCommandCount = 28
numberReachableStations = 6
model = Model()
@variable(model, order[1:moveCommandCount, 1:moveCommandCount,1:numberReachableStations, 1:numberReachableStations], Bin)	
@variable(model, moveWhen[1:moveCommandCount] >= 0.0 )
durationLookUp = rand(numberReachableStations, numberReachableStations)
followedByTime = rand(moveCommandCount)
transporterProblem = TransporterProblem(durationLookUp, numberReachableStations, moveWhen, followedByTime, order, moveCommandCount )
function moveDurationOrderIdx(orderIdx::Integer, transporterProblem::TransporterProblem)
	sum(
		sum(sum(transporterProblem.order[:,orderIdx, idxFrom,idxTo])* transporterProblem.durationLookUp[idxFrom, idxTo] 
			for idxFrom in 1:transporterProblem.numberOfStations
		) 
	for idxTo in 1:transporterProblem.numberOfStations
	)
end

function beginningOfOrderedOp(moveOrderIdx::Integer, transporterProblem::TransporterProblem)
	transporterProblem.moveWhen[moveOrderIdx]
end

foreach(1:moveCommandCount-1) do orderIdx
    println(orderIdx)
        spaceMove = 1.0
        @constraint(model, 
        beginningOfOrderedOp(orderIdx,transporterProblem)+
        moveDurationOrderIdx(orderIdx, transporterProblem)+ 
        sum( sum(order[moveIdx, orderIdx,:,:])*
        (transporterProblem.followedByTime[moveIdx])
        for moveIdx in 1:moveCommandCount) + spaceMove
            <= beginningOfOrderedOp(orderIdx+1,transporterProblem)
        )
end

```

---

<div class="post-metadata">

**Author:** ![leethargo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leethargo/32/6004_2.png) [@leethargo](https://discourse.julialang.org/u/leethargo)\
**Post date:** [October 22, 2019, 5:50am UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148/3 "2019-10-22T05:50:42Z")

</div>

So this might be an issue related to column vs row based storage of arrays?

It looks like the model size (variables, constraints) are moderate. How long does the construction take?

---

<div class="post-metadata">

**Author:** ![bhalonen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bhalonen/32/9848_2.png) [@bhalonen](https://discourse.julialang.org/u/bhalonen)\
**Post date:** [October 22, 2019, 2:20pm UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148/4 "2019-10-22T14:20:15Z")

</div>

The first way took something like 20 seconds, my solution took like a half second.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [October 22, 2019, 3:50pm UTC](https://discourse.julialang.org/t/problem-construction-advice-in-jump-for-speed/30148/5 "2019-10-22T15:50:07Z")

</div>

It looks like your first model is a quadratic program, whereas the second one is a linear program? That explains the difference in build speed.
