Курс лекций (4)

2.2 Функции хеширования

2.2.1 Как уже отмечалось, основная идея хеширования заключается в том, что элемент данных заносится в память по адресу, который легко вычислить, зная содержимое ключевого слова (КлСл), присвоенного этому элементу. На выбор КлСл не накладывается практически никаких ограничений: могут использоваться обычные имена или произвольные числовые коды (ЧК), причем к ним не требуется добавлять какие-нибудь контрольные метки или символы. Длина КлСл также выбирается произвольно, хотя в вычислениях участвуют обычно только несколько первых символов. В результате набор или область допустимых слов (т.е. пространство имен) оказывается весьма обширным. Например, количество слов, которые можно составить из шести букв английского алфавита = 256  млн. (? 300 млн.!) .

Первая мысль, которая приходит в голову при рассмотрении возможных вариантов преобразования пространства имен в пространство адресов (ПрИм > ПрАдр) это желание осуществить тем или иным способом сжатие пространства имен (ПрИм). Коэффициент  заполнения ПрИм в реальных условиях оказывается крайне малым. Поэтому хотелось бы подобрать такую функцию, у которой в области значений (совпадающей с адресным пространством) адреса распределялись бы более равномерно и с большей плотностью.

Если бы ключевым словам были поставлены в соответствие некоторые числовые значения v, случайно распределенные по закону, близкому к равномерному, то задача решалась бы достаточно просто.

Обозначим F(v) интегральную функцию распределения случайной переменной v. Если в качестве хеш-адреса, соответствующего данному v, взять величину , где

H общее количество допустимых адресов;

B первый адрес,

то на отрезке [B, B+H] хеш-адреса будут распределены равномерно.

К сожалению, такой подход связан с определенными сложностями:

Во-первых, ключевые слова это, как правило, коды, элементам которых при переводе в числовую форму придают различные веса. Очень сомнительно, что бы получавшиеся в результате такого преобразования числа имели распределение, близкое к равномерному.

Во-вторых, таким способом нельзя устранить проблему коллизий, т.к. при сжатии в результате ошибок дискретизации могут появиться совпадающие адреса.

Позже мы посмотрим, что преобразование адресов может осуществляться проще и независимо от распределения ключевых слов. Поэтому методы сжатия рассматривать не будем.

Преобразование ключевых слов в допустимые адреса памяти в общем случае выполняется с помощью некоторой функции хеширования.

Содержимое ключа обозначим через k, а число h(k) назовем вычисленным адресом, или хеш-адресом.

Если двум разным ключам k1 и k2 соответствуют одинаковые адреса h(k1) = h(k2), то говорят, что возникла коллизия. При этом, для одного из конфликтующих элементов (обычно второго) необходимо отыскать незанятый адрес, который нетрудно определить, зная вычисленный h(k1) – это может быть следующий за h(k1) или другой.

Если резервные ячейки помещаются в области памяти, адреса которой входят в область значений хеш-функции, то коллизии могут происходить и с резервными ячейками.

В принципе коллизии всегда устраняются одним способом независимо от того, где они возникли по вычисленному или резервному адресу.

Если на ключевые слова не накладывается никаких ограничений, то можно сравнивать различные функции хеширования, исходя из способности минимизировать количество коллизий. В общем случае, хорошей функцией хеширования может считаться любая, обеспечивающая равномерное распределение вычисленных адресов внутри выделенной области памяти.

Процесс формирования хеш-функции включает обычно два этапа:

  1. выбор способа перевода ключевых слов в числовую форму;
  2. выбор алгоритма преобразования числовых значений в набор хеш-адресов.

2.2.2 Перевод ключевых слов в числовую форму

Всякая информация, вводимая в ЭВМ, должна быть тем или иным способом закодирована. Установлены стандартные форматы для кодирования чисел, букв, других символов на любых носителях (и в памяти). Данные между устройствами тоже передаются в форме специальных кодов.

Например, ASCII (Американский стандартный код обмена информацией), КОИ-8, ДКОИ и др.

В этих кодах все числа, буквы, символы представлены 8-ми разрядными цифрами (байт).

Для выполнения арифметических операций числа обычно преобразуются либо в двоичную, либо в двоично-десятичную форму. Учитывая, что все машинные переменные так или иначе представлены в числовой форме, то дополнительных преобразований проводить уже не надо.

Однако в некоторых алгоритмах, предназначенных для вычисления адресов, требуется, чтобы все исходные числовые величины располагались в пределах допустимого диапазона целых чисел в ЭВМ.

Как правило, ключевое слово представляет собой строку, состоящую из цифр, букв, или алфавитно-цифровых символов. В алфавит могут входить разные символы. Наиболее удобны алфавиты, включающие простое число символов. При проведении арифметических преобразований это число выступает в качестве основания системы счисления.

Предположим, что имеется алфавит, в котором каждому символу i согласно некоторому правилу поставлен в соответствии номер

di ? {0, 1, 2,…, W-1}.

Тогда строку, образованную из этих символов, и записанную в форме

