powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Зарядка для ума ( алгоритмическая задача)
14 сообщений из 39, страница 2 из 2
Зарядка для ума ( алгоритмическая задача)
    #38389374
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаР,
Вас интересует решение на сфере (эллипсоиде, геоиде, ...) или на плоскости тоже подойдет?
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389411
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDДохтаР,
Вас интересует решение на сфере (эллипсоиде, геоиде, ...) или на плоскости тоже подойдет?


Это не реальная задача , во времени на размышления ограничений нет , любое решение подходит.
И чем больше будет вариантов, тем больше будет возможность выбрать самое оптимальное с точки зрения получени конечного результати и поиска компромисов ресурсы-производительность.

Единстенное ограничение, запрещено одновременное хранение
всех возможных вариантов ( декартового произведения обьектов ),
кроме случая когда его создание есть решением задачи.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389448
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDДохтаР,
Вас интересует решение на сфере (эллипсоиде, геоиде, ...) или на плоскости тоже подойдет?

В общем случае на плоскости , как самое простое , если оно буде масштабироваться
на N мерные пространства, то его автор может смело писать резюме
в гугл, яндекс или боинг со ссылкой на этот топик.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389492
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Могут быть ошибки, но в целом идея, думаю, понятна.
Как-то так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
        /* Представим себе матрицу с целочисленными индексами,
        в которой хранятся точки. P[i, j]

        Для любых двух точек A и B с индексами в матрице
                (Ai, Aj) и (Bi, Bj) должно выполняться следующее:

        Если Ai <= Bi Тогда A.x <= B.x;
        Если Aj <= Bj Тогда A.y <= B.y;

        То есть, матрица отсортирована по возрастанию x и y.

        Таким образом, любая прямоугольная область между точками
        на плоскости соотвествует прямоугольной области в матрице.
        */

        Matrix<Point2D.Double> P = new Matrix<Point2D.Double>();
        // Как-то мы эту матрицу заполнили.

        final double maxInflRadius = 0;
        final double maxInflRadius2 = 2 * maxInflRadius;
        // В процессе заполнения уже определили максимальный радиус влияния

        // А теперь алгоритм отбора точек для вычисления расстояния.

        final int columnCount = P.columnCount();
        final int rowCount = P.rowCount();
        Point2D.Double A, B;

        boolean continueRowScan;
        boolean continueColumnScan;
        int Bi, Bj;

        for (int Aj = 0; Aj < rowCount; ++Aj) {
            for (int Ai = 0; Ai < columnCount; ++Ai) {

                A = P.get(Ai, Aj);


                /* Каждую точку будем сравнивать только с точками
                из того же столбца или правее, и из той же строки или ниже.
                Так исключаются избыточные пары сравнений (A, B) и (B, A).
                */
                Bj = Aj;
                continueColumnScan = true;

                while (continueColumnScan && Bj < rowCount) {
                    Bi = Ai;
                    continueRowScan = true;

                    while (continueColumnScan && continueRowScan && Bi < columnCount) {
                        // Если это не одна и та же точка
                        if (Bi != Ai || Bj != Aj) {
                            B = P.get(Bi, Bj);

                            if (B.x - A.x > maxInflRadius2) {
                                continueRowScan = false;
                            }

                            if (B.y - A.y > maxInflRadius2) {
                                continueColumnScan = false;
                            }

                            if (continueColumnScan && continueRowScan
                                    && B.x - A.x + B.y - A.y <= maxInflRadius2) {

                                // Вычислить расстояние, и произвести действия, если есть пересечение.
                            }
                        }

                        ++Bi;
                    }

                    ++Bj;
                }
            }

        }
    }



Осталось придумать, как хранить такую матрицу в разреженном виде и как ее изначально заполнить.

Пошел устраиваться в Гугл...
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389575
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDМогут быть ошибки, но в целом идея, думаю, понятна.
Как-то так:

Код: java
1.
2.
3.
4.
                /* Каждую точку будем сравнивать только с точками
                из того же столбца или правее, и из той же строки или ниже.
                Так исключаются избыточные пары сравнений (A, B) и (B, A).
                */



Осталось придумать, как хранить такую матрицу в разреженном виде и как ее изначально заполнить.

Пошел устраиваться в Гугл...

Хранение декартового произведения обьектов вы заменили на факториал итераций цикла.
Формально это постановку не нарушает ,
но Ваше решение нельзя назвать оптимальным для массива из 6000 обьектов.

Например, зачем ганять все итерации цикла ,
для случая когда зона влияния в одной из точек покрывает всю матрицу целяком.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389606
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРХранение декартового произведения обьектов вы заменили на факториал итераций цикла.
Здесь нет факториала итераций цикла. Вообще непонятно, откуда взялся факториал.

Если дано n точек, самый тупой алгоритм (с декартовым произведением) будет иметь сложность O(n^2) (O от n в квадрате).

Действительно, в худшем случае, мой алгоритм имеет такую же сложность, но может быть лучше,
если зоны влияния точек находятся не все вместе рядом, а разбиты на относительно удаленные группы.

ДохтаРНапример, зачем ганять все итерации цикла ,
для случая когда зона влияния в одной из точек покрывает всю матрицу целяком.
Для любого алгоритма в худшем случае сложность будет O(n^2), это случай, когда абсолютно все зоны влияния попарно пересекаются. И тогда обязательно гонять цикл по максимуму.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389612
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРНапример, зачем ганять все итерации цикла ,
для случая когда зона влияния в одной из точек покрывает всю матрицу целяком.
Кроме того, приведенные пример, непонятен (видимо вы неверно поняли задачу).

Даже если зона влияния одной из точек покрывает всю матрицу,

Из исходной задачи:
evgenius_bТребуется получить перечень пар всех взаимовлияющих объектов по принципу: расстояние между парой объектов не более, чем сумма их максимальных зон влияния.

Предположим, есть точки, A, B, C, D. И зона точки A покрывает всю матрицу.
Тогда все равно требуется найти, пересекаются ли зоны влияния точек B и C, B и D, C и D.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389614
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаР,
Но кое в чем вы правы, мой алгорим можно улучшить.
Сейчас он отсекает точки, когда они гарантированно не пересекаются.
А можно по другой ветке обрабатывать точки, когда они гарантированно пересекаются.
И вычислять расстояния, только для пар, попадающих в сомнительную зону.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389647
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDДохтаР,
Но кое в чем вы правы, мой алгорим можно улучшить.
Сейчас он отсекает точки, когда они гарантированно не пересекаются.
А можно по другой ветке обрабатывать точки, когда они гарантированно пересекаются.
И вычислять расстояния, только для пар, попадающих в сомнительную зону.

Да , похожий подход к алгоритмическому решению как один из вариантов я предполагал ранее
14804926
ДохтаРалгоритмика выбора начинала перебора вариантов , от минимального растояния между точками или или от максимальной площади области вляния ?
зы с таким ходом мыслей есть шанс изобрести велосипед на тему стоимостного оптимизатора



Что бы получать пары на первых итерациях, а в лучшем случае прекратить перебор
по кондишину.

При равномероном распределении зон влияния по площади ,
придется перебирать все варианты,
в плодь пополучения декартового произведения обьектов. в качестве результата в самом худшем случае.

Исходя из этого у меня возникла мысль ,
пердварительно посчитать сумму площадей зон влияния и сравнить с площадью прямоугольника на котором расположены точки.

Это можно сделать достаточно быстро,
и имперически оценить насколько долгим может быть полный расчет пар.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38389667
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTID
HoBTIDТаким образом, любая прямоугольная область между точками
на плоскости соотвествует прямоугольной области в матрице.



Если дано n точек, самый тупой алгоритм (с декартовым произведением) будет иметь сложность O(n^2) (O от n в квадрате).



Хочу обратить ваше внимание, что цикл у вас не по точкам, а по масштабной сетке
мартицы.

n =6000 точек в матрице 100500 Х 100500 имеет сложность чуть :) больше O(n^2) (O от n в квадрате).
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38406191
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это ж вроде классическая задача для BSP? делим "пространство" пополам, точки, целиком попадающие в проверяем только с соседями по "половинке"
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38406302
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманЭто ж вроде классическая задача для BSP? делим "пространство" пополам, точки, целиком попадающие в проверяем только с соседями по "половинке"


