Обнаружение пересечения области по точкам [дубликат]

Хорошо, позвольте мне объяснить концепцию очень простыми словами.

Во-первых, с более широкой точки зрения у нас есть коллекции, а hashmap является одной из данных в коллекциях.

To понять, почему мы должны переопределять оба метода equals и hashcode, если вам нужно сначала понять, что такое hashmap и что делает.

Хеш-карта - это структура данных, в которой хранятся пары значений ключа в массиве. Давайте скажем [], где каждый элемент в 'a' является парой значений ключа.

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

Теперь почему используется хэшмап? Если нам нужно искать среди большого массива, то поиск по каждому из них, если они не будут эффективными, так что хэш-метод говорит нам, что позволяет предварительно обрабатывать массив с некоторой логикой и группировать элементы на основе этой логики, т. Е. Hashing

, например: у нас есть массив 1,2,3,4,5,6,7,8,9,10,11, и мы применяем хеш-функцию mod 10, поэтому 1,11 будут сгруппированы вместе. Поэтому, если бы нам пришлось искать 11 в предыдущем массиве, нам пришлось бы перебирать полный массив, но когда мы группируем его, мы ограничиваем объем итераций, тем самым улучшая скорость. Эта структура данных, используемая для хранения всей вышеприведенной информации, может рассматриваться как 2d-массив для простоты

. Теперь помимо вышеизложенного hashmap также говорит, что он не добавит в него никаких дубликатов. И это главная причина, по которой мы должны переопределить значения equals и hashcode

. Поэтому, когда в его объяснении объясняется внутренняя работа hashmap, нам нужно найти, какие методы имеет hashmap, и как это следует за приведенным выше правила, которые я объяснил выше

, поэтому в hashmap есть метод, называемый put (K, V), и в соответствии с hashmap он должен следовать приведенным выше правилам эффективного распределения массива и не добавлять никаких дубликатов

, так что put put is состоит в том, что он сначала сгенерирует хэш-код для данного ключа, чтобы решить, какой индекс должен иметь значение. Если в этом индексе ничего не присутствует, тогда добавляется новое значение, если что-то уже присутствует там, тогда новое значение должно быть добавлено после окончания связанного списка по этому индексу. но не помните, что дубликаты не должны добавляться в соответствии с желаемым поведением хэш-карты. поэтому давайте предположим, что у вас есть два объекта Integer aa = 11, bb = 11. как каждый объект, полученный из класса объекта, реализация по умолчанию для сравнения двух объектов заключается в том, что она сравнивает ссылку, а не значения внутри объекта. Таким образом, в приведенном выше случае оба семантически равных будут терпеть неудачу в тесте равенства и возможность того, что будут существовать два объекта, один и тот же хэш-код и одинаковые значения, что создает дубликаты. Если мы переопределим, мы могли бы избежать добавления дубликатов. Вы также можете обратиться к Подробности работы

import java.util.HashMap;


public class Employee {

String name;
String mobile;
public Employee(String name,String mobile) {
    this.name=name;
    this.mobile=mobile;
}

@Override
public int hashCode() {
    System.out.println("calling hascode method of Employee");
    String str=this.name;
    Integer sum=0;
    for(int i=0;i h=new HashMap<>();
    //for (int i=0;i<5;i++){
        h.put(emp, emp);
        h.put(emp2, emp2);

    //}

    System.out.println("----------------");
    System.out.println("size of hashmap: "+h.size());


}

}

32
задан Patrick Collins 12 June 2015 в 16:55
поделиться

8 ответов

Вычислить область пересечения, которая также является прямоугольником:

SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))

Оттуда вы вычислите область объединения:

SU = SA + SB - SI

И вы можете рассмотреть отношение

SI / SU

(100% в случае идеального перекрытия, до 0%).

53
ответ дан Patrick Collins 25 August 2018 в 03:21
поделиться

Просто фиксируйте предыдущие ответы так, чтобы соотношение находилось между 0 и 1 (с использованием Python):

    # (x1,y1) top-left coord, (x2,y2) bottom-right coord, (w,h) size
    A = {'x1': 0, 'y1': 0, 'x2': 99, 'y2': 99, 'w': 100, 'h': 100}
    B = {'x1': 0, 'y1': 0, 'x2': 49, 'y2': 49, 'w':  50, 'h':  50}

    # overlap between A and B
    SA = A['w']*A['h']
    SB = B['w']*B['h']
    SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ])
    SU = SA + SB - SI
    overlap_AB = float(SI) / float(SU)
    print 'overlap between A and B: %f' % overlap_AB

    # overlap between A and A
    B = A
    SB = B['w']*B['h']
    SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ])
    SU = SA + SB - SI
    overlap_AA = float(SI) / float(SU)
    print 'overlap between A and A: %f' % overlap_AA

