Название: operator < Отправлено: Igors от Март 31, 2013, 18:00 Добрый день
Есть такая структурка Код Как теперь определить оператор < для использования напр в std::map ? Спасибо Название: Re: operator < Отправлено: RedDog от Март 31, 2013, 18:33 А как он должен действовать? Может суммы сравнивать?
тогда примерно так: Код: bool operator < ( const CMatrix & sec ) const Название: Re: operator < Отправлено: kamre от Март 31, 2013, 18:36 Как теперь определить оператор < для использования напр в std::map ? Оператор < для для использования в std::map никак не связан с оператором ==, поэтому можно как угодно определить, удовлетворяя StrictWeakOrdering (http://www.sgi.com/tech/stl/StrictWeakOrdering.html). Например, сравнивая лексикографически.А если же вдруг появится дополнительное требование, чтобы отношение эквивалентности из оператора <, определяемое как !(x < y) && !(y < x), совпадало с отношением, определяемым оператором ==, то это невозможно, т.к. приведенный выше оператор == не транзитивный, а StrictWeakOrdering требует транзитивности. Название: Re: operator < Отправлено: kambala от Март 31, 2013, 18:43 Например, сравнивая лексикографически. по-моему это абсолютно естественный вариантНазвание: Re: operator < Отправлено: Igors от Март 31, 2013, 18:47 А как он должен действовать? Может суммы сравнивать? Мне хотелось бы побыть в роли незнающего, которому вумные люди покажут "как правильно" - а Вы сразу встречный вопрос(ы), типа творческая дискуссия - я на это не подписывался :)Оператор < для для использования в std::map никак не связан с оператором ==, поэтому можно как угодно определить, удовлетворяя StrictWeakOrdering (http://www.sgi.com/tech/stl/StrictWeakOrdering.html). Например, сравнивая лексикографически. Я понял все что Вы сказали - ну а делать-то что? :) Кстати мое первое впечатление было подобным - недостижимо именно из-за требований транзитивности А если же вдруг появится дополнительное требование, чтобы отношение эквивалентности из оператора <, определяемое как !(x < y) && !(y < x), совпадало с отношением, определяемым оператором ==, то это невозможно, т.к. приведенный выше оператор == не транзитивный, а StrictWeakOrdering требует транзитивности. по-моему это абсолютно естественный вариант Но не дающий разумных результатовНазвание: Re: operator < Отправлено: Fat-Zer от Март 31, 2013, 18:52 Например, сравнивая лексикографически. по-моему это абсолютно естественный вариантНазвание: Re: operator < Отправлено: Igors от Март 31, 2013, 19:01 только вот матрицы, для которых operator==() будет возвращать труъ, будут добавляться по нескольку раз... Совершенно верно, матрицы могут быть реально равны/идентичны но из-за неизбежной погрешности double "точное" сравнение вернет false[/offtop] У меня одного впечатление что форум как-то приуныл, много дней "нiчого цiкавого"? Well, "Good Times Bad Times" :) Название: Re: operator < Отправлено: kamre от Март 31, 2013, 19:09 ну а делать-то что? Использовать другие структуры данных, т.к. std::map здесь явно не подходит.Название: Re: operator < Отправлено: Fat-Zer от Март 31, 2013, 19:21 может через std::unordered_map сделать?
hash примерно такая будет: Код: size_t hash<CMatrix>(const CMatrix & M) { Название: Re: operator < Отправлено: Igors от Март 31, 2013, 19:24 Использовать другие структуры данных, т.к. std::map здесь явно не подходит. Вариант, но дороговато выходит (напр свое дерево), "при прочих равных условиях" std предпочтительнее (как справедливо рекомендует наш модератор). Нет ли ходов попрактичнее?Название: Re: operator < Отправлено: kamre от Март 31, 2013, 19:35 Вариант, но дороговато выходит (напр свое дерево), "при прочих равных условиях" std предпочтительнее (как справедливо рекомендует наш модератор). Нет ли ходов попрактичнее? В std нет контейнеров для spatial indexing, поэтому или самому реализовывать или брать какие-то готовые реализации.Название: Re: operator < Отправлено: kamre от Март 31, 2013, 19:37 может через std::unordered_map сделать? Не будет корректно работать, т.к. найдутся два элемента a==b, для которых будут разные значения функции hash.Название: Re: operator < Отправлено: m_ax от Март 31, 2013, 19:51 А как он должен действовать? Может суммы сравнивать? Мне хотелось бы побыть в роли незнающего, которому вумные люди покажут "как правильно" - а Вы сразу встречный вопрос(ы), типа творческая дискуссия - я на это не подписывался :)Может стоит отмотать несколько шагов назад и задаться вопросом что привело к такой безапелляционной мысли писать этот совершенно не свойственной для матриц оператор? И потом, для матриц нет однозначного оператора < ... Их можно придумать бесконечное множество реализаций (в зависимости от Вашего настроения или положения звёзд и т.д.)... А теперь подумайте о том, кто будет использовать Ваш код.. В общем это очень, подчёркиваю, очень плохая идея( Название: Re: operator < Отправлено: Old от Март 31, 2013, 20:01 Может стоит отмотать несколько шагов назад и задаться вопросом что привело к такой безапелляционной мысли писать этот совершенно не свойственной для матриц оператор? Реализация оператора это уже последствия, мне интересней для чего может понадобиться использовать матрицы в качестве ключа коллекции?Что-то мне подсказывает, что лучше изменить архитектуру, что бы не приходилось так делать. Название: Re: operator < Отправлено: Igors от Март 31, 2013, 20:28 Может стоит отмотать несколько шагов назад и задаться вопросом что привело к такой безапелляционной мысли писать этот совершенно не свойственной для матриц оператор? Да отчего же "несвойственной", друг мой? Напр я получаю кучу трансфомеров в виде матриц по каждому полигону - неужели это неестественно проверить и сохранить только уникальные их них? ... В общем это очень, подчёркиваю, очень плохая идея( Реализация оператора это уже последствия, мне интересней для чего может понадобиться использовать матрицы в качестве ключа коллекции? Ага, а вот и "тип из второго батальона", рад его видеть :) Ну ладно m_ax - молодой, увлекается "синтаксическим сахаром", это пройдет. Но Вы-то - человек с немалым опытом - как насчет упереться рогом и подумать - или четко доказать что это невозможно. А то сразу в кусты, мол, меняем архитектуру :)Что-то мне подсказывает, что лучше изменить архитектуру, что бы не приходилось так делать. Название: Re: operator < Отправлено: Old от Март 31, 2013, 20:40 Ага, а вот и "тип из второго батальона", рад его видеть :) Ну ладно m_ax - молодой, увлекается "синтаксическим сахаром", это пройдет. Но Вы-то - человек с немалым опытом - как насчет упереться рогом и подумать - или четко доказать что это невозможно. А то сразу в кусты, мол, меняем архитектуру :) Для меня, так же как и для m_ax, не понятен смысл оператора < для матриц, точек, цветов, виджетов и других подобных структур. :)Что я тут могу подтверждать и опровергать? И правда, очень интересно, для чего может понадобиться использовать матрицы в качестве ключей коллекций. Что используется в качестве значения? Расскажите без стеснений. :) Название: Re: operator < Отправлено: m_ax от Март 31, 2013, 21:00 Может стоит отмотать несколько шагов назад и задаться вопросом что привело к такой безапелляционной мысли писать этот совершенно не свойственной для матриц оператор? Реализация оператора это уже последствия, мне интересней для чего может понадобиться использовать матрицы в качестве ключа коллекции?Что-то мне подсказывает, что лучше изменить архитектуру, что бы не приходилось так делать. Ага, а вот и "тип из второго батальона", рад его видеть :) Ну ладно m_ax - молодой, увлекается "синтаксическим сахаром", это пройдет. Но Вы-то - человек с немалым опытом - как насчет упереться рогом и подумать - или четко доказать что это невозможно. А то сразу в кусты, мол, меняем архитектуру :) Для меня, так же как и для m_ax, не понятен смысл оператора < для матриц, точек, виджетов и других подобных структур. :)Что я тут могу подтверждать и опровергать? И правда, очень интересно, для чего может понадобиться использовать матрицы в качестве ключей коллекций. Что используется в качестве значения? Расскажите без стеснений. :) Хорошо, тогда, чтоб направить обсуждение в "конструктивное русло" может стоить внести некую предысторию, которая бы воссоздавала корень самой проблемы? Название: Re: operator < Отправлено: Fat-Zer от Апрель 01, 2013, 06:21 может через std::unordered_map сделать? Не будет корректно работать, т.к. найдутся два элемента a==b, для которых будут разные значения функции hash.как насчет упереться рогом и подумать - или четко доказать что это невозможно. дык kamre уже объяснил, что это не возможно и почему...Название: Re: operator < Отправлено: Igors от Апрель 01, 2013, 11:36 И правда, очень интересно, для чего может понадобиться использовать матрицы в качестве ключей коллекций. Что используется в качестве значения? Расскажите без стеснений. :) Есть N полигонных объектов каждый из которых может иметь до 8 текстур. Каждая текстура имеет матрицу. Если у каких-то объектов все текстуры равны (с заданной точностью) то они используют/шарят одни и те же данные (UV координаты), иначе разные. Как видите, дело совершенно рядовое.Название: Re: operator < Отправлено: kamre от Апрель 01, 2013, 15:12 для любых матриц a==b сиё должно выдавать одинаковый хеш... Функция round разрывная, поэтому всегда можно найти два элемента a==b, для которых будет разное значение. Просто сами представьте: все пространство разбивается на области с одинаковыми значениями hash функции, всегда есть граница между областями, можно взять сколь угодно близкие элементы находящиеся по разные стороны от границы.Название: Re: operator < Отправлено: Fat-Zer от Апрель 01, 2013, 16:11 Функция round разрывная, поэтому всегда можно найти два элемента a==b, для которых будет разное значение. Просто сами представьте: все пространство разбивается на области с одинаковыми значениями hash функции, всегда есть граница между областями, можно взять сколь угодно близкие элементы находящиеся по разные стороны от границы. да... правда...Название: Re: operator < Отправлено: Igors от Апрель 01, 2013, 16:34 Однако же - "углубление в корень/первоосновы" никакого прогресса пока не принесло :)
дык kamre уже объяснил, что это не возможно и почему... И это всем понятно? Или не очень - но лучше промолчать? :) Почему напр не просто такКод
2kamre А Вас, Штирлиц, я попрошу пока воздержаться :) Название: Re: operator < Отправлено: Old от Апрель 01, 2013, 18:17 Есть N полигонных объектов каждый из которых может иметь до 8 текстур. Каждая текстура имеет матрицу. Если у каких-то объектов все текстуры равны (с заданной точностью) то они используют/шарят одни и те же данные (UV координаты), иначе разные. Как видите, дело совершенно рядовое. Только отсюда не следует, что для реализации этого, необходимо обязательно использовать map. ;)Если отказаться от него, то хватит операторов равенства/не равенства. Название: Re: operator < Отправлено: m_ax от Апрель 01, 2013, 18:52 На крайний случай можно написать свой специфичный предикат и передать его map.
В смысле примерно так: Код
Но писать в самом CMatrix этот оператор< идея бредовая. Название: Re: operator < Отправлено: Igors от Апрель 01, 2013, 19:00 Только отсюда не следует, что для реализации этого, необходимо обязательно использовать map. ;) Ну использование прямого перебора, мягко говоря, не украшает программиста - этим он расписывается в своей беспомощности. Если отказаться от него, то хватит операторов равенства/не равенства. На крайний случай можно написать свой специфичный предикат и передать его map. А почему оператор < для структуры кажется Вам бредовым? Ну есть какое-то отношение упорядочивания. Если их много - может и лучше подсовывать той или иной функтор, а если 1 и др не видно - так чего в структуре не объявить? Впрочем это дело вкуса. Главное - а корректен ли предложенный оператор/функтор?В смысле примерно так: .. Но писать в самом CMatrix этот оператор< идея бредовая. Название: Re: operator < Отправлено: Old от Апрель 01, 2013, 19:11 Ну использование прямого перебора, мягко говоря, не украшает программиста - этим он расписывается в своей беспомощности. Да? Не знал. :)Т.е. придумать невозможный оператор для структуры, что бы ее можно было использовать в map для вас показатель класса? :) Название: Re: operator < Отправлено: m_ax от Апрель 01, 2013, 19:41 А почему оператор < для структуры кажется Вам бредовым? Ну есть какое-то отношение упорядочивания. Если их много - может и лучше подсовывать той или иной функтор, а если 1 и др не видно - так чего в структуре не объявить? Впрочем это дело вкуса. Главное - а корректен ли предложенный оператор/функтор? Да как уже неоднократно говорили: введение такого оператора нарушает свойства транзитивности для объектов матриц. Этого одного факта уже вполне достаточно чтоб хотя бы призадуматься (а может есть решение более логичное).. Название: Re: operator < Отправлено: Igors от Апрель 01, 2013, 19:50 Да? Не знал. :) Я на map не настаиваю - предлагайте др решения, только без "пускания пузырей" с прямым перебором :)Т.е. придумать невозможный оператор для структуры, что бы ее можно было использовать в map для вас показатель класса? :) Да как уже неоднократно говорили: введение такого оператора нарушает свойства транзитивности для объектов матриц. Этого одного факта уже вполне достаточно чтоб хотя бы призадуматься (а может есть решение более логичное).. А что это за свойства такие? И как мы их нарушаем? Можно объяснить попроще, а то у Вас все так "официально" :)Название: Re: operator < Отправлено: m_ax от Апрель 01, 2013, 20:13 А что это за свойства такие? И как мы их нарушаем? Можно объяснить попроще, а то у Вас все так "официально" :) Да очень просто: У Вас нет никаких гарантий что если a < b и b < c, то и a < c. И как следствие, если у Вас, например, имеется некая последовательность: a1, a2, a3, a4, .. an, то отсортированная последовательность (с помощью этого оператора<) будет зависеть от исходной. Это плохо, я бы сказал - это костыль.. Во-вторых это плохо ещё и от того, что у Вас реализация класса CMatrix начинает обрастать зависимостями от способа реализации каких то частных задач.. Такие зависимости - это практически всегда следствие корявой архитектуры.. Ну и в-третьих: Вы уверены, что Вас правильно поймут те, кто, возможно будет в будущем работать с Вашим кодом? Название: Re: operator < Отправлено: Fat-Zer от Апрель 02, 2013, 06:55 И это всем понятно? Или не очень - но лучше промолчать? :) Почему напр не просто так про то, что транзитивность ( a<b & b<c => a<c ) не выполняется уже сказали.с такой штукой std::map просто будет не корректно работать... в частности может добавлять одинаковые элементы или не находить уже имеющиеся. может будут и другие глюки при повороте дерева например... одним словом тут точно придётся воять какой-то особый контейнет... есть одна идея, правда, быть может, бредовая, основанная на том, что для скалярного double аналогичный отношение с epsilon будет задавать строгий порядок... потом, может быть, расскажу, когда и если оно более детально обрисуется в голове... Название: Re: operator < Отправлено: Igors от Апрель 02, 2013, 11:50 Да очень просто: У Вас нет никаких гарантий что если a < b и b < c, то и a < c. про то, что транзитивность ( a<b & b<c => a<c ) не выполняется уже сказали. Да как-то сказали - повторили написанное :) Лучше на живом примере. Пусть epsilon = 1 и матрицы отличаются только первыми 2-мя числами. Имеем 2 ключа(0.9, 10) (0.1, 30) Поскольку разница по первому ключу < epsilon, используем второй. Теперь появляется 3-й ключ, напр (1.5, 20) Выясняется что как бы мы не крутили, расставить ключи по возрастанию (a < b < c), не удается. Мапа не будет работать правильно, а для некоторых реализаций имеет право даже рухнуть. Это популярная ошибка, поэтому лучше разжевать. Название: Re: operator < Отправлено: Igors от Апрель 02, 2013, 12:01 Простое и хорошее решение было предложено в первом же ответе, оформим
Код Писал прямо здесь, возможны погрешности. Критикуем, опровергаем :) Название: Re: operator < Отправлено: m_ax от Апрель 02, 2013, 12:10 Тогда уж в качестве ключа лучше брать Sp (шпур) (он же Tr (трэйс), он же след), поскольку он инвариантен по отношению к вращениям..
Да и считается быстрей) Название: Re: operator < Отправлено: Anchorite от Апрель 07, 2013, 19:50 Код: bool operator < ( const CMatrix & sec ) const Не подойдет? Естественно, что никакого "физического" или "математического" смысла в этом операторе нет. Название: Re: operator < Отправлено: Bepec от Апрель 07, 2013, 20:13 Гениальный!!! ответ. Без сарказма.
Название: Re: operator < Отправлено: Igors от Апрель 08, 2013, 11:42 Код: bool operator < ( const CMatrix & sec ) const Не подойдет? Естественно, что никакого "физического" или "математического" смысла в этом операторе нет. Название: Re: operator < Отправлено: Bepec от Апрель 08, 2013, 12:04 Забацайте там 20% погрешности.
Название: Re: operator < Отправлено: Igors от Апрель 08, 2013, 12:13 Забацайте там 20% погрешности. :) Что-то у Вас с фундаментальными вещами совсем неважноНазвание: Re: operator < Отправлено: Bepec от Апрель 08, 2013, 12:32 Умейте отличать сарказм от серьёзных ответов. :)
Название: Re: operator < Отправлено: Igors от Апрель 08, 2013, 12:57 Умейте отличать сарказм от серьёзных ответов. :) У Вас ни то ни другое, так, скажу что-нибудь, авось попаду в тему :) Название: Re: operator < Отправлено: Bepec от Апрель 08, 2013, 13:50 Спасибо за лестные слова. Я их ждал.
Название: Re: operator < Отправлено: Anchorite от Апрель 08, 2013, 17:11 Конечно этот оператор будет работать корректно, но полученный отсортированный контейнер (напр std::map) оказывается бесполезным - ведь "близкие" элементы (для которых == вернет true) окажутся где угодно, а совсем не рядом друг с другом. А задача добавлять в мапу только те матрицы для которых нет близких имеющихся Ну тогда, я считаю, что operator== следует модифицировать следующим образом Код: bool operator < ( const CMatrix & sec ) const Название: Re: operator < Отправлено: Igors от Апрель 08, 2013, 17:48 Код: bool operator < ( const CMatrix & sec ) const |