atoptima / Coluna.jl

Branch-and-Price-and-Cut in Julia
https://www.atoptima.com
Other
193 stars 43 forks source link

ERROR: LoadError: ArgumentError: reducing over an empty collection is not allowed #488

Closed hhkramer closed 3 years ago

hhkramer commented 3 years ago

Describe the bug When trying to solve my application with coluna using Strong Branching with BestDualBoundStrategy and disabling Primal Heuristics I get the following error:

ERROR: LoadError: ArgumentError: reducing over an empty collection is not allowed

To Reproduce Parameters are set as follows:

coluna = optimizer_with_attributes(
        Coluna.Optimizer,
        "params" => Coluna.Params(
            solver = Coluna.Algorithm.TreeSearchAlgorithm(
                branchingtreefile = "clsp.dot",
                dividealg = Coluna.Algorithm.StrongBranching(
                    phases = [Coluna.Algorithm.BranchingPhase(20, Coluna.Algorithm.RestrMasterLPConquer()),
                              Coluna.Algorithm.BranchingPhase(2, 
                                                              Coluna.Algorithm.ColCutGenConquer(
                                                                colgen = Coluna.Algorithm.ColumnGeneration(),
                                                                max_nb_cut_rounds = 0,
                                                                primal_heuristics = Coluna.Algorithm.ParameterisedHeuristic[]))],
                    rules = [Coluna.Algorithm.PrioritisedBranchingRule(Coluna.Algorithm.VarBranchingRule(), 1.0, 1.0)]
                ),
                explorestrategy = Coluna.Algorithm.BestDualBoundStrategy(),
                conqueralg = Coluna.Algorithm.ColCutGenConquer(
                    primal_heuristics = Coluna.Algorithm.ParameterisedHeuristic[])
            )
        ),
        "default_optimizer" => Gurobi.Optimizer 
    )

Expected behavior

ERROR: LoadError: ArgumentError: reducing over an empty collection is not allowed
Stacktrace:
 [1] _empty_reduce_error() at .\reduce.jl:299
 [2] reduce_empty(::Function, ::Type{Float64}) at .\reduce.jl:309
 [3] mapreduce_empty(::typeof(identity), ::Function, ::Type{T} where T) at .\reduce.jl:343
 [4] reduce_empty(::Base.MappingRF{typeof(identity),typeof(max)}, ::Type{Float64}) at .\reduce.jl:329
 [5] reduce_empty_iter at .\reduce.jl:355 [inlined]
 [6] mapreduce_empty_iter(::Function, ::Function, ::Array{Float64,1}, ::Base.HasEltype) at .\reduce.jl:351
 [7] _mapreduce(::typeof(identity), ::typeof(max), ::IndexLinear, ::Array{Float64,1}) at .\reduce.jl:400
 [8] _mapreduce_dim at .\reducedim.jl:318 [inlined]
 [9] #mapreduce#620 at .\reducedim.jl:310 [inlined]
 [10] mapreduce at .\reducedim.jl:310 [inlined]
 [11] _maximum at .\reducedim.jl:727 [inlined]
 [12] _maximum at .\reducedim.jl:726 [inlined]
 [13] #maximum#631 at .\reducedim.jl:722 [inlined]
 [14] maximum at .\reducedim.jl:722 [inlined]
 [15] compute_tree_depth_score!(::Coluna.Algorithm.BranchingGroup, ::Coluna.Algorithm.OptimizationState{Coluna.MathProg.Formulation{Coluna.MathProg.DwMaster},
Coluna.MathProg.MinSense}) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\Algorithm\branching\branchinggroup.jl:143
 [16] perform_strong_branching_with_phases!(::Coluna.Algorithm.StrongBranching, ::Coluna.Env, ::Coluna.Algorithm.ReformData, ::Coluna.Algorithm.DivideInput, :
:Array{Coluna.Algorithm.BranchingGroup,1}) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\Algorithm\branching\branchingalgo.jl:174
 [17] run!(::Coluna.Algorithm.StrongBranching, ::Coluna.Env, ::Coluna.Algorithm.ReformData, ::Coluna.Algorithm.DivideInput) at C:\Users\hugoh\.julia\packages\
