martinbiel / StochasticPrograms.jl

Julia package for formulating and analyzing stochastic recourse models.
MIT License
75 stars 25 forks source link

Creating instant model issue with scenario defined type vector #27

Closed thvo1304 closed 3 years ago

thvo1304 commented 3 years ago

Hello, I'm trying to create a stochastic model with a defined scenario using the instantiate function. However, I'm being stuck at the step of generating the model.

# Generating scenario object
@define_scenario SampleScenario = begin
  d::Vector{Float64}

  @zero begin
    return SampleScenario([])
  end
end

sampled_d = []

for i in 1:size(new_d,2)
  scen_d = SampleScenario(new_d[:,i], probability = 1/s)
  push!(sampled_d,scen_d)
end

##### Sample Average Approximation (SAA)
SAA_model = @stochastic_model begin
  @stage 1 begin
      @decision(model, x[i in loc], Bin)
      @objective(model, Min, sum(f[i]*x[i] for i in loc))
      @constraint(model, max_d <= sum(q[i]*x[i] for i in loc))
  end
  @stage 2 begin
      @uncertain d
      @variable(model, y[i in loc, j in cust] >= 0)
      @objective(model, Min, sum(c[i,j]*y[i,j] for i in loc, j in cust))
      for j in cust
        @constraint(m, sum(y[i,j] for i in loc) == 1)
      end
      @constraint(model, sum(d[j]*y[i,j] for i in loc, j in cust) <= (q[i]*x[i] for i in loc))
  end
end

sp = instantiate(SAA_model, sampled_d, optimizer = Gurobi.Optimizer)

This is the errors that i got :

julia> sp = instantiate(SAA_model, sampled_d, optimizer = Gurobi.Optimizer)
ERROR: MethodError: no method matching instantiate(::StochasticModel{2,Tuple{StageParameters{NamedTuple{(),Tuple{}}},StageParameters{NamedTuple{(),Tuple{}}}}}, ::Array{Any,1}; optimizer=Gurobi.Optimizer)
Closest candidates are:
  instantiate(::StochasticModel{2,P} where P<:Tuple{StageParameters,StageParameters}; instantiation, optimizer, scenario_type, kw...) at C:\Users\thvoe\.julia\packages\StochasticPrograms\54439\src\methods\api.jl:51
  instantiate(::StochasticModel{2,P} where P<:Tuple{StageParameters,StageParameters}, ::Array{var"#s313",1} where var"#s313"<:AbstractScenario; instantiation, optimizer, defer, direct_model, kw...) at C:\Users\thvoe\.julia\packages\StochasticPrograms\54439\src\methods\api.jl:13
  instantiate(::StochasticModel{N,P} where P<:Tuple{Vararg{StageParameters,N}}, ::Tuple{Vararg{Array{var"#s313",1} where var"#s313"<:AbstractScenario,M}}; instantiation, optimizer, defer, kw...) where {N, M} at C:\Users\thvoe\.julia\packages\StochasticPrograms\54439\src\methods\api.jl:75
  ...
Stacktrace:
 [1] top-level scope at REPL[36]:1

This is a scenario that I created - I created 10 scenarios and stored them in sampled_d

SampleScenario with probability 0.1
  d: [2.988512125542072e7, 1.82191958067763e7, 1.6796811372859593e7, 1.2689287123169903e7, 1.2078740851981416e7, 1.1504444297988124e7, 1.1032095197107881e7, 9.268044238581678e6, 7.744850040767815e6, 6.6352522102797e6, 6.339484999019626e6, 6.3095052556271525e6, 
6.031037127521951e6, 5.545212596396539e6, 5.197903683791194e6, 4.829404886428685e6, 4.881395579573187e6, 4.936513209080188e6, 5.008080425502865e6, 4.39200793904869e6, 4.0712369579552263e6, 3.9271770918271123e6, 3.739408541525981e6, 3.602130358768027e6, 3.4117168988347184e6, 3.243302016049922e6, 3.347707426277846e6, 3.2215137658458822e6, 2.798349753356594e6, 2.8439707818016275e6, 2.5755031919725165e6, 2.4840354253501585e6, 2.41716560820301e6, 1.8032710521427672e6, 1.7415367789567339e6, 1.561161983844303e6, 1.5362675149438747e6, 1.2259069179470218e6, 1.2056343414727375e6, 1.1159628408654933e6, 1.0212575397324166e6, 1.0220766953609476e6, 832085.879686038, 709216.1856799318, 650942.8530383029, 639527.8115793295, 602692.494167077, 569459.1519526091, 464521.8452150164]

I don't know how to solve this problem. Hope you can help! Thank you.

martinbiel commented 3 years ago

It is a type inference issue, your sampled_d = [] gives an Array{Any,1} which is not recognized as an array of scenarios. Inititializing it as sampled_d = SampleScenario[] should fix it.

Note, that with the latest release you can safely rely on the fallback scenario structure for implementations like this:

SAA_model = @stochastic_model begin
    @stage 1 begin
        @decision(model, x[i in loc], Bin)
        @objective(model, Min, sum(f[i]*x[i] for i in loc))
        @constraint(model, max_d <= sum(q[i]*x[i] for i in loc))
    end
    @stage 2 begin
        @uncertain d[j in cust]
        @variable(model, y[i in loc, j in cust] >= 0)
        @objective(model, Min, sum(c[i,j]*y[i,j] for i in loc, j in cust))
        for j in cust
            @constraint(m, sum(y[i,j] for i in loc) == 1)
        end
        @constraint(model, sum(d[j]*y[i,j] for i in loc, j in cust) <= (q[i]*x[i] for i in loc))
    end
end
sampled_d = Scenario[]
for i in 1:size(new_d,2)
    scen_d = @scenario d[j in cust] = new_d[:,i] probability = 1/s
    push!(sampled_d, scen_d)
end

Note the @uncertain declaration and the matching @scenario instantiation. The above code is not tested since I do not know what new_d and s etc are.