2016-07-28 2 views
0

Предположим, у меня есть std::vector<Point> где Point является struct Point { double x; double y;} Я хотел бы разделить такой вектор на группы (ведра), где все пункты в одном ведре имеют такую ​​же евклидову норму между собой (например dist (PointA, PointB) == X, где X является константой). Я решил использовать std::map для такой задачи с оператором пользовательских сортировки:Partition станд :: вектор 2D точек

struct ClosePoints 
{ 
    bool operator()(Point const& A, Point const& B) const 
    { 
     bool same = dist(A,B) < x; 
     //If not close enough use lexical sort 
     return same ? false : std::tie(A.x, A.y) < std::tie(B.x,); 
    } 
} 

Разметки Код:

std::map<Point, std::list<Point>, ClosePoints> map; 
for(const auto& p : pointsVector) 
    map[p].push_back(p); 

После некоторого тестирования и печать ведра я заметил, что некоторые моменты, которые повинуются дал Конец евклидовой нормы X закончился в разных ковшиках. Я не могу понять, почему это так?

+1

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

+0

1) Что такое 'x'? 2) Что такое 'dist()'? 3) Что делать, если 'dist (A, B) PaulMcKenzie

+0

Вы не выполняете строгий порядок, как 'A <= A + eps' и' A + eps <= A + 2 * eps', но не 'A <= A + 2 * eps'. – Jarod42

ответ

2

Проблема заключается в том, что оператор сравнения, который вы определили, не обеспечивает отношения эквивалентности. Например, вы можете иметь точку B, близкую к A и C, но точки A и C могут быть далеки друг от друга. Таким образом, если вы сравните B с A и C, вы поместите их в ту же корзину, что и B. Однако, если вы сначала скомпилируете A и C, результаты будут непредсказуемыми.

+0

Это правильно в общий случай, но в моем случае (данные, над которыми я работаю) такие точки ABC из вашего примера все будут подчиняться расстоянию: (A, B) (B, C) (C, A) будут иметь одинаковое расстояние между собой – JobNick

+0

@JobNick OK, я предполагаю, что у вас есть подмножества с расстоянием друг от друга больше, чем x, и каждое подмножество может быть помещено в шар с радиусом x. Тогда ваша логика правильная. Однако вам нужно заказать разные подмножества, чтобы заставить работу оператора. Это не имеет решения, поскольку оператор может основываться только на геометрической характеристике всего подмножества, например, средней координаты всех элементов, min или max некоторой координаты для всего подмножества. Это легко доказать. – slav

+0

Я думаю, что проблема заключается в порядке ввода элементов. Возможно, в какой-то момент времени, когда дерево перебалансирует себя вставкой элементов, которые уже имеют репрезентативный набор, создает собственный узел дерева (набор). – JobNick