This is not the best solution probably but and attempt to optimize it.
Algorithm is based on random sampling:
- Generate N circles on the map
- Remove all circles that are not covering any point
- Sort circles descending by number of covered points
- Foreach circle (sorted) - mark points that are covered by circle as covered. If circle is not covering any new points remove from the list.
Here is code you can preview it live: http://jsfiddle.net/rpr8qq4t/ example result (13 circles per 30 points):
Parametrizations:
var POINTS_NUMBER = 30;
var RADIUS = 50;
var SAMPLE_COUNT = 400;
Some optimizations may be added to it (for example some circles can be excluded from the list too early)
Edit:
- Change in step 1 brings better results: Generate N circles for each point (circles that covers at least on point)
New version: http://jsfiddle.net/nwvao72r/3/
Edit 2 (final algorithm)
Finally:
- Foreach point generate N=10 circles in random distance less than R from point (radius of circle so we are sure that for each circle at least one point belongs to it and each point belongs to at least one circle)
- Repeat until all points are covered:
- get circle covering max number of uncovered points. Mark points as covered.
Here is the version that brings best results for me, you can check it here http://jsfiddle.net/nwvao72r/4/
on average 12 circles per 30 points here.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…