Ответ 1
Третий подход может быть комбинацией обоих и лениво оценивает матрицу расстояний. Инициализируйте матрицу со значениями по умолчанию (нереалистичными значениями, например отрицательными), и когда вам нужно рассчитать расстояние между двумя точками, если значения уже присутствуют в матрице - просто возьмите ее. В противном случае вычислите его и сохраните в матрице.
Этот подход обрабатывает вычисления (и является оптимальным при выполнении самого низкого числа возможных парных вычислений), для большего количества ветвей в коде и еще нескольких инструкций. Однако из-за отраслевых предсказателей я предполагаю, что эти накладные расходы не будут такими драматичными.
Я предсказываю, что он будет иметь лучшую производительность, если расчет будет относительно экспансивным.
Другая оптимизация может заключаться в том, чтобы динамически переключаться на реализацию простой матрицы (и вычислять оставшуюся часть матрицы), когда число уже рассчитанных превышает определенный порог. Это может быть достигнуто довольно хорошо на языках ООП, путем переключения реализации интерфейса при достижении определенного порога.
На самом деле лучшая реализация будет в значительной степени зависеть от стоимости функции расстояния и данных, которые вы кластеризуете, поскольку некоторым нужно будет вычислять одни и те же точки чаще, чем другие наборы данных.
Я предлагаю сделать тест и использовать статистические инструменты, чтобы оценить, какой метод на самом деле лучше.