Використовуючи послідовність де Бреййна, щоб знайти


11

Шон Андерсон опублікував трохи крутив хакі , що містять алгоритм Еріка Коула , щоб знайти А.Н. -розрядним целочисленного в операцій з множення і пошуку.N v O ( lg ( N ) )log2vNvO(lg(N))

Алгоритм спирається на "магічне" число з послідовності Де Бруйна. Чи може хтось пояснити основні математичні властивості послідовності, що використовується тут?

uint32_t v; // find the log base 2 of 32-bit v
int r;      // result goes here

static const int MultiplyDeBruijnBitPosition[32] = 
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

v |= v >> 1; // first round down to one less than a power of 2 
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];

2
Ідея виходить з цієї статті supertech.csail.mit.edu/papers/debruijn.pdf . Послідовність де Бруйна розміром - це спосіб представити всі бітові рядки розміром k дуже стисло: кожна можлива рядок з'являється рівно один раз у вигляді суміжного підпорядкування . Отже, якщо ви змістите послідовність de Bruijn на n 2 k біт і прочитаєте останні k біт, у вас є унікальний ідентифікатор для n . 2kkn2kkн
Сашо Ніколов

1
До речі, це обчислює лише ; і як написано, він працює лише для 32-бітних цілих чисел. журнал2v
Сашо Ніколов

1
@Sasho Перетворитись на відповідь?
Yuval Filmus

@SashoNikolov Спасибі, додав функцію стелі до питання
Юрій Байда

Відповіді:


9

Спершу зауважте, що цей алгоритм обчислює лише , і як написаний код, він працює лише для v, що вписується у 32- бітове слово.журнал2vv32

Послідовність зсувів або -ів, яка з’являється першою, має функцію розповсюдження провідного 1-біта аж до найменш значущого біта. Числово це дає 2 log 2 v - 1 .v2журнал2v-1

Цікава частина - трюк de Bruijn, який походить з цієї праці про Leiserson, Prokop та Randall (мабуть, професори MIT проводять час, роблячи трохи хакі :)). Що потрібно знати про послідовності де Бруйна, це те, що вони представляють усі можливі послідовності заданої довжини таким чином, наскільки це можливо стиснене. Точно послідовність де Бруйна над алфавітом - це двійковий рядок s довжиною 2 k таким чином, що кожна двійкова стрічка k довжиною з’являється рівно один раз у вигляді суміжного підрядка (дозволено обгортання). Причина цього корисна в тому, що якщо у вас є число X{0,1}с2ккХчиє бітове представлення - це послідовність де Бреййна ( підкреслена нулями), то верхні k біти 2 i X однозначно ідентифікують i (до тих пір, як i < k ).кк2iХii<к


3
Зверніть увагу , що ви можете використовувати будь-яку послідовність де Брейна таким чином , щоб обчислити дав 2 я . Однак ви не можете використовувати довільну послідовність де Бреййна для обчислення i, що дається 2 i - 1 . Тут 0x07C4ACDD = 00000111110001001010110011011101, здається, є послідовністю де Бруйна з деякими додатковими властивостями, завдяки чому додаткова - 1 не руйнує цей підхід. i2ii2i11
Jukka Suomela

Дякую @JukkaSuomela, мене це трохи збентежило. Я думаю, ти завжди можеш просто додати 1 до . v
Сашо Ніколов

5

Деякі коментарі (насправді не відповідь). Класифікуємо 32-бітні цілі числа таким чином:c

  • Тип X: (як двійковий рядок) - це послідовність Де Бруйна (для всіх обертів біти [27,31] є різними). Приклад:c

    11111011100110101100010100100000
    
  • Введіть Y: біти [27,31] з різні при я = 0 , 1 , . . . , 31 . Про це говорять Leiserson et al. використовує. Приклади:2ici=0,1,...,31

    00000100011001010011101011011111
    00001111101110011010110001010010
    
  • Тип Z: біти [27,31] з різні при я = 0 , 1 , . . . , 31 . Це те, що нам потрібно в оригінальному запитанні. Приклади:(2i+1-1)ci=0,1,...,31

    00000111110001001010110011011101  (07C4ACDD)
    10000111110001001010110011011101
    01111000001110110101001100100011
    11111000001110110101001100100011
    