Выход будет:

    overlap between A and B: 0.250000
    overlap between A and A: 1.000000
3
ответ дан Alessio B 25 August 2018 в 03:21
поделиться

@ User3025064 является правильным и является самым простым решением, однако исключительность должна быть проверена сначала для прямоугольников, которые не пересекаются, например, для прямоугольников A & amp; B (в Visual Basic):

If A.Top =< B.Bottom or A.Bottom => B.Top or A.Right =< B.Left or A.Left => B.Right then
    Exit sub   'No intersection
else
    width = ABS(Min(XA2, XB2) - Max(XA1, XB1))
    height = ABS(Min(YA2, YB2) - Max(YA1, YB1))
    Area = width * height      'Total intersection area.
End if
2
ответ дан cdmh 25 August 2018 в 03:21
поделиться
[ymin_a, xmin_a, ymax_a, xmax_a] = list(bbox_a)
[ymin_b, xmin_b, ymax_b, xmax_b] = list(bbox_b)

x_intersection = min(xmax_a, xmax_b) - max(xmin_a, xmin_b) + 1
y_intersection = min(ymax_a, ymax_b) - max(ymin_a, ymin_b) + 1

if x_intersection <= 0 or y_intersection <= 0:
    return 0
else:
    return x_intersection * y_intersection
2
ответ дан Felix 25 August 2018 в 03:21
поделиться

Формула для пересечения будет

SI= Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))

, тогда объединение будет S=SA+SB-SI

И, наконец, отношение будет SI / S.

18
ответ дан Ganz7 25 August 2018 в 03:21
поделиться

Ответ @ user3025064 - правильный ответ. Принятый ответ непреднамеренно переворачивает внутренние MAX и MIN звонки. Нам также не нужно сначала проверять, пересекаются они или нет, если мы используем представленную формулу MAX (0, x) в отличие от ABS (x). Если они не пересекаются, MAX (0, x) возвращает ноль, что делает область пересечения 0 (то есть непересекающейся).

Я предлагаю, чтобы @Yves Daoust исправил его ответ, потому что он принят, который появляется любому, кто ищет эту проблему. Еще раз, вот правильная формула для пересечения:

SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))

Остальное как обычно. Союз:

SU = SA + SB - SI

и соотношение:

SI/SU

1
ответ дан Hazem 25 August 2018 в 03:21
поделиться

Недавно я столкнулся с этой проблемой и применил ответ Ив, но почему-то это привело к неправильному размеру области, поэтому я переписал ее.

Предполагая два прямоугольника A и B, узнайте, сколько они перекрываются, и если да, верните размер области:

IF A.right < B.left OR A.left > B.right
    OR A.bottom < B.top OR A.top > B.bottom THEN RETURN 0

width := IF A.right > B.right THEN B.right - A.left ELSE A.right - B.left
height := IF A.bottom > B.bottom THEN B.bottom - A.top ELSE A.bottom - B.top

RETURN width * height
7
ответ дан Ja͢ck 25 August 2018 в 03:21
поделиться

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

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

Рассмотрим случай

a: (1,1), (4,4)
b: (2,2), (5,3)

. В этом случае мы видим, что для пересечения высота должна быть bTop - bBottom, поскольку вертикальная часть b полностью содержится в a.

Нам просто нужно добавить еще несколько случаев следующим образом: (Код можно закоротить, если вы обрабатываете верх и низ как то же самое, что и правое и левое, поэтому что вам не нужно дважды дублировать условный фрагмент, но это должно делать.)

if aRight <= bLeft or bRight <= aLeft or aTop <= bBottom or bTop <= aBottom:
    # There is no intersection in these cases
    return 0
else:
    # There is some intersection

    if aRight >= bRight and aLeft <= bLeft:
        # From x axis point of view, b is wholly contained in a
        width = bRight - bLeft
    elif bRight >= aRight and bLeft <= aLeft:
        # From x axis point of view, a is wholly contained in b
        width = aRight - aLeft
    elif aRight >= bRight:
        width = bRight - aLeft
    else:
        width = aRight - bLeft

    if aTop >= bTop and aBottom <= bBottom:
        # From y axis point of view, b is wholly contained in a
        height = bTop - bBottom
    elif bTop >= aTop and bBottom <= aBottom:
        # From y axis point of view, a is wholly contained in b
        height = aTop - aBottom
    elif aTop >= bTop:
        height = bTop - aBottom
    else:
        height = aTop - bBottom

return width * height
4
ответ дан Shar 25 August 2018 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: