Skip to content

Commit

Permalink
First working version of the new datastructures
Browse files Browse the repository at this point in the history
  • Loading branch information
HBreddam committed Feb 4, 2020
1 parent 67d222f commit 77070b5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 37 deletions.
7 changes: 3 additions & 4 deletions src/MIP/SupportFunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ function buildJd(timeslots,subcal)
timeslots |> @filter(_.dayID in keys(subcal))|>@groupby(_.resourceID) |>@map((d = key(_),j = unique(map(x->x.dayID,_)))) |> NDSparse
end
function buildI(timeslots)
timeslots |> @groupby((_.resourceID,_.dayID)) |> @map({d=key(_)[1],j=key(_)[2],i=map(x->x.timeslotID,_)})|> NDSparse
timeslots|> @filter(!_.booked) |> @groupby((_.resourceID,_.dayID)) |> @map({d=key(_)[1],j=key(_)[2],i=map(x->x.timeslotID,_)})|> NDSparse
end


function getTlowerbound(timeslots,resourceID,dayID)
println("$resourceID - $dayID")
bookedslots = timeslots |> @filter(_.resourceID == resourceID && _.dayID == dayID && _.status )|> @orderby(_.endTime) |> @take(1) |>@map(_.endTime) |> collect
bookedslots = timeslots |> @filter(_.resourceID == resourceID && _.dayID == dayID && _.booked )|> @orderby(_.endTime) |> @take(1) |>@map(_.endTime) |> collect
if length(bookedslots) == 1
value = Dates.value(first(bookedslots))/60000000000
else
Expand Down Expand Up @@ -56,7 +55,7 @@ end

"Produces a IndexedTable of patient groups based on the function patientgroup()"
function buildPg(patients,visits,Vp)
table(patients |> @groupby(patientgroup(visits,Vp,_.intID))|> @map((group1=key(_)[1],group2=key(_)[2],group3=key(_)[3],patients= map(x->x.intID,_))) |> collect)
table(patients |> @groupby(patientgroup(visits,Vp,_.intID))|> @map((types=key(_)[1],startmonth=key(_)[2],endmonths=key(_)[3],patients= map(x->x.intID,_))) |> collect)
end