Coluna\uQdsR\src\Algorithm\branching\branchingalgo.jl:294
 [18] run_divide_algorithm!(::Coluna.Algorithm.TreeSearchAlgorithm, ::Coluna.Env, ::Coluna.Algorithm.TreeSearchRuntimeData{Coluna.MathProg.MinSense}, ::Coluna
.Algorithm.ReformData, ::Coluna.Algorithm.Node) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\Algorithm\treesearch.jl:270
 [19] run!(::Coluna.Algorithm.TreeSearchAlgorithm, ::Coluna.Env, ::Coluna.Algorithm.ReformData, ::Coluna.Algorithm.OptimizationInput{Coluna.MathProg.Formulati
on{Coluna.MathProg.DwMaster},Coluna.MathProg.MinSense}) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\Algorithm\treesearch.jl:340
 [20] optimize!(::Coluna.MathProg.Reformulation, ::Coluna.Env, ::Coluna.ColunaBase.Bound{Coluna.MathProg.Primal,Coluna.MathProg.MinSense}, ::Coluna.ColunaBase
.Bound{Coluna.MathProg.Dual,Coluna.MathProg.MinSense}) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\optimize.jl:98
 [21] macro expansion at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\optimize.jl:65 [inlined]
 [22] macro expansion at C:\Users\hugoh\.julia\packages\TimerOutputs\4QAIk\src\TimerOutput.jl:190 [inlined]
 [23] optimize!(::Coluna.MathProg.Problem, ::Coluna.Annotations, ::Coluna.Params) at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\optimize.jl:64
 [24] optimize! at C:\Users\hugoh\.julia\packages\Coluna\uQdsR\src\MOIwrapper.jl:101 [inlined]
 [25] optimize!(::MathOptInterface.Bridges.LazyBridgeOptimizer{Coluna.Optimizer}) at C:\Users\hugoh\.julia\packages\MathOptInterface\ZJFKw\src\Bridges\bridge_
optimizer.jl:264
 [26] optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface
.Utilities.Model{Float64}}}) at C:\Users\hugoh\.julia\packages\MathOptInterface\ZJFKw\src\Utilities\cachingoptimizer.jl:215
 [27] optimize!(::JuMP.Model, ::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple
{(),Tuple{}}}) at C:\Users\hugoh\.julia\packages\JuMP\y5vgk\src\optimizer_interface.jl:139
 [28] optimize!(::JuMP.Model) at C:\Users\hugoh\.julia\packages\BlockDecomposition\OYIcC\src\BlockDecomposition.jl:51
 [29] optimize!(::JuMP.Model, ::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple
{(),Tuple{}}}) at C:\Users\hugoh\.julia\packages\JuMP\y5vgk\src\optimizer_interface.jl:129
 [30] optimize! at C:\Users\hugoh\.julia\packages\JuMP\y5vgk\src\optimizer_interface.jl:115 [inlined] (repeats 2 times)
 [31] macro expansion at C:\Users\hugoh\Documents\Codes\Atoptima\UFPB_Project\ColunaBenchmarks\src\CapacitatedLotSizing\run.jl:31 [inlined]
 [32] macro expansion at .\timing.jl:233 [inlined]
 [33] run_clsp(::String, ::Main.CapacitatedLotSizing.AppParams) at C:\Users\hugoh\Documents\Codes\Atoptima\UFPB_Project\ColunaBenchmarks\src\CapacitatedLotSiz
ing\run.jl:30
 [34] top-level scope at C:\Users\hugoh\Documents\Codes\Atoptima\UFPB_Project\ColunaBenchmarks\src\CapacitatedLotSizing\scripts\runsingleinstance.jl:13
 [35] include(::Function, ::Module, ::String) at .\Base.jl:380
 [36] include(::Module, ::String) at .\Base.jl:368
 [37] exec_options(::Base.JLOptions) at .\client.jl:296
 [38] _start() at .\client.jl:506
in expression starting at C:\Users\hugoh\Documents\Codes\Atoptima\UFPB_Project\ColunaBenchmarks\src\CapacitatedLotSizing\scripts\runsingleinstance.jl:13

Environment (please complete the following information):

guimarqu commented 3 years ago

@rrsadykov what should be the value of max_delta if isempty(deltas) ?

https://github.com/atoptima/Coluna.jl/blob/7a7d72688e3b326d0ad7273b38cd5adb828a9785/src/Algorithm/branching/branchinggroup.jl#L143-L146

rrsadykov commented 3 years ago

If deltas is empty, max_delta and parent_delta can be anything, as they are not used later (score is set to zero if deltas is empty). Sorry for this bug