Деякі спостереження, засновані на швидких експериментах (я сподіваюся, що я правильно)

  1. Існує 65536 цілих чисел типу X.

  2. Існує 4096 цілих чисел типу X + Y. Це саме ті цілі числа типу X, які починаються з послідовності '0000 ...'

    • інтуїція: з провідними нулями обертання = зсув?
  3. Існує 256 цілих чисел типу X + Y + Z. Це саме ті цілі числа типу X, які починаються з послідовності '0000011111 ...'

    • інтуїція: ??
  4. Усі цілі числа типу Y також типу X.

  5. Однак є також 768 цілих чисел типу Z, які не є ні типу X, ні типу Y. Вони починаються з "1000011111 ...", "0111100000 ..." або "1111100000 ..."


1
Це єдина відповідь, яка стосується того, чому множення Де Бреййна на 2 ^ n-1 працює, на відміну від 2 ^ n, що є лише зрушенням. Мені подобається, якби хтось міг розширити "інтуїцію" №3 вище. Як Ерік Коул придумав це? Метод спроб і помилок? Або деяке розуміння того, що насправді відбувається з бітами, коли ви помножите на 2 ^ n-1?
FarmerBob

1
  • Звідки береться ця константа?

Цитуючи: "10 грудня 2009 року Марк Дікінсон відбив пару операцій, вимагаючи, щоб v було округлено до однієї менше, ніж наступна потужність 2, а не сила 2". [graphics.stanford.edu/~seander/bithacks.html]

Ця часткова константа - це послідовність Де Бруйна з двійковим алфавітом, але має додаткову властивість. Я буду називати це "властивістю Марка Дікінсона", оскільки оригінальний алгоритм міг бути реалізований без цих спеціальних послідовностей БД. Додавши дві додаткові операції, ми могли використовувати будь-яку звичайну послідовність БД. Операція: v ^ = (v >> 1); // clr всі біти, крім MSB, встановлені після каскадного або зсуву.

  • Результати (груба сила)

Seq.Type | № Цілі | № DBSeq. з | без обертань | з властивістю Дікінсона
B (2, 3) | 256 | 16 | 2 | 1
Б (2, 4) | 64Кі | 256 | 16 | 4
Б (2, 5) | 04Гі | 64Кі | 02Кі | 256
Б (2, 6) | 16Еі | 04Гі | 64Мі | ??

  • Особливе майно

0х7С4АСDD 2к1(мод232)32к1введіть тут опис зображення2к1

  • Лексикографічно найменші бінарні послідовності де Бреййна з властивістю Дікінсона

    [B (2,3): 0x1D] [B (2,4): 0x0F2D] [B (2,5): 0x7C4ACDD] [B (2,6): Ще шукаю]

Якщо ви сподівалися на вишукану математичну формулу, яка б описала їх, або теорему для їх створення чи щось подібне, я думаю, що це потребує глибокого розуміння теорії чисел та, можливо, інших сфер, що не виходить за межі мого набору навичок. Якщо я де дивовижу здогадуюсь, я б заперечив, що їх можна виробляти за допомогою клітинних автоматів. Це не відповідь, чому? на жорсткій основі, але спроба інтуїтивно зрозуміти, чому це працює і чому він працює належним чином, тому ви можете використовувати це з упевненістю.

PS Я не висвітлював конструкцію LUT, яку легко вивести, якщо ви розумієте принципи роботи алгоритмів.


Нарешті знайдено: B (2,6) 0x3f08a4c6acb9dbd - послідовність на 64-бітній обробці зі "властивістю Дікінсона". Я знайшов принаймні 122K таких послідовностей.
ФранГ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.