Expand Down
6 changes: 3 additions & 3 deletions src/MIP/masterproblem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function setupmaster(subproblems,patients,resources,timeslots,subMastercalendar,

K = length(patients)
Pg = sets.Pg
Gp = keys(Pg) ##TODO virker nok ikke men nu smutter jeg hjem
Gp = [i for i in 1:length(Pg)]
D = JuliaDB.select(resources,:intID)
J = keys(subMastercalendar)
Jd = sets.Jd
Expand All @@ -27,10 +27,10 @@ function setupmaster(subproblems,patients,resources,timeslots,subMastercalendar,
@constraint(master,consref_offtime[d in D, j in Jd[d]], sum(lambda[m]*1000 for m in 1:K) <= closingtime[d,j]) #TODO Only for consultations

@constraint(master,convexitycons[g in Gp],
sum(lambda[m] for m in 1:K if m in Pg[g].patients) == length(P_g[g].patients) )
sum(lambda[m] for m in 1:K if m in Pg[g].patients) == length(Pg[g].patients) )


@constraint(master,consref_onepatient[ d in D, j in Jd[d], i in I[d,j]],
@constraint(master,consref_onepatient[ d in D, j in Jd[d].j, i in I[d,j].i],
0 <=1 )


Expand Down
49 changes: 29 additions & 20 deletions src/MIP/model_column.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
EPSVALUE = 0.1


function columngeneration(patients, visits, resources, timeslots, mastercalendar, timeDelta, setuponly = false)
function columngeneration(patients, visits, resources, timeslots, mastercalendar, timeDelta; setuponly = false, multithreading = false)
println("Building sets")
timeslotsNDSparse = ndsparse(timeslots)
subproblems = Subproblems()
sets = Sets()
Expand All @@ -13,9 +14,9 @@ function columngeneration(patients, visits, resources, timeslots, mastercalendar
sets.Jd = buildJd(timeslots,mastercalendar)
sets.I = buildI(timeslots)
sets.Pg = buildPg(patients,visits,sets.Vp)

println("Setting up sub-problems")
setup_sub!(subproblems,patients,visits,resources,timeslotsNDSparse,mastercalendar,timeDelta,sets,1)

println("Setting up master")
mp = setupmaster(subproblems,patients,resources,timeslots,mastercalendar,sets)
#generateInitialColumns(mp,subproblems)
if setuponly
Expand All @@ -26,6 +27,7 @@ function columngeneration(patients, visits, resources, timeslots, mastercalendar
while !done
iteration +=1
println(iteration)
println("Solving master")
optimize!(mp.model)
println("Master objective value = $(JuMP.objective_value(mp.model))")
println.(getPositiveVariables(mp.lambda))
Expand All @@ -39,24 +41,31 @@ function columngeneration(patients, visits, resources, timeslots, mastercalendar
θ = dual.(mp.consref_onepatient)
κ = dual.(mp.convexitycons)

subthreads = []
println("Solving subproblems")
if multithreading
subthreads = []
for sub in values(subproblems.pricingproblems)
push!(subthreads,Threads.@spawn solveSub!(sub,sets,ϕ,θ,κ))
end
#end
for thread in subthreads
wait(thread) #TODO remove multithreading, fix at turn MT back on
end
else
for sub in values(subproblems.pricingproblems)
solveSub!(sub,sets,ϕ,θ,κ)
# solveSub!(sub,ϕ,θ,κ)
# done2 = addcolumntomaster!(mp,sub,iteration,EPSVALUE) #TODO add patient info
# done &= done2
# count = 0
# while !done2 && count < 0#length(sub.patients)
# count += 1
# solveSub!(sub,getIndexofPositiveVariables(sub.xvars)) #TODO time this
# done2 = addcolumntomaster!(mp,sub,iteration,EPSVALUE)
# end
end
#end

for sub in values(subproblems.pricingproblems)

push!(subthreads,Threads.@spawn solveSub!(sub,ϕ,θ,κ))
# solveSub!(sub,ϕ,θ,κ)
# done2 = addcolumntomaster!(mp,sub,iteration,EPSVALUE) #TODO add patient info
# done &= done2
# count = 0
# while !done2 && count < 0#length(sub.patients)
# count += 1
# solveSub!(sub,getIndexofPositiveVariables(sub.xvars)) #TODO time this
# done2 = addcolumntomaster!(mp,sub,iteration,EPSVALUE)
# end
end
#end
for thread in subthreads
wait(thread)
end
done = addcolumntomaster!(mp,subproblems,iteration,EPSVALUE)

Expand Down
15 changes: 5 additions & 10 deletions src/MIP/subproblem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
function setup_sub!(subproblems,patients::IndexedTable,visits,resources::IndexedTable,timeslots,mastercalendar::Dict{Int,Date},TimeDelta,sets,months)


for patient in rows(patients)
for patientgroup in [i for i in 1:length(sets.Pg)]

#TODO length of min treatment time should be calculated and used.


setup_sub!(subproblems,patient,visits,resources,timeslots,mastercalendar,TimeDelta,sets,months)
setup_sub!(subproblems,patientgroup,visits,resources,timeslots,mastercalendar,TimeDelta,sets,months)
end
end
startofyear(date::Date) = Date(Year(date))
Expand All @@ -31,12 +31,12 @@ function getTimeDelta(timeDelta,visits,v1,v2)
end


function setup_sub!(subproblems,patient::NamedTuple,visits,resources::IndexedTable,timeslots,mastercalendar::Dict{Int,Date},timeDelta,sets,months)
function setup_sub!(subproblems,p::Int64,visits,resources::IndexedTable,timeslots,mastercalendar::Dict{Int,Date},timeDelta,sets,months)
M1 = 10
M2 = 1000

Td(v1,v2) = getTimeDelta(timeDelta,visits,v1,v2)
p = patient.intID

V = sets.Vp[p].v; Dv = sets.Dv; D = sets.Dp[p].d; J = sets.J ;Jd = sets.Jd; I = sets.I
Ts(d,j,i) = Dates.value(timeslots[d,j,i].startTime)/60000000000
Te(d,j,i) = Dates.value(timeslots[d,j,i].endTime)/60000000000
Expand All @@ -46,11 +46,6 @@ function setup_sub!(subproblems,patient::NamedTuple,visits,resources::IndexedTab
enddate = startdate + Month(months)-Day(1)
subMastercalendar = MasterCalendar(mastercalendar,startdate,enddate)



# TODO tilføj gruppering igen
#TODO input all the . notificatons

sub = Model(with_optimizer(Gurobi.Optimizer,OutputFlag=0))
@variable(sub,xvars[v in V,d in Dv[v].d,j in Jd[d].j,i in I[d,j].i],Bin)
@variable(sub,yvars[j = J],Bin)
Expand Down Expand Up @@ -115,7 +110,7 @@ function solveSub!(sub,ϕ,θ,κ)
optimize!(sub.model)
status = termination_status(sub.model)
if status != MOI.TerminationStatusCode(1)
println("$(minimum(sub.J)) - $(maximum(sub.J))")

throw("Error: Non optimal sub-problem for subproblem $(sub.intID)")

#TODO Throw warning and extend search area
Expand Down

0 comments on commit 77070b5

Please sign in to comment.