Jest to problem z optymalizacją. Mamy bibliotekę Java typu open source, która rozwiązuje ten problem (grupowanie, w którym ilość na klaster musi znajdować się między ustawionymi zakresami). Będziesz potrzebował maksymalnej liczby punktów maksymalnie kilku tysięcy - nie więcej niż 5000, a może 10000.
Biblioteka jest tutaj:
https://github.com/PGWelch/territorium/tree/master/territorium.core
Sama biblioteka jest skonfigurowana pod kątem problemów związanych z typem geograficznym / GIS - zobaczysz zatem odniesienia do X i Y, szerokości i długości geograficznej, klientów, odległości i czasu itp. Możesz po prostu zignorować elementy „geograficzne” i użyć go jako czystego klaster.
Zapewniasz zestaw początkowo pustych klastrów wejściowych, każdy z minimalną i maksymalną ilością docelową. Klaster przypisze punkty do twoich klastrów wejściowych, używając heurystycznego algorytmu optymalizacji (swapy, ruchy itp.). W optymalizacji optymalizuje przede wszystkim utrzymanie każdego skupiska w zakresie minimalnej i maksymalnej ilości, a następnie minimalizuje odległości między wszystkimi punktami skupienia i centralnym punktem skupienia, aby skupisko było spójne przestrzennie.
Nadajesz solverowi funkcję metryczną (tj. Funkcję odległości) między punktami za pomocą tego interfejsu:
https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/TravelMatrix.java
Metryka jest tak skonstruowana, aby zwracała zarówno odległość, jak i „czas”, ponieważ została zaprojektowana z myślą o problemach geograficznych związanych z podróżą, ale w przypadku dowolnych problemów związanych z klastrowaniem wystarczy ustawić „czas” na zero, a odległość jest faktyczną metryką, której używasz między zwrotnica.
Skonfigurowałbyś swój problem w tej klasie:
https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/Problem.java
Twoje punkty to „Klienci”, a ich liczba to 1. W klasie klientów upewnij się, że ustawiłeś costPerUnitTime = 0 i costPerUnitDistance = 1, zakładając, że zwracasz swoją odległość metryczną w polu „odległość” zwróconym przez TravelMatrix.
https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/Customer.java
Zobacz tutaj przykład uruchamiania solvera:
https://github.com/PGWelch/territorium/blob/master/territorium.core/src/test/java/com/opendoorlogistics/territorium/TestSolver.java