Je suis également presque sûr que le problème est NP-Hard, le problème le plus similaire que j'ai trouvé est celui de la Problème du k-centre . Si le temps d'exécution est plus important que l'exactitude, un algorithme gourmand est probablement votre meilleur choix :
Q ={}
while |Q| < k
Q += p from S where mindist(p, Q) is maximal
Remarque : dans des problèmes similaires, par exemple le le problème de la couverture de l'ensemble il est possible de montrer que la solution de l'algorithme glouton est au moins 63% aussi bonne que la solution optimale.
Afin d'accélérer les choses, je vois 3 possibilités :
-
Indexez votre ensemble de données dans un R-Tree d'abord, puis effectuer une recherche gourmande. La construction du R-Tree est O(n log n), mais bien qu'il soit développé pour la recherche du plus proche voisin, il peut également vous aider à trouver le point le plus éloigné d'un ensemble de points en O(log n). Cela peut être plus rapide que l'algorithme naïf O(k*n).
-
Echantillonnez un sous-ensemble de vos 16 millions de points et exécutez l'algorithme glouton sur ce sous-ensemble. Comme il s'agit de toute façon d'une approximation, vous pourrez peut-être faire l'économie d'un peu plus de précision. Vous pouvez également combiner cette méthode avec l'algorithme 1.
-
Utilisez une approche itérative et arrêtez-vous lorsque vous manquez de temps. L'idée ici est de sélectionner aléatoirement k points dans S (appelons cet ensemble Q'). Ensuite, à chaque étape, vous échangez le point p_ de Q' qui a la distance minimale à un autre point de Q' avec un point aléatoire de S. Si l'ensemble résultant Q'' est meilleur, continuez avec Q'', sinon répétez avec Q'. Pour ne pas rester bloqué, vous pouvez choisir un autre point de Q' que p_ si vous n'avez pas trouvé de remplacement adéquat après quelques itérations.