I'm attempting to use Google's OR-Tools to produce a distance constraint between 2x 2D points (p0 & p1).
This becomes the non-linear expression: (p1x - p0x)² + (p1y - p0y)² = d²
I have attempted to produce this with the CP-Sat solver using the following code:
int64_t d = 50;
int64_t d_sq = d*d;
// p0 at (10, 20)
IntVar p0x = cp_model.NewConstant(0);
IntVar p0y = cp_model.NewConstant(0);
// p1 is to be determined by solver
IntVar p1x = cp_model.NewIntVar({ int64_t_min, int64_t_max });
IntVar p1y = cp_model.NewIntVar({ int64_t_min, int64_t_max });
// x1-x0 and y1-y0
IntVar xDif = cp_model.NewIntVar({ -d, d });
IntVar yDif = cp_model.NewIntVar({ -d, d });
cp_model.AddEquality(xDif, p1x - p0x);
cp_model.AddEquality(yDif, p1y - p1y);
// xdif_sq = xdif^2 & ydif_sq = ydif^2
IntVar xDif_sq = cp_model.NewIntVar({ 0, d_sq });obvious solution is to add a tolerance range to d. But I'm having an issue
IntVar yDif_sq = cp_model.NewIntVar({ 0, d_sq });
cp_model.AddMultiplicationEquality(xDif_sq, { xDif, xDif });
cp_model.AddMultiplicationEquality(yDif_sq, { yDif, yDif });
// dif_sq_sum = xdif^2 + ydif^2
IntVar Dif_sq_sum = cp_model.NewIntVar({ 0, 2*d_sq });
cp_model.AddEquality(Dif_sq_sum, xDif_sq + yDif_sq);
// make both sides of equation equal
cp_model.AddEquality(iv_Dif_sq_sum, d_sq);
The problem is that because the solver only accepts integers, it can only calculate the position of p1 when the all parts are integer values.
For example, 3² + 4² = 5² works fine.
But I want to make it work for when a term is non-integer? a² + b² = (almost) c²
The obvious solution is to add a tolerance range to d. But I'm having an issue trying to achieve this as when I do, the status becomes infeasible. Here is the code I've tried.
IntVar iv_Error;
cp_model.AddMultiplicationEquality(iv_Dif_sq_sum, { iv_Error, iv_Error });
cp_model.AddLessThan(iv_Error, d + 1);
cp_model.AddGreaterThan(iv_Error, d - 1);
If anybody has any good suggestions I would be very grateful! Thanks
Cross-posted from https://github.com/google/or-tools/discussions/3220.
The discussion is happening there.