Алгоритм поиска окружности с максимальным числом точек (алгоритм углового заметания)
Мне надо реализовать алгоритм, ищущий точку с целочисленными координатами на плоскости, являющуюся центром круга заданного целочисленного радиуса, в который попадает наибольшее количество точек из заданного набора (координаты точек целые).
Следуя совету, данному мне вот тут Как найти координаты окружности данного радиуса, включающей наибольшее число точек? я пытаюсь реализовать описанный там алгоритм.
Вот мои наработки - https://github.com/sltrs1/angular_sweep
Я реализовал наивный алгоритм, который дал мне верный ответ.
Далее я попытался реализовать алгоритм углового заметания (angular sweep), описанный вот здесь https://www.geeksforgeeks.org/angular-sweep-maximum-points-can-enclosed-circle-given-radius/ с некоторыми модификациями.
Модификации следующие: исходный алгоритм исполняется только для заданного набора точек, то есть, ищет подходящий круг с центром в одной из точек заданного множества. Я сделал так, что он исполняется для каждой из всех возможных точек плоскости. То есть, центр круга не обязательно должен быть одной из точек набора.
И вот тут у меня начались проблемы. Второй алгоритм дал результат, отличный от результата наивного алгоритма.
Наивный алгоритм
for(i = 0; i < MAX_POINTS_X; i++) {
for (j = 0; j < MAX_POINTS_Y; j++) {
z1 = (double)i + ((double)j)*I;
for (k = 0; k < num_points; k++) {
dist = cabs(z1 - points[k]);
if (dist <= radius) {
naive_solution[i][j]++;
if ( naive_solution[i][j] > naive_solution_max ) {
naive_solution_max = naive_solution[i][j];
max_i = i;
max_j = j;
}
}
}
}
}
При данных из репозитория и радиусе 10 дает результат 86 точек и круг с центром (44,47).
Угловой алгоритм
for (i = 0; i < num_points; i++) {
z1 = (x+y*I);
if ( cabs(z1 - points[i]) > 0.001 &&
dis[x][y][i] < 2*radius ) {
b = acos( dis[x][y][i]/(2*radius) );
a = carg( z1 - points[i] );
alpha = a-b;
beta = a+b;
angles[angles_count].first = alpha;
angles[angles_count].second = 1;
angles_count++;
angles[angles_count].first = beta;
angles[angles_count].second = 0;
angles_count++;
}
}
for ( i = 0; j < angles_count - 1; i++ ) {
for (j = (int)angles_count - 1; j > i; j--) {
if ( !comparePairs(angles[j-1], angles[j]) ) {
swapPairs( &angles[j-1], &angles[j] );
}
}
}
count = 1;
res = 1;
for (j = 0; j < angles_count; j++) {
if (angles[j].second)
count++;
else
count--;
if (count > res)
res = count;
}
Дает при тех же данных 88 и (42,56).
Почему угловой алгоритм дает другой результат? У меня в реализации ошибка или он просто делает не то же самое, что и наивный?
Буду очень признателен, если кто-то поможет разобраться.