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

Circle Packing and HTML reporting

$
0
0

Little example. Here, we try to pack \(n\) circles with a given radius \(r_i\) into a larger disc with an unknown radius \(R\). The goal is to minimize \(R\). The underlying model is simple: 

Packing of Circles
\[\begin{align} \min\> & \color{darkred}R \\ & \sum_c \left(\color{darkred}p_{i,c}-\color{darkred}p_{j,c}\right)^2 \ge \left(\color{darkblue}r_i+\color{darkblue}r_j\right)^2 & \forall i\lt j \\ & \sum_c p_{i,c}^2 \le \left(\color{darkred}R-\color{darkblue}r_i\right)^2 & \forall i \\ & \color{darkred}R \ge 0\\ & c \in \{x,y\} \\ \end{align}\]

The first constraint says that inner circles cannot overlap. The second constraint states that inner circles should be inside the outer disc. These types of models are very difficult for global solvers. However, very good solutions can be found using a simple multistart NLP approach: solve a number of trials with a random starting point.

Of course, we need some visualization to assess the results. Here, I use simple HTML and SVG, which is easy to generate. The results look like:


The GAMS model looks like:

$onText

 

   Pack n circles of given radius

   within a disc. Minimize the

   size of this disc.

 

   This problem has nonconvex quadratic constraints.

  

$offtext

 

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

data

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

 

set

  i 'circles' /circle1*circle50/

;

 

parameter radius(i'lognormally distributed';

radius(i) = exp(1+normal(0,0.5));

display radius;

 

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

additional sets

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

 

alias (i,j);

sets

   ij(i,j'compare i<j'

   'coordinates' /x,y/

;

ij(i,j) = ord(i)<ord(j);

display ij;

 

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

model

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

variables

   'radius of outer circle'

   p(i,c'position'

;

 

r.lo = 0;

 

Equations

  overlap(i,j'no-overlap'

  inside(i)    'inside outer circle'

;

 

overlap(ij(i,j))..

    sum(c, sqr(p(i,c)-p(j,c))) =g= sqr(radius(i)+radius(j));

 

inside(i)..

    sum(c, sqr(p(i,c))) =l= sqr(r-radius(i));

 

model pack /all/;

 

option nlp=conopt;

p.l(i,c) = uniform(-20,20);

r.l = 100;

solve pack minimizing r using nlp;

display p.l,r.l;

 

abort$(pack.modelstat <> %modelStat.locallyOptimal%) "no solution";

 

 

parameter solutions(*,*,*);

solutions('Single',i,c) = p.l(i,c);

solutions('Single',i,'r') = radius(i);

solutions('Single','outer','r') = r.l;

display solutions;

 

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

multistart approach

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

 

set trials /trial1*trial25/;

turn off info written to listing file

pack.solprint = 2;

 

scalar bestr /inf/;

 

loop(trials,

  p.l(i,c) = uniform(-10,10);

  r.l = 100;

  solve pack minimizing r using nlp;

  continue$(pack.modelstat <> %modelStat.locallyOptimal%);

  if (r.l<bestr,

     bestr = r.l;

     solutions(trials,'outer','r') = r.l;

     solutions('Multistart',i,c) = p.l(i,c);

     solutions('Multistart',i,'r') = radius(i);

     solutions('Multistart','outer','r') = r.l;

  );  

);

 

display solutions;

 

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

global solver can do this in one solve

this is a difficult model for global

solvers.

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

$ontext

option nlp=baron;

solve pack minimizing r using nlp;

$offtext

 

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

plot results

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

$set htmlfile 'result.html'

scalar k,n,r0;

file f /%htmlfile%/;

put f;

n = card(i);

k = card(trials);

 

r0 = solutions('single','outer','r');

set run / Single, Multistart/;

 

put '<h1>Results of Circle Packing Model</h1>'/;

put "<p>Pack ",n:0:0," circles with given radii in a container."

    " We minimize the size of the outer disc. The multistart algorithm"

    " used ",k:0:0," trials.</p>";

   

put "<table><tr>"/;

 

loop(run,

   put '<td><svg width="400" height="300" viewBox="',

        (-1.1*r0):0:3,',(-1.1*r0):0:3,'',(2.2*r0):0:3,'',(2.2*r0):0:3,'">'/;

   put '<circle cx="0" cy="0" r="',solutions(run,'outer','r'):0:3,'"/>'/;

  

   loop(i,

        put '<circle cx="',solutions(run,i,'x'):0:3,

                  '" cy="',solutions(run,i,'y'):0:3,

                  '" r="',solutions(run,i,'r'):0:3,

                  '" fill="darkorange"/>'/;

   );

  

   put "</svg><p><center>",run.tl," solve. Outer radius:",

       solutions(run,'outer','r'):0:3,"</center></p></td>"/;

);

 

put "</tr></table>"/;

putclose;

executeTool 'win32.ShellExecute "%htmlfile%"'

 

An advantage of generating HTML is that it does not require installing special software. In some corporate environments, this can be a big plus. An obvious improvement is to solve the subproblems in a parallel fashion. GAMS has a so-called scenario solver. Unfortunately, it does not have any capabilities to provide different initial values, so it is not very useful for this case. 


Viewing all articles
Browse latest Browse all 51

Trending Articles