Get the square root in an optimisation Or-Tools CP-SAT

94 views Asked by At

In my CP SAT Or-tools optimisation, I need to extract and assign the diagonal (hypotenuse) of a right-angled triangle to an or-tools variable; knowing that x and y of the triangle are known as or-tools integer variables.

The value of the diagonal, rounded to the nearest integer, is suitable in terms of precision.

How can I do this, given that I can't see a solution or a suitable function for extracting the square root of a value?

Thanks in advance,

1

There are 1 answers

2
Laurent Perron On BEST ANSWER

There is some code for that in the spread_robot example.

            x_diff = model.NewIntVar(-room_size, room_size, f"x_diff{i}")
            y_diff = model.NewIntVar(-room_size, room_size, f"y_diff{i}")
            model.Add(x_diff == x[i] - x[j])
            model.Add(y_diff == y[i] - y[j])

            # Compute the square of the previous differences.
            x_diff_sq = model.NewIntVar(0, room_size**2, f"x_diff_sq{i}")
            y_diff_sq = model.NewIntVar(0, room_size**2, f"y_diff_sq{i}")
            model.AddMultiplicationEquality(x_diff_sq, x_diff, x_diff)
            model.AddMultiplicationEquality(y_diff_sq, y_diff, y_diff)

            # We just need to be <= to the scaled square distance as we are
            # maximizing the min distance, which is equivalent as maximizing the min
            # square distance.
            model.Add(scaled_min_square_distance <= scaling * (x_diff_sq + y_diff_sq))

The code in the example only maintain an upper bound of the square root with a given scaling.

You will need to add the inequalities with

    ((min_distance + 1) ^ 2 > scaling * (x_diff_sq + y_diff_sq))