Last active
January 3, 2022 15:21
-
-
Save Sushant-Padha/6210c782eceb57da9331e4d7dc54b167 to your computer and use it in GitHub Desktop.
Julia: JuMP constraint to only use a value `n` times
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using JuMP | |
using ConstraintSolver | |
using Random: shuffle | |
const CS = ConstraintSolver | |
function my_global_cardinality_count(model, a, gcc) | |
for (i, count) in enumerate(gcc) | |
# my_count_ctr(model, x, val, s) | |
my_count_ctr(model, a, i, count) | |
end | |
end | |
function my_count_ctr(model, x, val, s) | |
len = length(x) | |
b = @variable(model, [1:len], Bin) | |
for i in eachindex(x) | |
@constraint(model, b[i] := {x[i] == val}) | |
end | |
@constraint(model, s == sum(b)) | |
end | |
function get_counts(numvars::Int, numvals::Int, iterations::Int) | |
model = Model(optimizer_with_attributes(CS.Optimizer, "logging" => [], "all_solutions" => true, "time_limit" => 10)) | |
@variable(model, c[1:numvals], CS.Integers(1:numvars)) | |
@constraint(model, sum(c) == numvars) | |
optimize!(model) | |
numsols = MOI.get(model, MOI.ResultCount()) | |
arrcounts = [] | |
# return iterations random counts | |
for i in shuffle(collect(Int, 1:numsols)) | |
length(arrcounts) == iterations && break | |
counts = convert.(Int, JuMP.value.(c; result = i)) | |
push!(arrcounts, counts) | |
end | |
return arrcounts | |
end | |
function gcc_test(model::Model, numvars::Int, numvals::Int, counts::Vector{Int}) | |
x = @variable(model, [1:numvars], CS.Integers(1:numvals)) | |
my_global_cardinality_count(model, x, counts) | |
optimize!(model) | |
status = JuMP.termination_status(model) | |
if status != MOI.OPTIMAL | |
error("UNSOLVED status = ", status) | |
end | |
return x | |
end | |
function binexpr_test(model::Model, numvars::Int, numvals::Int, counts::Vector{Int}) | |
y = @variable(model, [1:numvars, 1:numvals], Bin) | |
@constraint(model, [i = 1:numvars], sum(y[i, :]) == 1) | |
@constraint(model, [j = eachindex(counts)], sum(y[:, j]) == counts[j]) | |
x = @expression(model, [i = 1:numvars], sum(j * y[i, j] for j in 1:numvals)) | |
optimize!(model) | |
status = JuMP.termination_status(model) | |
if status != MOI.OPTIMAL | |
error("UNSOLVED status = ", status) | |
end | |
return x | |
end | |
function main(numvars::Int, numvals::Int, iterations::Int) | |
arrcounts = get_counts(numvars, numvals, iterations) | |
@show numvars | |
@show numvals | |
@show iterations | |
optimizer = optimizer_with_attributes(CS.Optimizer, "logging" => []) | |
println() | |
println(">>> gcc_test") | |
for counts in arrcounts | |
model = Model(optimizer) | |
@time x = gcc_test(model, numvars, numvals, counts) | |
sol = convert.(Int, JuMP.value.(x)) | |
# @show sol | |
end | |
println("\n>>> binexpr_test") | |
for counts in arrcounts | |
model = Model(optimizer) | |
@time x = binexpr_test(model, numvars, numvals, counts) | |
sol = convert.(Int, JuMP.value.(x)) | |
# @show sol | |
end | |
end | |
numvars = 100 | |
numvals = 85 | |
iterations = 7 | |
main(numvars, numvals, iterations) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
numvars = 100 | |
numvals = 85 | |
iterations = 7 | |
>>> gcc_test | |
34.166232 seconds (135.26 M allocations: 5.712 GiB, 4.85% gc time) | |
30.425048 seconds (134.50 M allocations: 5.686 GiB, 5.43% gc time) | |
32.487867 seconds (134.39 M allocations: 5.682 GiB, 11.95% gc time) | |
39.821295 seconds (134.67 M allocations: 5.691 GiB, 13.72% gc time) | |
39.392002 seconds (134.97 M allocations: 5.702 GiB, 17.15% gc time) | |
37.955290 seconds (135.10 M allocations: 5.706 GiB, 16.18% gc time) | |
46.214961 seconds (134.53 M allocations: 5.687 GiB, 23.91% gc time) | |
>>> binexpr_test | |
20.687769 seconds (5.41 M allocations: 2.105 GiB, 66.87% gc time, 0.29% compilation time) | |
12.021020 seconds (5.34 M allocations: 2.096 GiB, 22.89% gc time) | |
12.614482 seconds (5.34 M allocations: 2.096 GiB, 31.58% gc time) | |
10.301787 seconds (5.35 M allocations: 2.098 GiB, 40.05% gc time) | |
11.158253 seconds (5.36 M allocations: 2.100 GiB, 36.38% gc time) | |
16.221497 seconds (5.36 M allocations: 2.101 GiB, 46.33% gc time) | |
12.527854 seconds (5.34 M allocations: 2.097 GiB, 35.56% gc time) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment