Генерация случайных слов.
SysUtils,
Math;
function SelectRandomString(a : array of string): string;
var
i : integer;
begin
i := Random (High(a));
Result := a;
end;
function RandomWord(): string;
const
glas_arr : array [0..6] of string = ('a', 'w', 'e', 'y', 'u', 'i', 'o');
sogl_arr : array [0..18] of string = ('q', 'r', 't', 'p', 's', 'd', 'f', 'g',
'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v',
'b', 'n', 'm');
MaxWLen = 10; //Maximal length of the word;
var
i, j, WLen : byte;
begin
Randomize;
WLen := Random (MaxWLen);
Result := ' ';
{This assignment is very important: it makes each word unique}
for i := 0 to Wlen do
begin
j := Random (2);
case j of
0 : Result := Result + SelectRandomString (glas_arr);
1 : Result := Result + SelectRandomString (sogl_arr);
else
Result := Result + SelectRandomString (glas_arr) + SelectRandomString (Sogl_arr);
end;
end;
end;
Результат:
И всё бы прекрасно, только текст получается некрасивый. На решение задачи по забитию БД данными это никак не влияет, но для общего развития стало интересно, как сделать так, чтобы текст был похож на естественные языки?
Варианты:
1. Использовать RandG (гауссово распределение случайных чисел) и сформировать массив так, чтобы выбирались более часто встречающиеся буквы.
2. Использовать массив слогов. Для реалистичности можно попробовать найти распределение слогов в естественном языке.
Дело в том, что решение этой задачи может быть использовано в других местах, например, в играх. Поэтому всё-таки интересно сгенерировать "приятный" текст.
тем неменее считаю, что использование слогов достаточно удачная идея. Можно ещё создать набор правил, которые бы учитывали особенности сочетания слогов, их частоту и прочее. Опять же, создание всего этого вручную мне кажется утомительным, я за идею о генерации, посредством парсинга
Меня вдохновил на подвиги Adobe InDesign, там есть Placeholder Text, похожий на латынь, да не латынь.
[QUOTE=Romik]создание всего этого вручную мне кажется утомительным, я за идею о генерации, посредством парсинга[/QUOTE]
Не понял, что имеется в виду.
Когда речь идёт о слогах, базу следует расширить и разнообразить, однако это только моё приватное мнение, прошу рассматривать его как один из допустимых вариантов. Так вот, написав программу-парсер, которая смогла бы проанализировать достаточный объём текста, чтобы извлечь из него разные части слов (вероятно тут уместее было бы сказать разные слоги, но моя идея предполагает дальнейшее развитие, т е корни, приставки, суффиксы, окончания), можно было написать алгоритм, который используя такую базу, пытался бы по правила языка конструировать слова.
ИМХО, проще поэкспериментировать с массивом. Не вижу смысла писать ещё и парсер. Другое дело, что может стоит написать генератор массива слогов, поскольку в стандартной латинице 7 гласных и 19 согласных, получается уже 133 слога (руками вбивать ломает), + удвоить это количество из-за обращений слогов, + такие сочетания, как ll, ss, th, sch, ch, sh. Потом их рассортировать по популярности, и тогда уже что-то получится.
I. Подготовка
1. Взять электронный словарь
2. Получить распределение длин слов
3. Получить распределение первых букв для каждой длины слова
4. Получить распределение парных букв для каждой длины слова
5. Посчитать условные вероятности для первых букв при заданной длине слова.
6. Посчитать условные вероятности для текущей буквы при заданной предыдущей букве и заданной длине слова
II. Генерация слова.
1. Получить случайную длину слова исходя из распределения 2
2. Получить случайную первую букву исходя из распределения 5
3. В цикле до конца слова - получить случайную тукущую букву исходя из длины слова и предыдущей буквы (распределение 6).
По - моему, очень интересная задачка.
Вопросы?
I. Подготовка
1. Взять электронный словарь
2. Получить распределение длин слов
3. Получить распределение первых букв для каждой длины слова
4. Получить распределение парных букв для каждой длины слова
5. Посчитать условные вероятности для первых букв при заданной длине слова.
6. Посчитать условные вероятности для текущей буквы при заданной предыдущей букве и заданной длине слова
II. Генерация слова.
1. Получить случайную длину слова исходя из распределения 2
2. Получить случайную первую букву исходя из распределения 5
3. В цикле до конца слова - получить случайную тукущую букву исходя из длины слова и предыдущей буквы (распределение 6).
По - моему, очень интересная задачка.
Вопросы?
Замечание. Генератор случайных чисел должен:
1. обладать большим периодом
2. обладать хорошей разрешающей способностью.
Рекомендую Mersenne Twister (очень скоростной, период=(2^19937)-1).
Хорошая разрешающая способность нужна, чтобы генерировать данные, распределенные произвольно.
Для того, чтобы сгенерировать какое - то данное, принимающее конкретный набор значений с конкретными вероятностями (как в моем примере), можно разбить отрезок, в который попадают случаные значения с выхода генератора, на отрезки, число которых равно числу значений, а длины пропорциональны вероятностям. Тогда i-е данное выдирается в случае попадания равномерно распределенного числа, выданного генератором, в отрезок. Для этого и нужна хорошая разрешающая способность.
Хорошая разрешающая способность = случайные числа большой разрядности. Если брать генераторы с маленьким периодом, то случайные числа быстро "съедят" период.
Вижу еще один способ генерации данных, распределенных произвольным образом - упорядочить значения так, чтобы огибающая была Гауссовой или Лапласовой. Затем генерировать числа, гаспределенные по Гауссу или по Лапласу. Здесь выбор i-го данного происходит тогда, когда случ. сичло, распределенное по Гауссу, попадает в интервал, отвечающий i-му данному. Но здесь интервалы уже имеют постоянный шаг. Тем не менее, хорошая разрешающая способность генератора требуется и здесь.