Skip to content

Parametrise sets or have different sets? #22

@dourouc05

Description

@dourouc05

What would be the best option to encode very similar sets? Currently, I have defined GlobalCardinality, GlobalCardinalityVariable, ClosedGlobalCardinality, and ClosedGlobalCardinalityVariable: there are also up-low and sliding variants of the GCC, which would make an awful lot of sets (sixteen). Plus less common variants, without loops and with a cost matrix, that would make 64 sets for all possible variants of GCC, i.e. a combinatorial explosion. (And then some user will ask for another kind, and that would be 128.)

The same kind of problem appeared with knapsacks and bin packing: every time a new parameter is added or a fixed parameter is allowed to be a variable, a slew of new sets must be added (with many new bridges, also).

The other solution would be to have more parameters for each set: that would mean only a GlobalCardinality set to replace the four existing GlobalCardinality, GlobalCardinalityVariable, ClosedGlobalCardinality, and ClosedGlobalCardinalityVariable. It would look like this:

struct GlobalCardinality{T, UpOrLow, VariableValues} <: MOI.AbstractVectorSet
    dimension::Int
    values::Vector{T}
end

# GlobalCardinalityVariable{T}: GlobalCardinality{T, false, true}
# ClosedGlobalCardinality{T}: GlobalCardinality{T, true, false}
# ClosedGlobalCardinalityVariable{T}: GlobalCardinality{T, true, true}

Instead of Booleans, we could do like MOI.Indicator and use an enum (https://github.com/jump-dev/MathOptInterface.jl/blob/9ceb2dee8820e14c1edb0f21b66115faa3469af6/src/sets.jl#L985-L1041). Using this kind of type parameters would be absolutely needed so that solvers can say exactly what version(s) they support and rely on bridges for the rest of them (for instance, Closed just means that the number of occurrences for each value is bounded below and above).

However, such a representation would make it hard to extend the available sets: adding a new GCC set, for instance, would require changing this package's code to remain consistent. It's still possible to create sets outside, however. I feel this would break the OCP principle, even though the code here would be easier to write and to use for users. To write new solver wrappers, I don't think having type parameters instead of many sets would be a great problem, but each change to CPE would force solvers/wrappers to be updated (I don't think there should be many of them either).

@Wikunia @Azzaare in your opinion, what would be best for the solvers and users?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions