#java #graph #cgal
#java #График #cgal
Вопрос:
я впервые работаю с CGAL, некоторые из вас могут возразить, почему я должен изучать CGAL из чего-то подобного, но это новый проект, который я должен сделать (и … да, я должен использовать CGAL и Java вместе взятые):/ Короче говоря… У меня есть только:
- Два двойных массива, представляющих координаты x и y моих вершин. Давайте назовем их
double[] x, y;
. - Оба массива имеют
S
случайные значения. - Две вершины
u
иw
связаны, еслиdistance(x[u], y[u], x[w], y[w]) < CONSTANT
(ofc. Я делаюdistanceSquared(x[u], y[u], x[w], y[w]) < CONSTANT_SQUARED
, поэтому я избегаю вызывать sqrt()). x
иy
заполняются случайным образом значениями от0
доUPPER_LIMIT
, никакая другая информация не предоставляется.
Вопрос, x
y
описывает ли и связанный граф?
Сейчас у меня есть два алгоритма:
-
Алгоритм 1:
- Создайте список смежности (
Arraylist<Integer>[] adjLists;
) для каждой вершины (исследована только верхняя треугольная матрица). СложностьO(|V|^2)
(V = набор вершин). - Рекурсивное исследование графа, маркировка и подсчет вершин, если посещенная вершина равна
S
моему графу, имеет только один подключенный компонент, мой граф подключен. СложностьO(|E|)
(E = набор ребер).
- Создайте список смежности (
-
Алгоритм 2:
private static boolean algorithmGraph(double[] x, double[] y) { int unchecked, inside = 0, current = 0; double switchVar; while (current <= inside amp;amp; inside != S - 1) { unchecked = inside 1; while (unchecked < S) { if ((x[current] - x[unchecked]) * (x[current] - x[unchecked]) (y[current] - y[unchecked]) * (y[current] - y[unchecked]) <= CONSTANT_SQUARED) { inside ; // switch x coordinates | unchecked <-> inside switchVar = x[unchecked]; x[unchecked] = x[inside]; x[inside] = switchVar; // switch y coordinates | unchecked <-> inside switchVar = y[unchecked]; y[unchecked] = y[inside]; y[inside] = switchVar; } unchecked ; } current ; } return inside == S - 1; }
Забавно, что второй медленнее, я не использую структуры данных, код итеративный и на месте, но интенсивное использование switch делает его чертовски медленным.
Спецификация проблемы изменилась, и теперь я должен сделать это с помощью CGAL и Java, я прочитаю все «https://github.com/CGAL/cgal-swig-bindings » чтобы узнать, как использовать CGAL в Java … но я хотел бы получить некоторую помощь по этому конкретному экземпляру кода CGAL… Существуют ли более быстрые алгоритмы, уже реализованные в CGAL?
Спасибо за ваше время, ребята! Счастливого кодирования!
Комментарии:
1. Мало того, что трудно понять, чего пытается достичь ваш второй алгоритм, но он явно глючит. Проверьте это с
double x[]={1,2,3}
помощью ,double y[]={0,0,0}
,S=2
иCONSTANT_SQUARED=4
— возвращаемое значение равноfalse
, даже если ни одна пара точек не разделена расстоянием> 2. Счастливой отладки, Vento — научитесь писать понятный код, это увеличит ваши шансы написать хороший код.2. Извините, я забыл написать
inside
в if-блоке перед switchVar. Пожалуйста, укажите на это. КстатиS
, это длина массива, поэтому в вашем примере должно быть 3.3. Второй алгоритм пытается создать связанный подграф, вершины от индекса
0
доinside
содержатся в подграфе. Если узел, которого нет в моем подграфе (unchecked
индекс, отinside 1
доS
), должен быть подключен к моему подграфу (проверка диапазона, если блок), я перемещаю этот новый узел внутри моего подграфа, переключая координаты. Условия while — это просто проверка границ и способ ускорить вычисления (еслиinside == S - 1
мой подграф — это весь граф, поэтому граф подключен -> первый while может остановиться).
Ответ №1:
Я считаю, что без метода пространственного индексирования наилучшая производительность, которую вы собираетесь достичь в наихудшем сценарии (все подключено), будет O(n*(n-1)/2)
.
Если вы можете позволить себе создать пространственный индекс (иметь достаточно памяти, чтобы заплатить за повышение скорости), вы можете рассмотреть R-tree и варианты — вставка — это O(n)
поиск O(log2(n))
: это позволит получить ваш подход «обнаружение выбросов путем изучения расстояний» за стоимость O(n*log2(n))
в наихудшем случае.