k = dN ? dN-1 …d1?d0,

можно рассматривать как представление некоторого числа в системе с основанием W. Его значение определяется по формуле:

(1)

Возьмем, например, английский алфавит и следующим образом присвоим номера его буквам:

di = {A=0, B=1, …, Z=25}.

Тогда слову “ABE” соответствует числовое значение 0 ? 262 + 1 ? 261 + 4 ? 260 = 30.

Описанный метод дает хорошие результаты при переводе в числовую форму английских имен и слов.

Рассмотрим, каким способом в числовую форму, пригодную для хеширования, можно преобразовать индексные переменные. Такая проблема, в частности, возникает при разработке методов хранения и выборки разреженных матриц.

Разреженными называют такие матрицы, у которых только небольшая часть элементов отлична от нуля, причем эти ЭД ? 0 распределены внутри матрицы произвольным образом. Для того чтобы не расходовать машинную память на запись нулей, ненулевые элементы (ЭД ? 0) можно занести в хеш-таблицу, причем в этом случае пара индексов (i, j), указывающих позицию элемента в матрице, выступает в качестве ключевого слова.

Полагая, что i ? {1, 2,…, p} и j ? {1, 2,…, q}, мы можем получить числовое значение «ключевого слова» (i, j) при помощи одной из следующих двух формул:

v = i + q?(j 1) 1 или v = j + p?(i 1) 1 (2)

Адрес в хеш-таблице, по которому будет храниться ЭД (элемент матрицы), вычисляется в виде некоторой функции v точно также, как определяется хеш-функция символьной строки, если известно ее числовое значение v.

В рассмотренных методах перехода к числовой форме стремились получить распределение величин v, достаточно близкое к равномерному.

Однако в процедуре хеширования имеется и второй этап, связанный с преобразованием числовых значений v в пространстве хеш-адресов. В ходе этой операции осуществляется окончательная рандомизация адресов.

Рандомизация метод преобразования ключа записи в адрес ее размещения во внутренней памяти, основанный на использовании генератора псевдослучайных чисел.

Качество результатов данного этапа в основном определяется свойствами функции хеширования.

Краткая «справка» по методам рандомизации

Основные методы:

  • линейный;
  • квадратичный;
  • случайный.

Прежде, чем углубляться в дальнейшее обсуждение алгоритмов хеширования, целесообразно рассмотреть некоторые методы генерации псевдослучайных чисел.

Псевдослучайные числа имеют отношение к методам хеширования по двум причинам:

  1. хеш-адреса, получаемые как функции ключевых слов, сами по себе являются псевдослучайными числами;
  2. зависящие или не зависящие от значения ключа случайные числа используются в алгоритмах пробинга.

Наиболее важной характеристикой псевдослучайных чисел является степень корреляции между соседними элементами, величина которой должна быть, по возможности, минимальной.

Что касается метода хеширования, то он относится, по существу, к методу проб и ошибок. Поэтому качество псевдослучайных чисел для него особой роли не играет и влияет лишь на суммарное число проб. Определяющим здесь является быстродействие самого алгоритма хеширования, который должен выполняться с помощью минимального количества коротких (l) команд.

Последовательности псевдослучайных чисел, применяемые, например, в алгоритмах пробинга, обладают одним важнейшим свойством:

Если задано некоторое исходное число, то всякая последовательность, формируемая алгоритмом-генератором псевдослучайных чисел, полностью детерминирована. Это объясняется тем, что вычисление псевдослучайных чисел всегда производится по рекуррентной схеме, т.е. результаты, полученные на предыдущих шагах, используются в качестве параметров на последующих.

Известны несколько алгоритмов генерации псевдослучайных чисел.

Наиболее распространены основанные на так называемом мультипликативном сравнении.

Для выполнения операций хеширования могут применяться и специальные аппаратные средства. Наиболее известные способы аппаратной реализации генераторов псевдослучайных чисел:

  • сдвиговый регистр со специальными обратными связями (по операции “исключающее ИЛИ” над двумя разрядами).

Другие методы хеширования

  • метод деления ;
  • метод умножения;
  • метод извлечения битов.

Один из старейших способов формирования хеш-функции:

  • двоичное число, соответствующее хеш-адресу, образуется просто путем сцепления нужного количества битов, извлекаемых из определенных позиций внутри указанной битовой строки;
  • метод квадрата (числовое значение ключевого слова v возводится в квадрат);
  • метод сегментации (строка делится на сегменты, равные по длине хеш-адресу, и далее, различные сочетания и операции с сегментами);
  • переход к новому основанию (системы счисления);
  • алгебраическое деление (группирование ключевых слов, применение полиномов);
  • оптимальные функции хеширования (попытки обобщить методы алгебраического кодирования);
  • специальные методы хеширования (для решения задач классификации, сокращенные хеш-таблицы).

Нет комментариев »

Еще нет комментариев.

RSS лента комментариев к этой записи.

Оставить комментарий

Вы должны войти чтобы оставить комментарий.