So what are our CellBlock decisions?

Well, we've got to think about this.

It may not look like this in an assignment solve problem, but it is.

We've got our prisoners are the domains of the function that we're trying to find,

and the object of the codomain are the row times column, it's the cell blocks.

But we're not going to represent this as a single function,

we're going to break it down into two functions because that's a much more

natural way of representing the problem.

So for each prisoner, we're going to really decide two functions.

That is, which row is that prisoner in and which column is that prisoner in?

Of course those two functions together decide which exact cell they're in.

That's because it's going to be much more natural to reason about and

express some of the constraints of the problem with these two functions than with

a single function, which only names an exact cell position.

And these are the kind of decisions that we need to make when modelling.

What's the right way of representing what we're doing in order to make it

easy to express the constraints and the objectives of the model,

in order that the solver can solve it efficiently.

So we can think about how we gotta express the constraints of the problem.

So no two prisoners in the same cell.

So one way to do this is to look at each pair of prisoners, and we'll say,

well we've got to make them not in the same cell.

Well one way of doing that is saying the absolute value of the distances in

the rows, and the distances in the columns,

if we add them up, has to be greater than 0.

So that means that we can't have them in both the same row and

both the same column, so that's one efficient way of writing that down.

Can't we use alldifferent?

Remember this was an assignment subproblem and what we would like to

say is capture that substructure had use the alldifferent constraint.

So that as solvers you can make use of that and get the maximum value out of it.

Yes we can and

in fact they're much better way than doing this is to map this to an alldifferent.

But in order to do that, we're going to have to create, basically,

a unique number for each CellBlock, which is easy enough to do.

We take the row number, we multiply it by the number of columns there are and

add the column number and that's going to give us a unique number for each cell.

And then we're going to force those to the alldifferent for each prisoner and

that will force that each prisoner is in a different cell.

And then we've now used our global constraint,

all different to make sure they're all mapped to a different cell.

So this is where if we had a model which only gave a unique cell number,

this would be very, very convenient but

it would make the rest of the model much more difficult.

And so we only need it for this thing, let's only create this view

of the problem for the alldifferent constraint and nowhere else.

Now, we have to have no adjacent prisoners in here

the kind of model we used up here is very efficient.

We're going to say that if we take the absolute value of the rows and

the columns, they have to be greater than one which will make sure the distance away

is at least more than one.

So, we can't be right next to the cell of a dangerous prisoner.

So, we look for each prisoner and for each dangerous prisoner where it's not the same

obviously the dangerous prisoner can't be the same cells themselves or herself and

so, for each other prisoner that can't be within a distance of one.

If we go in this horizontal distance.

So that will effectively map that we're

far enough away from the dangerous prisoners.

And then we can't use a combination such as the alldifferent,

a more complicated constraint meaning to express it in a more complicated way.