- •Индуктивные функции
- •Общая схема вычисления индуктивных функций
- •Общая формулировка задания
- •Задания
- •Обработка одномерных массивов
- •Сведения о массивах в языке Паскаль
- •Цель, требования и рекомендации к выполнению задания
- •Примеры выполнения задания. Работа с одномерным массивом
- •Задания
- •Простые алгоритмы сортировки одномерных массивов
- •Обработка двухмерных массивов
- •Пример выполнения задания
- •Цель, требования и рекомендации к выполнению задания Цель, требования и рекомендации аналогичны изложеным в 7. 2.
- •Задания
- •Обработка файлов, представляющих упорядоченные множества
- •Общая формулировка задания
- •Цель, требования и рекомендации к выполнению задания
Индуктивные функции
Общая схема вычисления индуктивных функций
Основные определения, схема программ и примеры алгоритмов вычисления индуктивных функций на последовательностях подробно изложены в [6]. Более краткое изложение дано в [1] и ориентировано на представление последовательности в виде последовательного файла. Конечно, последовательность может быть реализована и как массив, и как линейный список, и некоторыми другими способами. Далее в заданиях будем рассматривать реализацию последовательности именно в виде файла, так как этот способ делает более естественным использование однопроходных алгоритмов, что и достигается при вычислении индуктивной функции.
В приведенных далее заданиях указана функция f(), значение которой надо вычислить. Будем использовать обозначения, введенные в [1]: – последовательность элементов заданного типа, т. е. = x1x2…xn, где xi X, а X – произвольный алфавит; пустая последовательность обозначается как ; k(X) – пространство всех конечных последовательностей над X длины не менее, чем k; при этом 0(X) (X).
Напомним определение индуктивной функции (см.[1], с.20). Функция f: (X) Y называется индуктивной, если f(x) можно вычислить, зная f() и x, т. е. если существует функция G:Y XY, такая, что для всех (X), x X выполняется соотношение f(X) = G(f(), x).
Если последовательность реализована в программе файлом fin типа file of X, то вычисление индуктивной функции может быть реализовано следующим фрагментом программы:
Reset(fin); y:=y0; {y0=f()}
While not Eof(fin) do
begin
Read(fin,x);
y:=G(y,x)
end {while}
Очевидно, что это фактически схема, из которой конкретная программа может быть получена интерпретацией абстрактных типов X и Y, переменных x, y и y0, функции G(y, x). Эта схема имеет инвариант цикла y = f(L(fin)) и ограничивающую функцию Length(R(fin)). Здесь использованы обозначения: L(fin) – прочитанная часть файла fin, R(fin) – непрочитанная часть, а Length(fin) – длина файла (количество элементов представленной в нем последовательности).
Общая формулировка задания
Заданы алфавит X и функция f: (X) Y. Требуется определить, является ли функция f() индуктивной. Если “да” – выписать функцию G(,), если “нет” – подтвердить это, применяя критерий индуктивности [1, с. 21], а затем придумать индуктивное расширение [1, с. 23] и выписать G для него.
Далее требуется написать на языке Паскаль программу вычисления указанной функции f(), считая, что – это состояние последовательности элементов типа X, находящейся во входном файле.
При формулировке задания используются следующие обозначения типов, реализующих алфавит X: Z – Integer, N – натуральные, N0 – натуральные с нулем, S – Char, B – Boolean, R – Real, R0 – неотрицательные Real, R+ – положительные Real, R2 = R * R (декартово произведение).
Используется также следующая специальная терминология:
а) отрезок – это связная подпоследовательность (т. е. подпоследователь-ность подряд идущих элементов основной последовательности);
б) отрезок с некоторым заданным свойством (знакопостоянный, возрастающий и т. п.) предполагается максимально длинным, т.е. не является частью другого отрезка с тем же свойством.
Цель, требования и рекомендации к выполнению задания
Цель выполнения задания: ознакомиться с основными приёмами и получить навыки программирования задач обработки последовательностей однотипных элементов с применением однопроходных алгоритмов. В качестве типовой задачи рассматривается частный, но показательный и важный пример – вычисление индуктивных функций на последовательностях. При этом математическая последовательность реализуется в заданиях как последовательный файл.
Требования и рекомендации к выполнению задания:
алгоритм решения задачи должен быть однопроходным и не должен использовать дополнительную память, пропорциональную размеру входного файла (использование массивов для хранения входной последовательности запрещено);
возможны 2 варианта реализации последовательности в виде входного файла: а) файл имеет тип Text, создается с помощью стандартного текстового редактора и просматривается тоже стандартными средствами; б) файл имеет тип file of X, создается и просматривается специальной отдельной программой (или программами) генерации и просмотра;
рекомендуется использовать схему вычисления индуктивной функции, в которой на каждом шаге основного цикла из входного файла читается и обрабатывается 1 элемент последовательности (в этом случае инвариант цикла и ограничивающая функция стандартны);
программа должна выводить поочередно обрабатываемые элементы входного файла, а также другие (промежуточные) данные в виде, позволяющем проанализировать и понять процесс формирования окончательного результата как автору программы, так и проверяющему задание;
выходные данные (включая те, что необходимы для понимания работы алгоритма) должны выводиться на экран для оперативного анализа результатов (в режиме отладки) и в выходной файл (в режиме формирования отчета) для демонстрации проверяющему работоспособности программы;
требуется протестировать основные особые случаи входных данных (например, входной файл пуст или содержит лишь 1 элемент), корректную обработку последнего элемента файла, проверить, учитывается ли наличие стационарного значения индуктивной функции и т. п.
Пример выполнения задания
Рассмотрим задачу, подробно проанализированную в [1, с.26]: вычисление суммы элементов отрезка заданной последовательности, имеющего максимальную сумму. Далее приводится программа, решающая эту задачу. В комментариях приведены все основные обозначения и рекуррентные (индуктивные) расчетные соотношения, позволяющие понять работу программы.
program Inductive_function_1;
{-------------------------------------------------------------------------------------------------}
{ Пример вычисления индуктивного расширения функции : }
{ f( w ) = " Сумма элементов отрезка с максимальной суммой " , }
{ где отрезок - связная подпоследовательность последовательности w. }
{ Пусть исходная последовательность есть w = x(1)x(2)...x(n) }
{ и пусть S(k,l) = SUM ( k <= i <= l : x(i) ), где 1 <= k <= l <= n . }
{ Тогда заданная функция есть f(w) = max ( S(k,l) : 1 <= k <= l <= n ) }
{ Функция f - неиндуктивна. Рассмотрим индуктивное расширение }
{ F = ( f, t ), где t( w ) = max ( S(j,n) : 1 <= j <= n ) }
{ Содержательно t(w) - потенциальный конкурент текущего рекорда f(w) }
{ при продолжении последовательности w . Вычисление f и t : }
{ t ( w * x ) = max ( x, x + t(w) ), }
{ f ( w * x ) = max ( f(w), t(w*x) ), }
{ t ( $ ) = 0, f( $ ) = MinInt. }
{ Здесь $ обозначает пустую последовательность. }
{ Исходная последовательность читается из файла INITSEQ.DAT . }
{-------------------------------------------------------------------------------------------------}
const MinInt = -32768;
var x, { очередной элемент последовательности }
y, { y = f ( w ) }
z : Integer; { z = t ( w ) }
fin, { input file }
fout : Text ; { output file }
begin
Assign( fin, 'INITSEQ.DAT' );
Assign( fout, {'INFREZ.DAT'}'' );
Rewrite( fout );
WriteLn( fout, 'Элемент Рекорд Конкурент ' );
Reset( fin ); { L(fin)=$ }
y := MinInt; { y=f($) }
z := 0; { z=t($) }
{ inv : y=f(L(fin)) & z=t(L(fin)) }
{ bound: length(R(fin)) }
while not Eof(fin) do
begin
Read( fin, x );
Write( fout, x : 8 );
{ новый конкурент : }
if z>0 then z := z + x else z := x;
{ новый рекорд : }
if z>y
then { обновить рекорд }
begin
y := z;
WriteLn( fout, y : 9 )
end
else { оставить старый }
WriteLn( fout , z : 20 );
end { while };
{ y = f ( fin ) & z = t( fin ) }
WriteLn( fout, '***Максимальная сумма = ', y, '***' );
Close( fin );
Close( fout )
end { Inductive_function_1 } .
|
Экран результатов |
|
Элемент Рекорд Конкурент 1 1 2 3 -5 -2 3 3 6 9 -10 -1 6 6 9 15 1 16 -5 11 ***Максимальная сумма = 16*** |
Результаты выполнения этой программы приведены в таблице.
В первой колонке выводятся элементы входной последовательности, во второй — значение “текущего” рекорда, если он обновляется (замещается конкурентом) на данном шаге. В третьей колонке выводятся значения конкурента, кроме тех шагов, на которых конкурент становится новым рекордом. Такой вывод исходных и промежуточных данных позволяет проследить за работой алгоритма по шагам и понять способ формирования окончательного результата.
