На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! правила раздела Алгоритмы
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code.../code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке :)
Модераторы: Akina, shadeofgray
  
> Сравнение чисел по "маске"
    Есть 2-мерный массив, числа в массиве одного порядка и состоят из комбинаций 1 и 2. Например
    ExpandedWrap disabled
      2221 2222 2222 2222 1112
      2222 2222 1211 2111 1122
      2122 1221 2212 1222 1111


    И есть "маски". Это тоже числа, количество цифр в этих числах не может превышать количество цифр в числах массива, т.е. для приведенного выше массива маска может содержать от 1 до 4 цифр. Маска формируется из цифр 0, 1 и 2, и показывает чему должны быть равны определенные разряды чисел массива (0 означает, что значение разряда не важно). Примеры масок: 2002, 11, 121, 221. Так маска 2002 означает, что самый старший и самый младший разряды должны быть равны 2, этой маске соответствуют числа 2222, 2112, 2212, 2122 из примера.

    Нужно в массиве найти все числа, соответствующие определенной маске. Потом этим числа будут участвовать в обработке.
    Т.к. реальные массивы имеют большую размерность, а число "масок" и их длина тоже могут меняться, хочется найти какой-то быстрый способ для такой проверки. Пробовал сделать через битовые операции, но не получилось. Может кто-то что-то подскажет?

    P.S.: пишется все это на Python, для работы с массивами используется NumPy.
      В массиве следует поменять 2 на 0.
      Маску надо поделить на две маски.
      Первая - это маска, у которой 1 там, где в твоей нули, и нули на месте 1 и 2.
      Вторая - это маска, у которой 2 заменены на 0.
      Теперь делаем (массив AND маска1) и сравниваем с (маска2).
      При совпадении - соответствует. Ну а нет - значит нет.
        если сопоставить числам бинарные коды n = 2221 = 1110b = 0x6, и каждой маске сопоставить пару бинарных масок m=2001 -> mz=1001b и mx=0001b, то проверка будет простой ((n xor mx) and mz) равно 0 при соответствии маске.
        однако затраты на перевод чисел в такой вид надо учитывать. если набор многоразовый, то дело того стоит, наверно.
          Akina, спасибо почти то, что нужно. Но как я понял, такой метод будет работать не всегда. Например, если маска 22, то и первая и вторая маски будут равны 0.

          Видимо, моя вина, что не очень четко описал задачу. Массивы могут быть сформированы не только из 4х-значных чисел, количество разрядов может быть любым, от 1 до 10, но одинаково для всех элементов массива.
            voltron, поймите СМЫСЛ того, что делается - и все эти проблемы легко снимете.
              Пытаюсь, но пока не очень получается. Если взять элемент массива 2212 и заменить 2 на 0, то получим 10. Пусть маска 2002, тогда маска1 - 110, а маска2 - 0. Если теперь применить AND к элементу и маске1 (считая их двоичными числами) получим: 0010 AND 0110 = 0010. Результат не совпадает с маской2. Если же выполнять AND не поразрядно, а побитово (т.е. исходить из того, что все числа в десятичной системе) вообще ничего не получается.
              Хм... что-то я совсем запутался. Попробую еще завтра на свежую голову
                Цитата voltron @
                Пусть маска 2002, тогда маска1 - 110, а маска2 - 0.

                Здрасьте, приехали! Это с какого перепугу длины масок отличаются от длины исходного шаблона?
                  Опустил начальные нули.
                  0110 и 0000
                    Не надо опускать ничего - а то можно доопускаться...

                    Ну ладно, что тебя собсно смущает? никогда ничего не приходилось с нулём сравнивать?
                      Все, разобрался.

                      Но к сожалению, предложенный метод не очень подходит. По тестам скорость практически не изменилась.
                        Цитата voltron @
                        По тестам скорость практически не изменилась.

                        А вы анализ производительности делали?

                        Цитата voltron @
                        И есть "маски". Это тоже числа, количество цифр в этих числах не может превышать количество цифр в числах массива

                        Как маски поступают в программу? Может на этапе "загрузки" их приводить к требуемому виду, например, донарашивать урезанными нулями, и т.д.?
                        Может добавить оптимизацию и в алгоритм (разработать алгоритм) и сам алгоритм оптимизировать (его работу).
                        У меня было очень много расчетов, программа работала 3-4 минуты. Добавил OpenMP -> 3-4 секунды :crazy: (все расчеты в цикле были, на 4-х ядернике было просто прелесть)
                        Из-за особенности данных, добавил данные в кеш (сетка) за один проход, часть расчетов не нужных отсеялась при работе со своей ячейкой в кеше.

                        Так что, если цель оптимизация времени работы, надо подходить глобально
                        1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0667 ]   [ 14 queries used ]   [ Generated: 2.07.25, 02:46 GMT ]