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

Added instance generator for KEP #224

Merged
merged 3 commits into from
May 5, 2022

Conversation

marco-novaes98
Copy link
Contributor

Fill a CPModel with the variables and constraints generated. We fill it directly instead of
creating temporary files for efficiency purpose!

The decision matrix x is the adjacent matrix of the graph (i.e. the instance).
x[i, j] is branchable => pair i can receive a kidney from pair j
x[i, j] is not branchable => pair i can not receive a kidney from pair j

The generator ensure that all pairs have at least one in edge and one out edge (i.e. one branchable variable per row and column).
For this we first place one branchable variable in each line of the matrix with a different column index each time.
Then, the remaining edges are assigned randomly between the non-asssigned elements of the decision matrix.

@marco-novaes98 marco-novaes98 requested a review from 3rdCore May 5, 2022 15:30
@marco-novaes98 marco-novaes98 marked this pull request as ready for review May 5, 2022 15:30
@gostreap gostreap added generator Everything related to instance generation. Usually found in the `datagen` folder. and removed reinforcement learning labels May 5, 2022
Copy link
Collaborator

@3rdCore 3rdCore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That Looks good for me!

# ensure that all pairs have at least one in edge and one out edge
indexes = [(i,j) for i = 1:nb_nodes for j = 1:nb_nodes]
permutation = shuffle([i for i=1:nb_nodes]) # permutation[i] = j => x[i, j] is branchable
flat_index_required_branchable = [permutation[i] + (i-1)*nb_nodes for i in 1:nb_nodes]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you briefly explain this ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That transform the permutation [2, 1, 3] such that : [2, 1, 3] -> [2, 4, 6]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright got it, that's because indexes[i+nb_nodes*j]= (i,j) ? or the contrary ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your last message is right! The idea is that in first place we assign one branchable variable in each line of the matrix with a different column index each time. permutation ensures that each column index is different each time. In that way we ensure that all pairs have at least one incoming arc and one outgoing arc.

Comment on lines +46 to +94
### Variables ###
x = Matrix{SeaPearl.AbstractIntVar}(undef, nb_nodes, nb_nodes)
minus_x = Matrix{SeaPearl.AbstractIntVar}(undef, nb_nodes, nb_nodes)

for i = 1:nb_nodes
for j = 1:nb_nodes
if (i,j) in index_branchable
x[i, j] = SeaPearl.IntVar(0, 1, "x_"*string(i)*"_"*string(j), model.trailer)
SeaPearl.addVariable!(model, x[i, j]; branchable=true)
minus_x[i, j] = SeaPearl.IntVarViewOpposite(x[i, j], "-x_"*string(i)*"_"*string(j))
else
x[i, j] = SeaPearl.IntVar(0, 0, "x_"*string(i)*"_"*string(j), model.trailer)
SeaPearl.addVariable!(model, x[i, j]; branchable=false)
minus_x[i, j] = SeaPearl.IntVarViewOpposite(x[i, j], "-x_"*string(i)*"_"*string(j))
end
end
end

### Constraints ###
for i = 1:nb_nodes
#Check that any pair receives more than 1 kidney
SeaPearl.addConstraint!(model, SeaPearl.SumLessThan(x[i, :], 1, model.trailer))

#Check that any pair gives more than 1 kidney
SeaPearl.addConstraint!(model, SeaPearl.SumLessThan(x[:, i], 1, model.trailer))

#Check that for each pair: give a kidney <=> receive a kidney
SeaPearl.addConstraint!(model, SeaPearl.SumToZero(hcat(x[:, i], minus_x[i, :]), model.trailer))
end

### Objective ###

#SeaPearl's solver minimize the objective variable, so we use minusNumberOfExchanges in order to maximize the number of exchanges
minusNumberOfExchanges = SeaPearl.IntVar(-nb_nodes, 0, "minusNumberOfExchanges", model.trailer)
SeaPearl.addVariable!(model, minusNumberOfExchanges; branchable=false)
vars = SeaPearl.AbstractIntVar[]

#Concatenate all values of x and minusNumberOfExchanges
for i in 1:nb_nodes
vars = cat(vars, x[i, :]; dims=1)
end
push!(vars, minusNumberOfExchanges)

#minusNumberOfExchanges will take the necessary value to compensate the occurences of "1" in x
objective = SeaPearl.SumToZero(vars, model.trailer)
SeaPearl.addConstraint!(model, objective)
SeaPearl.addObjective!(model, minusNumberOfExchanges)

nothing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I trust you on the model definition as long as is doesn't differ from what has been previously done !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used the same model


# the remaining edges are assigned randomly between the non-asssigned elements of the decision matrix
nb_unassigned_edges = total_edges - nb_nodes
append!(index_branchable, sample(indexes, nb_unassigned_edges))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very elegant syntax! The fact that splice! removes the value at index i from the array ensures that you cannot append twice the same edge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks :)

@marco-novaes98 marco-novaes98 merged commit 8f43730 into master May 5, 2022
@marco-novaes98 marco-novaes98 deleted the marco/kep_instance_generator branch May 5, 2022 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generator Everything related to instance generation. Usually found in the `datagen` folder.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants