Quantcast
Channel: Yet Another Math Programming Consultant
Viewing all articles
Browse latest Browse all 804

Tiny non-convex quadratic model brings solvers to their knees

$
0
0

Here is a very small geometric problem:

Given \(n\) points in 2d space, find the smallest triangle that contains all these points.


Find the smallest triangle containing all points.


This looks like a simple problem. Somewhat to my surprise, my attempt here does not bear that out.

To model this, we need to address two issues:

  1. Calculate the area of a triangle,
  2. Make sure all data points are inside the triangle.

Area of a triangle


Assuming our triangle has corner points \((\color{darkred}x_1,\color{darkred}y_1)\), \((\color{darkred}x_2,\color{darkred}y_2)\) and \((\color{darkred}x_3,\color{darkred}y_3)\), the determinant formula for the area is: \[\color{darkred}A = 0.5 \> {\mathbf{abs}} \> {\mathbf{det}}\begin{bmatrix}\color{darkred}x_1 & \color{darkred}y_1 & 1\\\color{darkred}x_2 & \color{darkred}y_2 & 1 \\ \color{darkred}x_3 & \color{darkred}y_3 & 1\end{bmatrix}\] This can be written as: \[\color{darkred}A=0.5 \cdot |\color{darkred}x_1(\color{darkred}y_2-\color{darkred}y_3) + \color{darkred}x_2(\color{darkred}y_3-\color{darkred}y_1) + \color{darkred}x_3(\color{darkred}y_1-\color{darkred}y_2)|\] The absolute value can be linearized easily. What remains is a non-convex quadratic expression.


Points must be inside the triangle


Here I used a concept called barycentric coordinates [1]. If we can form weights \(\color{darkred}\lambda_k\) such that \[\begin{align}& \color{darkblue}p = \sum_k \color{darkred}\lambda_k \cdot \color{darkred}t_k \\ & \color{darkred}\lambda_k \ge 0 \\ & \sum_k \color{darkred}\lambda_k = 1 \end{align}\] then point \(\color{darkblue}p\) is inside the triangle formed by corner points \(\color{darkred}t_k\). This again introduces a non-convex quadratic expression as both \(\color{darkred}\lambda_k\), and \(\color{darkred}t_k\) are endogenous (i.e. variables). Note that \(\color{darkblue}p\) and \(\color{darkred}t_k\) are two-dimensional, while \(\color{darkred}\lambda_k\) are scalars.


Optimization model


Putting these two things together, we arrive at our optimization model:

 

Smallest triangle model
\[\begin{align}\min\> & \color{darkred}A^+ + \color{darkred}A^- \\ & \color{darkred}A^+ - \color{darkred}A^- = 0.5 \cdot \left[\color{darkred}t_{1,x}(\color{darkred}t_{2,y}-\color{darkred}t_{3,y}) + \color{darkred}t_{2,x}(\color{darkred}t_{3,y}-\color{darkred}t_{1,y}) + \color{darkred}t_{3,x}(\color{darkred}t_{1,y}-\color{darkred}t_{2,y}) \right] \\ & \color{darkblue}p_{i,c} = \sum_k \color{darkred}\lambda_{i,k} \cdot \color{darkred}t_{k,c} && \forall i,c\\ &  \sum_k \color{darkred}\lambda_{i,k} = 1 && \forall i \\ & \color{darkred}A^+, \color{darkred}A^- \ge 0 \\ & \color{darkred}\lambda_{i,k} \ge 0 \\ & \color{darkred}t_{k,c}\> {\mathbf{free}}\\ & c \in \{x,y\}\\ & k\in \{1,2,3\}\\ & i \in \{1,\dots,n\}\end{align}\]

A special case is \(n=3\). We know the optimal solution for this: make the corner points of the triangle equal to the three data points. I would expect this to be fairly easy. We have a non-convex quadratic problem with just 17 variables. We can solve this with a global NLP solver (e.g. Baron, SCIP, Antigone, Octeract) or with a global quadratic solver (Gurobi). All these solvers find the optimal solution very quickly, but proving optimality is extremely difficult. Solving to proven optimality takes hours!

The picture at the top used \(n=25\) points. The data and solution for this data set is:

----     76 PARAMETER pdata points

x y

point1 17.17584.327
point2 55.03830.114
point3 29.22122.405
point4 34.98385.627
point5 6.71150.021
point6 99.81257.873
point7 99.11376.225
point8 13.06963.972
point9 15.95225.008
point10 66.89343.536
point11 35.97035.144
point12 13.14915.010
point13 58.91183.089
point14 23.08266.573
point15 77.58630.366
point16 11.04950.238
point17 16.01787.246
point18 26.51128.581
point19 59.39672.272
point20 62.82546.380
point21 41.33111.770
point22 31.4214.655
point23 33.85518.210
point24 64.57356.075
point25 76.99629.781


