The DBSCAN algorithm is probably what you are looking for.
It's an algorithm that finds clusters of points based on their density.
Since in your case popular means dense, you can use it to solve this task.
It requires two parameters:
- eps, the radius around each point within which to look for other points to form a cluster,
- minPts, the required number of points within the radius around a point to consider the group of nodes as a cluster.
You also need a function to measure the distance between points. Since you have (latitude, longitude) couples (generally in WGS84 format), the Haversize distance is what you need.
There are several implementations of the algorithm. If you are using Java, Apache Commons Math provides a decent implementation (see here for more details and some code snippet). Invoke the DBSCANClusterer
with eps=1.0 (radius of 1 km) and minPts=0 (clusters have 1 or more points). Refer to this answer for implementing the Haversine distance (be sure to match the same measurement unit used for eps). Finally sort the clusters by decreasing size to have them sorted by "popularity":
Collections.sort(clusters, (o1, o2) ->
Integer.compare(o2.getSize(), o1.getSize());
Cluster<? extends Clusterable> mostPopular = clusters.get(0);
If I remember correctly, this implementation solves the problem in quadratic time with respect to its size (the number of points). If all the instances of the problem that you will face has the same size of your example, you will have no problems.