For the Queue ICPC programming game Capture I ran into a geometrical problem.
While programming my little robot I wanted to have an algorithm calculate this for me:

  1. I have a field with 122 points
  2. I have a circle of fixed size

How do I calculate where to put the circle so it encapsulates the most points?

This is what I came up with, three algorithms:

Algorithm #1: Centerpoint

The first algorithm was created as a test. It doesn’t find the perfect solution, but gives a decent solution.
First I loop over all the points, and I check if there are points located at CIRCLE_RADIUS length from our point. This returns a score. The best point has a lot of other points nearby.

This algorithm is very quick, but it has a huge disadvantage, the circle will always have one of our points as center.

It will never yield the perfect solution… In the following picture this algorithm produces the green circle:

Picture of points and three calculated circles

Algorithm #2: Heatmap

The next idea I got was based on a heatmap. It is very computer heavy, but it will generate the best solution.

It works like this (psuedocode):

for( int x = 0 to FIELD_SIZE )
	for( int y = 0 to FIELD_SIZE )
		Point pixel = new Point(x,y);
		pixelScore = 0;
		for( Point point: points ) {
			if( point.distance(pixel) < CIRCLE_RADIUS*2 ) {
				pixelScore++;
			}
		}
	}
}

The pixel with the best score is used in most circles. Thus, this would need to be the center of our circle!

In the image above you can see the resulting heatmap, and the cyan circle is placed on the best possible pixel.

(In most cases, there are more then one ‘best pixels’, which one you choose doesn’t matter)

Algorithm #3: Bron-Kerbosch-myself

The heatmap algorithm, mentioned above, takes a LOT of processing time and is far from the most efficient algorithm. For the Queue ICPC contest there is a time limit for each calculation, and I need it to speed up!

So I started to wonder:

- What do all the points in the perfect circle have in common?

Well, they all have a maximum distance to each other of CIRCLE_RADIUS * 2.

So I started to play with graph algorithms.

The lines you see in the image above are all the points that can be connected with a maximum length of CIRCLE_RADIUS * 2. All the lines show points that could possibly be in the same circle together.
Then I googled a bit and found the term ‘clique‘. A clique is a group of points that all point to each other, just what we want with the graph shown in the picture!

When I searched a little further I came across the Bron-Kerbosch algorithm. It finds the perfect maximum clique for a given undirected graph! Again, just what we want!

Here is the pseudocode (from Wikipedia):

   BronKerbosch1(R,P,X):
       if P and X are both empty:
           report R as a maximal clique
       for each vertex v in P:
           BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
           P := P \ {v}
           X := X ⋃ {v}

But I ran into a little problem, I’d made a false assumption… If you have a triangle of three points, with all legs size N, and then draw a circle from the center… none of the points fall into the circle.

Picture of a circle inside a triangle, where the legs of the triangle are the circle's diameter. This causes all the corners to fall outside the circle.

Now I tried two ways to solve this, the first one is to use a smaller distance in the graph. If you only select points that are located (cosine(30) * CIRCLE_RADIUS * 2) every point will eventually fall into our circle. But this could eliminate the perfect circle obviously if two points in the perfect solution are further apart then (cosine(30) * CIRCLE_RADIUS * 2).

Then I desected the Bron-Kerbosch algorithm, and decided to change it a bit. This is what I ended up with:

   BronKerboschVanRijn(R,P,X):
       if P and X are both empty:
           report R as a maximal clique
       for each vertex v in P:
           BronKerbosch1(R ⋃ {v}, InCircle({R,v}, P), InCircle({R,v}, X))
           P := P \ {v}
           X := X ⋃ {v}

   InCircle(A, B):
       calculate minimal enclosing circle for points A
       return all B that are (euclidean distance) inside A

This returns all the maximal cliques that fall into our circle, and we are always sure they fall into our circle..! I think this will always generate the perfect solution, just as the heatmap. In this the above picture, this algorithm produces the red circle.

It already is lightyears faster then the heatmap algorithm, but I still need a bit more speed. I’m still struggling to improve my implementation, like trying to use a pivot as bronKerbosch2 (see wikipedia again) does.

Algorithm #4: ???

For some reason I still fail to believe I’m the first person in the world to tackle this problem. But I haven’t been able to find an algorithm for this. Some people recommended using a sweeping algorithm but I don’t understand how this is used to find the circle’s location. Others pointed me to Voronoi maps…

So if you have any suggestions, or know the algorithm I’m looking for, please add a comment :-)

Tagged with:
 

3 Responses to Placement of circle over points

  1. Krystof says:

    I believe it can work like this:

    Let’s denote the radius of the wanted circle R, the points we want to encapsulate will be “given points”, number of given points is N. Also let us assume that all the given points are distinct.

    Find a set of points that have distance R from at least two given points. Then one of the optimal circles will have center in one of these points. There is O(N^2) of such points and evaluating each such point takes O(N). This gives us O(N^3) algorithm.
    (When we find no such point, we can obviously encapsulate at most one point, and some center is trivial to find.)

    Why it works?

    If we have a circle encapsulating M points (M>1), there will be a circle encapsulating at least M points with center that lies R far from two points.

    [Proof:
    First for R-distance from one point:

    If we have a circle encapsulating M points whose center doesn't lie R far from any point, we can keep moving it in any direction as long as no point falls out of it. And a point falls out of it only when it was R far from it and now we are moving it further.

    For the second point it is similar -- we are R far from one point (P), and we can move the center point on the circle with center in P and diameter R until some other point slips from our encapsulating circle (to have such point, we need the M>1 condition). This again happens only when a point that was R-far from the center point gets a bit further.]

    BTW the clique finding is NP-complete so in some cases it can be worse than the heatmap algorithm (unless it for some reason isn’t NPC for this kind of graphs, or 122 points is just too little for it to happen)

  2. will says:

    You know I emailed you the code :)

    O(n) if you sweep. In the code I sent, I reordered the sweep to give better best-case performance.

  3. Tom says:

    I would really like to see algorithm that works in O(n) because I use algorithm O(n^2 log n) and it’s too slow.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>