first_stage_variables[1] = x
This stores the first stage variable x in the dictionary first_stage_variables with the key 1.
When you call Build_Subproblem with different values of s, this value gets overwritten. Thus, after Build_Subproblem, it contains the value of x from scenarios subproblem. When you solve the first subproblem, you query the value of the variable, but that problem hasn’t been optimized yet.
You need to think about a different data structure to use.
Here’s one approach:
using JuMP, Gurobi
scenarios = 3
probabiliity = [0.2, 0.5, 0.3]
demand = [[3.0, 3.0, 2.0], [5.0, 3.0, 2.0], [7.0, 3.0, 2.0]]
generators = 4
periods = 3
fixed_cost = [10, 7, 16, 6]
variable_cost = [40 24 4; 45 27 4.5; 32 19.2 3.2; 55 33 5.5]
minimum_power = 12
budget = 120
function build_subproblem(s::Int)
subproblem = Model(Gurobi.Optimizer)
set_silent(subproblem)
@variable(subproblem, x[1:generators] >= 0)
@variable(subproblem, y[1:generators, 1:periods] >= 0)
@constraint(subproblem, sum(x) >= minimum_power)
@constraint(subproblem, fixed_cost' * x <= budget)
for i in 1:generators, j in 1:periods
@constraint(subproblem, y[i, j] <= x[i])
end
for j in 1:periods
@constraint(subproblem, sum(y[:, j]) >= demand[s][j])
end
@objective(subproblem, Min, fixed_cost' * x + sum(variable_cost .* y))
return (model = subproblem, first_stage_variables = [x])
end
function solve_subproblem(data)
optimize!(data.model)
@assert is_solved_and_feasible(data.model) # Important!!! Check solved okay
first_stage_solutions = [
JuMP.value.(variable) for variable in data.first_stage_variables
]
return first_stage_solutions
end
subproblems = [build_subproblem(s) for s in 1:scenarios]
solutions = []
for s in 1:scenarios
push!(solutions, solve_subproblem(subproblems[s]))
end
You will probably benefit from reading these tutorials: