Answered question
This question has been answered.

Unanswered question
This question has not been answered yet.

Hello

To my understanding, and after browsing the documentation, I thought this following test with the inverse function would work, but the answer is "no solution"

using CP;
range rcandidats = 0 .. 3;
range ralveoles = 0 .. 9;
dvar int alv[rcandidats] in 0 .. 10;
dvar int can[ralveoles] in 0 .. 4;
constraints{
inverse(alv,can);
}

Here, I want to say that any candidate 0,1,2,3 will have a destination alv among the 10 locations 0,..9. Or a dummy destination 10 otherwise

Reversely, for any destination 0,..9, I will store in can the chosen candidate , that will be between 0 and 3 except if no candidate is chosen for this destination and in this case, the can variable is set to 4.

This seems compatible to me with the documentation :

if the length of the array f is n, and the length of the array invf is m, then the inverse constraint guarantees that:

for all i in the interval [0,n-1], if f[i] is in [0,m-1], then invf[f[i]]==i;

for all j in the interval [0,m-1], if invf[j] is in [0,n-1], then f[invf[j]]==j.

However, the program runs with no solution.

Do I miss something here ?

David

Hello

To my understanding, and after browsing the documentation, I thought this following test with the inverse function would work, but the answer is "no solution"

<pre class="java dw" data-editor-lang="java" data-pbcklang="java" dir="ltr">using CP;
range rcandidats = 0 .. 3;
range ralveoles = 0 .. 9;
dvar int alv[rcandidats] in 0 .. 10;
dvar int can[ralveoles] in 0 .. 4;
constraints{
inverse(alv,can);
}
</pre>

Here, I want to say that any candidate 0,1,2,3 will have a destination alv among the 10 locations 0,..9. Or a dummy destination 10 otherwise

Reversely, for any destination 0,..9, I will store in can the chosen candidate , that will be between 0 and 3 except if no candidate is chosen for this destination and in this case, the can variable is set to 4.

This seems compatible to me with the documentation :

if the length of the array f is n, and the length of the array invf is m, then the inverse constraint guarantees that:

for all i in the interval [0,n-1], if f[i] is in [0,m-1], then invf[f[i]]==i;

for all j in the interval [0,m-1], if invf[j] is in [0,n-1], then f[invf[j]]==j.

This is an error in the documentation. In fact, it is always the case that f[invf[i]] == i, which forces m == n too. To get what you want you can create arrays of size n+m and create m escape values on one side and n escape values on the other side. Each real value will have an appropriate escape value, and we add some constraints to ensure that the escape values are used in order (to break unless symmetries between escape values).

Here is the resulting model:

using CP;

int nRalveoles = 10;
int nCandidats = 4; range rcandidats = 0 .. nCandidats-1;
range ralveoles = 0 .. nRalveoles-1;
range R = 0..(nRalveoles + nCandidats)-1;

dvar int alv[R] in R;
dvar int can[R] in R;

constraints {
forall (i in rcandidats)
alv[i] in asSet(ralveoles) union {i + nRalveoles};
forall (i in ralveoles)
can[i] in asSet(rcandidats) union {i + nCandidats};

forall (i in R : i >= nCandidats + 1)
alv[i] < nRalveoles || alv[i] > max(j in nCandidats..i-1) alv[j];
forall (i in R : i >= nRalveoles + 1)
can[i] < nCandidats || can[i] > max(j in nRalveoles..i-1) can[j];

This is the accepted answer.
This is the accepted answer.

This is an error in the documentation. In fact, it is always the case that f[invf[i]] == i, which forces m == n too. To get what you want you can create arrays of size n+m and create m escape values on one side and n escape values on the other side. Each real value will have an appropriate escape value, and we add some constraints to ensure that the escape values are used in order (to break unless symmetries between escape values).

Here is the resulting model:

using CP;

int nRalveoles = 10;
int nCandidats = 4; range rcandidats = 0 .. nCandidats-1;
range ralveoles = 0 .. nRalveoles-1;
range R = 0..(nRalveoles + nCandidats)-1;

dvar int alv[R] in R;
dvar int can[R] in R;

constraints {
forall (i in rcandidats)
alv[i] in asSet(ralveoles) union {i + nRalveoles};
forall (i in ralveoles)
can[i] in asSet(rcandidats) union {i + nCandidats};

forall (i in R : i >= nCandidats + 1)
alv[i] < nRalveoles || alv[i] > max(j in nCandidats..i-1) alv[j];
forall (i in R : i >= nRalveoles + 1)
can[i] < nCandidats || can[i] > max(j in nRalveoles..i-1) can[j];

This is an error in the documentation. In fact, it is always the case that f[invf[i]] == i, which forces m == n too. To get what you want you can create arrays of size n+m and create m escape values on one side and n escape values on the other side. Each real value will have an appropriate escape value, and we add some constraints to ensure that the escape values are used in order (to break unless symmetries between escape values).

Here is the resulting model:

using CP;

int nRalveoles = 10;
int nCandidats = 4; range rcandidats = 0 .. nCandidats-1;
range ralveoles = 0 .. nRalveoles-1;
range R = 0..(nRalveoles + nCandidats)-1;

dvar int alv[R] in R;
dvar int can[R] in R;

constraints {
forall (i in rcandidats)
alv[i] in asSet(ralveoles) union {i + nRalveoles};
forall (i in ralveoles)
can[i] in asSet(rcandidats) union {i + nCandidats};

forall (i in R : i >= nCandidats + 1)
alv[i] < nRalveoles || alv[i] > max(j in nCandidats..i-1) alv[j];
forall (i in R : i >= nRalveoles + 1)
can[i] < nCandidats || can[i] > max(j in nRalveoles..i-1) can[j];