Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RB generator #220

Merged
merged 5 commits into from
May 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add test to rb + fix rb generator
  • Loading branch information
gostreap committed Apr 7, 2022
commit 60ab21ecc93d7ca99008a8e91372dd2813d79b90
23 changes: 13 additions & 10 deletions src/datagen/rb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ Generator of RB instances :
- n ≥ 2 number of variables
- α > 0 determines the domain size d = n^α of each variable,
- r > 0 determines the number m = r ⋅ n ⋅ ln(n) of constraints,
- 0 < p < 1 determines the number t = p ⋅ d^k of disallowed tuples of each relation.
- 0 < p < 1 determines the number nb = (1 - p) ⋅ d^k of disallowed tuples of each relation.
- d domain size of each variable
- m number of constraints
- t number of disallowed tuples of each relation
- nb number of allowed tuples of each relation
"""
struct RBGenerator <: AbstractModelGenerator
k::Int64 # arity of each constraint
Expand All @@ -32,7 +32,7 @@ struct RBGenerator <: AbstractModelGenerator
@assert α > 0
@assert r > 0
@assert 0 < p && p < 1
new(n, k, α, r, p, round(n^α), round(r*n*log(n)), round((1 - p) * d^k))
new(k, n, α, r, p, round(n^α), round(r*n*log(n)), round((1 - p) * round(n^α)^k))
end
end

Expand Down Expand Up @@ -63,18 +63,21 @@ function fill_with_generator!(cpmodel::CPModel, gen::RBGenerator; seed=nothing)
for i in 1:gen.m
scope = StatsBase.sample(1:gen.n, gen.k, replace=false, ordered=false)
variables = [x[j] for j in scope]
table = [[random_solution[j] for j in scope]]
table = zeros(Int64, gen.k, gen.nb)
table[:, 1] = [random_solution[j] for j in scope]

tuples = collect(Iterators.product([1:gen.d for j in 1:gen.k]...))
remove!(tuples, table[1])
allowed_indices = StatsBase.sample(1:length(tuples), gen.nb-1)
tuples = reshape(tuples, prod(size(tuples)))
tuples = [collect(tuple) for tuple in tuples]

for id in allowed_indices
tuple = tuples[id]
add!(table, tuple)
deleteat!(tuples, findfirst(t -> t == table[:, 1], tuples))
allowed_tuples = StatsBase.sample(tuples, gen.nb-1)

for (i, tuple) in enumerate(allowed_tuples)
table[:, i + 1] = tuple
end

SeaPearl.addConstraint!(cpmodel, SeaPearl.TableConstraint(variables, table))
SeaPearl.addConstraint!(cpmodel, SeaPearl.TableConstraint(variables, table, cpmodel.trailer))
end

return nothing
Expand Down
1 change: 1 addition & 0 deletions test/datagen/datagen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ include("coloring.jl")
include("knapsack.jl")
include("tsptw.jl")
include("nqueens.jl")
include("rb.jl")
# TODO: create a latin_square testset
# inlcude("latin.jl")
25 changes: 25 additions & 0 deletions test/datagen/rb.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@testset "rb.jl" begin
@testset "fill_with_generator!(::RBGenerator)" begin
trailer = SeaPearl.Trailer()
model = SeaPearl.CPModel(trailer)

k = 3 # arity of each constraint
n = 5 # number of variables
α = 1 # determines the domain size d = n^α of each variable,
r = 2 # determines the number m = r ⋅ n ⋅ ln(n) of constraints,
p = 0.5 # determines the number t = p ⋅ d^k of disallowed tuples of each relation.
generator = SeaPearl.RBGenerator(k, n, α, r, p)

nb::Int64 = round((1 - p) * round(n^α)^k)

SeaPearl.fill_with_generator!(model, generator)

@test length(keys(model.variables)) == n
@test length(model.constraints) == round(r * n * log(n))
for constraint in model.constraints
@test isa(constraint, SeaPearl.TableConstraint)
@test length(constraint.scope) == k
@test size(constraint.table) == (k, nb)
end
end
end