Пространства в постановке нет , есть только координаты множества точек.
Воссозавать все пространство из мax(X) max(Y) я считаю не совсем оптимальным решением.
Координаты могуть быть неравномерно распределены по пространству.
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38406325
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРВоссозавать все пространство из мax(X) max(Y) я считаю не совсем оптимальным решением.
1 проход
ДохтаРКоординаты могуть быть неравномерно распределены по пространству. для этого и придуман BSP

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Bsp {

    public static void main(String... args) {
        List<Point> points = new ArrayList<Point>();
        points.add(new Point(0, 0, 0, 2));
        points.add(new Point(1, 3, 0, 2));
        points.add(new Point(2, 4, 0, 1));

        Node node = new Node(points);
        node.collide();
    }

    public static void collide(Point other, Point point) {
        if (point.collides(other))
            System.out.println(point.id + " " + other.id);
    }
}

class Point {
    public final int id;
    public final double x, y, r;

    Point(int id, double x, double y, double r) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.r = r;
    }

    public boolean isBound(double left, double top, double right, double bottom) {
        return x - r >= left && x + r < right && y - r >= top && y + r < bottom;
    }

    public boolean collides(Point other) {
        double dx = x - other.x;
        double dy = y - other.y;
        double dr = r + other.r;
        return dx * dx + dy * dy < dr * dr;
    }
}

class Node {
    private List<Point> points;
    private final double l, t, r, b;
    private Node n1;
    private Node n2;

    public Node(Collection<Point> allPoints) {
        double l = Double.MAX_VALUE, t = Double.MAX_VALUE, r = -Double.MAX_VALUE, b = -Double.MAX_VALUE;
        for (Point point : allPoints) {
            l = Math.min(point.x - point.r, l);
            r = Math.min(point.x + point.r, r);
            t = Math.min(point.y - point.r, t);
            b = Math.min(point.y + point.r, b);
        }
        this.l = l;
        this.t = t;
        this.r = r;
        this.b = b;
        split(allPoints);
    }

    public Node(double l, double t, double r, double b) {
        this.l = l;
        this.t = t;
        this.r = r;
        this.b = b;
    }

    public void collide() {

        for (int i = 0, j = points.size(); i < j; i++) {
            Point point = points.get(i);
            for (int k = i+1; k < j; k++)
                Bsp.collide(point, points.get(k));

            if (n1 != null) n1.collide(point);
            if (n2 != null) n2.collide(point);
        }
        if (n1 != null) n1.collide();
        if (n2 != null) n2.collide();
    }

    private void collide(Point other) {
        for (Point point : points)
            Bsp.collide(other, point);
    }



    public void split(Collection<Point> pts) {
        points = new ArrayList<Point>();
        Node n1;
        Node n2;
        if (r - l > b - t) {
            n1 = new Node(l, t, (l + r) / 2, b);
            n2 = new Node((l + r) / 2, t, r, b);
        } else {
            n1 = new Node(l, t, r, (b + t) / 2);
            n2 = new Node(l, (b + t) / 2, r, b);
        }

        List<Point> list1 = new ArrayList<Point>();
        List<Point> list2 = new ArrayList<Point>();

        for (Point point : pts) {
            if (n1.contains(point))
                list1.add(point);
            else if (n2.contains(point))
                list2.add(point);
            else
                points.add(point);
        }

        if (list1.size() > 0) {
            n1.split(list1);
            this.n1 = n1;
        }

        if (list2.size() > 0) {
            n2.split(list2);
            this.n2 = n1;
        }
    }

    public boolean contains(Point point) {
        return point.isBound(l, t, r, b);
    }
}
...
Рейтинг: 0 / 0
Зарядка для ума ( алгоритмическая задача)
    #38406346
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
алсо в моём коде можно значительно упростить доставку Point до конечного узла bsp, и избежать всяких там worst case, когда мало точек остается в текущем узле
...
Рейтинг: 0 / 0
14 сообщений из 39, страница 2 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Зарядка для ума ( алгоритмическая задача)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]