Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Sushant-Padha
Last active January 3, 2022 15:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sushant-Padha/6210c782eceb57da9331e4d7dc54b167 to your computer and use it in GitHub Desktop.
Save Sushant-Padha/6210c782eceb57da9331e4d7dc54b167 to your computer and use it in GitHub Desktop.
Julia: JuMP constraint to only use a value `n` times
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)
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