---- 76 VARIABLE t.L triangle

x y

corner1 -1.25893.363
corner2 17.810 -10.334
corner3 136.18369.896


---- 76 VARIABLE area.L area (using variable splitting)

+ 6902.407


---- 76 VARIABLE lambda.L barycentric coordinates

corner1 corner2 corner3

point1 0.8150.0590.126
point2 0.1300.5340.336
point3 0.2140.6550.131
point4 0.7230.0150.262
point5 0.5820.418
point6 0.1080.1820.710
point7 0.2700.730
point8 0.6650.2680.067
point9 0.3140.6510.035
point10 0.1770.3800.443
point11 0.2840.5160.199
point12 0.2440.756
point13 0.5620.438
point14 0.6290.2250.146
point15 0.0020.4930.505
point16 0.5590.4080.033
point17 0.8470.0320.121
point18 0.2830.5980.119
point19 0.4670.1070.426
point20 0.2250.3590.416
point21 0.0530.7400.207
point22 0.0490.8280.123
point23 0.1520.6890.160
point24 0.2980.2590.443
point25 0.5000.500


 

Extensions


Initially, I wanted to solve a cover problem with multiple triangles: given \(n\) data points, find a set of \(m\) triangles that cover all points while minimizing the total area of the triangles. After this experiment, I probably should forget about that. 


Conclusion


This problem is, at first sight, not very difficult. However, we need to implement a few geometric concepts that are not obvious. The result is a non-convex quadratic model. Solvers find good (or optimal) solvers very quickly. Proving optimality is a very different thing: this turns out to be extremely difficult.

The remaining questions, of course, are: is this a really bad formulation? Any better ones around? Can we explain why the lowerbound remains at 0 until the tree has been fully explored?

References


  1. Barycentric coordinate system, https://en.wikipedia.org/wiki/Barycentric_coordinate_system


Appendix: GAMS model


$onText

 

  Given are n points (2d).

  Find smallest triangle that contains all points.

 

$offText

 

*---------------------------------------------------------------------

* data: points

*---------------------------------------------------------------------

 

set

   i 'points'   /point1*point25/

   'coordinates' /x,y/

;

 

parameter p(i,c'data points';

p(i,c) = uniform(0,100);

 

*---------------------------------------------------------------------

* find smallest triangle to contain all points

*---------------------------------------------------------------------

 

 

sets

   k  'corner points of triangle' /corner1*corner3/

   pm 'plusmin -- used in linearizing abs()' /'+','-'/

;

 

shorthands to make our area calculation easier

singleton sets

   x1(k,c) /'corner1'.'x'/

   x2(k,c) /'corner2'.'x'/

   x3(k,c) /'corner3'.'x'/

   y1(k,c) /'corner1'.'y'/

   y2(k,c) /'corner2'.'y'/

   y3(k,c) /'corner3'.'y'/

;

  

 

variable

   t(k,c)  'triangle'

   z       'objective'

;

 

positive variable

   area(pm)     'area (using variable splitting)'

   lambda(i,k)  'barycentric coordinates'

;

 

equations

   calcArea         'calculate area given its three corner points'

   calcLambda(i,c)  'solve for barycentric coordinates'

   sumLambda(i)     'lambdas need to add up to one'

   obj              'objective'

   order            'order corner points by their x coordinate'

;

 

calcArea..         area('+')-area('-') =e= 0.5*[t(x1)*(t(y2)-t(y3)) + t(x2)*(t(y3)-t(y1)) + t(x3)*(t(y1)-t(y2))];

calcLambda(i,c)..  p(i,c) =e= sum(k, lambda(i,k)*t(k,c));

sumLambda(i)..     sum(k, lambda(i,k)) =e= 1;

obj..              z =e= sum(pm,area(pm));

order(k-1)..       t(k,'x') =g= t(k-1,'x');

 

 

* some reasonable bounds

t.lo(k,c) = -1000;

t.up(k,c) = +1000;

 

 

model m /all/;

option nlp=baron, threads=0, reslim=1000;

solve m minimizing z using nlp;

 

* data + results

display p,t.l,area.l,lambda.l;

 

 

Note that an ordering constraint has been added. Not sure if it helps.


Viewing all articles
Browse latest Browse all 804

Trending Articles