Russian Qt Forum
Апрель 30, 2024, 15:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Построить ID  (Прочитано 3510 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Февраль 11, 2017, 16:58 »

Добрый день

Испытываю затруднения с вроде бы простой задачкой.

- Дано N точек (N может быть сколь угодно большим) и M actions (M обычно порядка 200). Каждая action хранит вектор пар индекс точки + вес, т.е.
Код
C++ (Qt)
struct CAction : public std::vector<std::pair<int, double> > {};
};
Обычно для точки активно 4-5 actions

Надо: вычислить и присвоить каждой точке ID которые должны совпадать для точек у которых все actions совпадают и имеют те же веса. Пример

точка 1; (action 1, weight = 1) + (action 2, weight = 1)  // ID = 1
точка 2; (action 2, weight = 1) + (action 3, weight = 1)  // ID = 2
точка 3; (action 1, weight = 1.1) + (action 3, weight = 1)  // ID = 3
точка 4; (action 1, weight = 1.1) + (action 3, weight = 1)  // ID = 3

Спасибо
« Последнее редактирование: Февраль 11, 2017, 17:06 от Igors » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Февраль 11, 2017, 21:22 »

адрес интанции каждого action можно сконвертировать в интегер,
далее суммируем со сдвигом:
ID1 = action 1 << 64 + weight << 128 + action 2 << 256 + weight
...
(я принял каждое значение за 64 бита, как наиболее универсальное на сегодня)
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #2 : Февраль 11, 2017, 21:33 »

адрес интанции каждого action можно сконвертировать в интегер,
далее суммируем со сдвигом:
ID1 = action 1 << 64 + weight << 128 + action 2 << 256 + weight
...
(я принял каждое значение за 64 бита, как наиболее универсальное на сегодня)
Сдвиг более чем на 63 бита для 64-битного числа это UB.
Что вы ждете на выходе (кроме 0)?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Февраль 12, 2017, 01:21 »

я псевдокод написал - не понимайте буквально.
по сути на выходе будет ID из четырех 64-битных чисел.

можно по другому: каждому экшину присваиваем уникальный айди - далее все чудо это сериализируем в QByteArray:

array << action1.id() << weight1 << action2.id() << weight2

и имеем уникальную последовательность байт - чем не ID Улыбающийся
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Февраль 12, 2017, 11:21 »

ID требуется в виде одного числа, напр int. Немного похоже на построение хеш-кода, но требуется уникальность, зато ID вычисляются все 1 раз, пусть и не быстро. Смысл "свернуть" данные actions для операций с точками где они могут дублироваться и удаляться.

Есть очень простой вариант - для каждой точки построить вектор пар индекс action + weight, а потом назначить ID используя ассоциативный контейнер. Примерно: берем первую точку и назначаем ей ID = 0. Берем 2-ю. Если ее вектор пар точно такой же как у первой, то ее ID тоже 0, иначе 1. Но "контейнер контейнеров" - это так ужасно коряво  Плачущий  Но ничего более изящного мне придумать не удалось.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.072 секунд. Запросов: 22.