Вот примерное решение. Поскольку N так велико, а M так мало, как насчет следующего:
- Вычислить выпуклую оболочку N
- Выберите до M точек от корпуса, которые удовлетворяют вашим критериям максимального расстояния.
- Если на шаге 2 у вас меньше M точек, выберите 1 точку изнутри, которая максимизирует расстояние от ранее выбранных точек.
- Повторите шаг 3, пока количество выбранных точек не станет М
Интуиция в этом заключается в том, что, поскольку N >> M , и вы хотите, чтобы точки были как можно дальше друг от друга, они, вероятно, будут близки к краям данных, поэтому вы могли бы также начать с корпуса, а затем итеративно пробейся оттуда.
Также, начиная с корпуса, вы уменьшаете начальный поиск с N до N 1/2 .
ОБНОВИТЬ
Если шаги 3 и 4, описанные выше, занимают слишком много времени (поскольку вы итеративно тестируете внутреннюю часть своего набора данных), мне пришло в голову еще две идеи, чтобы ускорить вашу проблему.
- Рандомизированный поиск : скажем, вы нашли P точек на корпусе на шаге 2. Затем случайным образом нарисуйте M - P точек изнутри. Выберите лучший набор после X испытаний.
- Имитация отжига : вычисление наименьшего ограничивающего прямоугольника, который покрывает ваш набор данных (не обязательно должен быть выровнен с осями, может быть наклонен). Затем определите набор из M равномерно распределенных точек сетки на этой ограничительной рамке. Обратите внимание, что эти точки не обязательно совпадают ни с одной из ваших точек набора данных. Затем для каждой точки сетки найдите k- ближайших соседей в вашем наборе данных. Пройдите каждую комбинацию M x k и выберите ту, которая удовлетворяет вашим критериям максимального расстояния. Другими словами, вы используете начальную сетку в качестве начальной загрузки, чтобы найти хорошее начальное решение.