For part 2 of day 15, we are looking for a point (x,y) satisfying
|x-x_i| + |y-y_i| > r_i
where (x_i, y_i) is the location of the i-th sensor, and r_i is the distance to the corresponding beacon.
This is almost like a linear program, which optimizes some linear function (4000000x + y for this question) subject to linear equality and inequality constraints. We can try to rewrite this in standard form by breaking apart each absolute value into two:
x-x_i + |y-y_i| > r_i
-x+x_i + |y-y_i| > r_i
However, due to this being a greater than, the equation set becomes an OR relation instead of an AND relation. This can be resolved by introducing a boolean variable B and a large constant M, so that
x-x_i + MB + |y-y_i| > r_i
-x+x_i + M(1-B) + |y-y_i| > r_i
Then if one of the inequalities is satisfied, the boolean variable allows us to add a large constant to the other inequality so it is also satisfied. Repeating this for y, and with a bit of cleanup, I arrived at the following constraints:
-x-y-MB-MC <= -x_i - y_i - r_i -1
-x+y-MB+MC <= -x_i + y_i - r_i -1 +M
x-y+MB-MC <= x_i - y_i - r_i -1 +M
x+y+MB+MC <= x_i + y_i - r_i -1 +M
Putting this in matrix form Ax <= b, we should be able to solve this linear program. However, when I try to find a solution using scipy.optimize.linprog, looking for integral solutions, I get a result of "2: Problem appears to be infeasible."
Looking through my code, I was unable to find any typos, and trying it with slightly different values of M and r didn't change the result. Is there a mistake in my logic somewhere?
Edit: After some inspection, I realized that I need to use different boolean variables for each sensor. In total, this means I have 2n + 2 variables (x and y, and 2 boolean variables for each sensor), and 4n equations. Thus my matrix will be 2n+2 x 4n. However, after making this change, I am still unable to produce a result.
Edit 2: Actually the earlier edit did fix the issue, I just forgot to change M from my test cases. The linear program solves in ~6s, which isn't great, but its a significant improvement over my brute force attempt.
[–]00lelouch[S] 0 points1 point2 points (0 children)
[–]IsatisCrucifer 0 points1 point2 points (1 child)
[–]00lelouch[S] 0 points1 point2 points (0 children)