
ОСНОВЫ АЛГОРИТМИЗАЦИИ
МЕТОДИЧЕСКИЕ УКАЗАНИЯ по курсу „ПРАКТИКУМ на ЭВМ"
\
ДНЕПРОПЕТРОВСК, ДГУ 1980
Министерство высшего и среднего специального образования СССР
Днепропетровский ордена Трудового Красного Знамени государственный университет имени ЗОй-летия воссоединения Украины с Россией
Кафедра математического обеспечения ЗВМ
ОСНОВЫ АЛГОРИТМИЗАЦИИ Методические указания по курсу "Практику* не ')?
Ллєнропетровск, ДГУ
Г9Є0
Яаннне методические указания предназначены для формирования навыков разработки и записи алгоритмов решения задач. В указаниях рассмотрены следуйте вопросы: Анализ задачи, понятие и и-зобрякение алгоритма, структурные элементы алгоритмов и основные вычислительные алгоритмы. Методические указания рассчитаны на студентов, изучающих курс программирования.
I. АНАЛИЗ ЗАДАЧИ
1.1. Моделирование процесса решения
При решении задач прикладной математики всегда приходится иметь дело с реальными явлениями и их свойствами - движение тел, различные производственные процессы, явления общественного развития и так далее. Считается, что мевду отдельными элементами задачи существует взаимосвязи, которые могут быть известны или неизвестны исследователе. Основными источниками знаний о взаимосвязях являются фундаментальные законы, которым подчиняется данные явления: законы сохранения, законы неразрывности, законы взаимодействия и другие.
Обычно задача первоначально формулируется в словесном виде - определить как связаны интересующие нас элементы: например, определить объем сооружения по известным его измерениям, определить движение тела в заданной среде при известных приложенных силах, предсказать выходную величину процесса и т.д.
Первым этапом анализа является построение математической модели исследованного явления. При этом мы отвлекаемся от тех свойств явления, которые не используются в данной задаче (например, цвет здания или материал из которого оно построено,, химический состав среды в которой движется тело), выделяя интересующие нас в данной задаче геометрические или количественные характеристики, подменяем реальное явление абстрактной моделью -вместо дома рассматриваем параллелепипед, вместо движущегося реального тела - .движение точки, на которую действуют определенные силы. Можно сказать, что переходах математической модели мы количественную характеристику явления заменяем математической величиной, с которой будем в любое время связывать одно число. Взаимосвязи между характеристиками явления заменяются взаимосвязями между соответствующими им математическими величинами. Правильно составленная математическая модель хороао описывает (т.е. с достаточной степенью точности) количественные взаимосвязи между характеристиками реального явления. Таким образом,задача, сформулированная Для реального явления,заменяется задачей для метематической модели явления.
Наиболее существенной выгодой от такого перехода является использование одних и тех же математических методов для анализа
щ
различных по природа моделей. Так, например, модель движения грунтовых год, модель распределения потенциала на плоском проводнике, модель двидения воздуха описываются одними и теми же математическими соотношениями.
Рассмотрим структуру данных в модели. Прежде всего,отме-тим, что элементами задачи выступают различные понятия,связан-ные с процессом - сила, упругость, масса, коэффициент при неиз-вестном во второй степени и т.д. При построении модели мы этипонятия рассматриваем только с точки зрения тех величин, которыеони могут принимать в процессе решения задачи. В модели анало-гом понятия является переменная, которая характеризуется своимименем (обозначением) и значением, закон изменения которогоопределяется моделью и исходными данными. Очень часто перемен-ные объединяются в массив (совокупность), которому присваивает-ся одно имя. Массив характеризуется количеством координат, ин-дексов, которые однозначно определяют любой элемент массива.Количество координат называется размерностью массива. Элементмассива обозначается как переменная с индексом - имя массивас указанием индексов. Например, Л , ь ■ , с . и т.д.
1.2. -Нормализация процесса решения задачи
Моделирование является хотя и важным, но не г^ззательным этапом постановки задачи, так как очень чаото задача сразу ставится как математическая.В математической задаче величины можно разделить на известные и неиз естные (подлежащие определению). Очень часто величины зависят от времени,другого параметра, т.е. представляют собой функции. В этом случае по предыстории известных величин требуется определить значение искомой величины в данный момент.
Мы можем пседставить процесс решения задачи как последовательное преобразование исходной информации х в выходную
3 . Насяду с известными данными исследователь обладает определенными знаниями об исследуехо* тлении- различные определения, теоремы, формулы и так далее. Каждому определению (как правило) соответствует какая-то величина. Теоремы, формулы позволяют опре.:елить зту величину через другие величины. Если от исходных данных исследователь может построить цепочку вспомогательных величин, через которые может сыть выражена в
- 5 -
явном виде искомая величина, то эта цепочка определяет метод решения задачи. Таким образом, процесс решения задачи мы рассматриваем как дискретную последовательность шагов. Такая последовательность может быть не единственной.
Обычно о данном явлении нам известно очень много и па основании исходных данных ( ) мы можем непосредственно образовать переменные первого уровня ("•'") (т.е. такие переменные, которые выражаются только через исходные данные), исполь_ зуя исходные данные и переменные \ можно строить и.' и т.д.
Такое множество переменных и определяет какие данные мы можем получить на основе исходных, £-максимальный уровень -за сколько шагов.
Следует отметить, что количество связей (переменных) зависит как от свойств объекта, так и от объема знаний исследователя о данном объекте и представляет обычно очень большое число. Еще больше можно составить путей, только некоторые из которых ведут к цели.
Анализ задачи (построение и(' ) продолжается до тех пор,пока на каком-то шаге У . Такой метод называется методом
прямого поиска. В качестве исходной точки можно взять искомую информацию и строить вспомогательные переменные ■С1*'.-Процесс продолжается до тех пор,пока 1/^ - X . Такой метод называется обратным поиском. Обратный метод приводит к меньшему количеству вспомогательных переменных ( к более короткому пути решения), однако получение такого решения является более сложным. Наиболее оптимальным является комбинированный метод, когда исходная задача заменяется задачей между ^гС') и и '3) . Основным вопросом при решении задачи являются выбор шагов, выбор подзадач данной задачи с убывающей сложностью,т.е. таких для решения которых требуется все меньшее количество шагов ( вспомогательных переменных). Очевидно, для этого исследователь должен иметь возможно большее количество сведений о данном явлении, т.е. с увеличением объема знаний увеличивается возможность получения решения задачи.
Но объем знаний (понятий, формул) это только одна сторона, которая является решающей при одношаговом решении. В противном случае ( т.е. для 1многошегового решения) решающим является фактор выбора вспомогательных переменных - выбор пути решения
(одного или нескольких прпвильных из огромного количества возможных). Для этого исследователь должен обладать умением, опытом выбора правильного пути, что обеспечивается умением распознавать ситуации более "близкие" к искомой,чем исходная. Такое умение развивается только при значительном количестве самостоятельно решенных задач с последующим анализом решения. Без последующего енализа почти нет закрепления, не вырабатывается навык классификации, распознавания задачи, что является самым существенным для выоора метода.
По степени близости (подобия) задачи можно разделить на три группы - тождественные, эквивалентные и однотипные. I. Тождественные задачи. Две задачи называются тождественными, если у них совпадают по значениям все исходные и искомые переменные. Например, решение одного и того же уравнения, одного и того же треугольника и т.д. Решение тождественных задач представляет повторение уже проделанного пути для его закрепления.
2. Эквивалентные задачи. Задачи будем вазывать эквивалентными, если они совпадают с точностью до значений и обозначений переменных. Например, решение любого квадратного уравнения, решение треугольника по двум сторонам и углу между ними. Эквивалентные задечи имеют один и тот же путь решения, одни и те же вспомогательные переменные. Эквивалентные задачи являются абстракцией тождественных задач по значениям переменных и по их обозначениям.
Щ Однотипные задачи. Пае задачи судем называть однотипными,
са': ким применим один и гот же математический метод решения. ••л"от-:т'ые задачи являются обобщениями (абстракцией) эквивалентных зоД'іч по информации в определенных классах. Задачи этого типа г--ч'сотся определенном математическим методое, либо объединяют определенные математические зьдгчи. Например, решение г: ой- ,л.;ьного треугольника, решение произвольной системы линейных алгебраических уравнений, дифференцирование заданных функция, вычисление значений по заданным формулам, вычисление определенного интеграла методом трапеций и т.д.
іїо* решети задачи желательно вспомнить не решалась ли тоаде:-Тве<ыая задача. Если нет, то не з,.ием ли мы такую же экви-в»-.-' нтную задачу, если нет, то не можем ли мы нашу задачу отнести г. ка/ому-то типу задач.
Для сложных задач это, как пэавило,*невозможко и в этом
•случае наиболее действенным методом является разбиение предложенной задачи на ряд подзадач известного типа, которые уже можно свести к определенным эквивалентным задачам. Такое разбиение зависит от знаний и опыта исследователя и, к сожалению, нет универсальных методов оазбиения произвольных задач. Иногда приводит к цели замена данной задачи другой, более общей (но с известным решением) при конкретных значениях параметров. Фактически и этот прием является разложением задачи на подзадачи. Следует остановиться ещё на введении вспомогательных параметров. На каком-то этапе мы предполагаем, что величина известна и решаем задачу в этом предположении. После : выражения искомых величин через "параметр" (неизвестную величину) мы её определяем или она "исчезает", если задача однородная относительно этого "параметра".
1.3. Примеры
Пример I. Из прямоугольного треугольника с острым углом оС вырезан полукруг максимального радиуса. Определить отношение площадей полукруга и треуголвника. В качестве исходной информации задачи выступает форма геометрических фигур и угол треугольника. По исходных данным можно только определить остальные углы треугольника. Перейдем от данной задачи к новой, в которой кроме указанных данных задан один катет (например, тот который лежит против угла Ы,) . В этой задаче треугольник имеет линейный элемент и два угловых, следовательно, по этим данным можно определять любой элемент треугольника ( в том числе и его площадь) - это первая подзадача.
Второй подзадачей является определение положения искомого полукруга. Очевидно, радиус будет максимальным, если диаметр полукруга лежит на одной стороне треугольника и окружность касается двух других (докажите это). Из трех экстремальных полукругов выбираем наибольший, опирающийся на гипотенузу (докажите это).
Теперь, когда положение полукруга определилось, в третьей задаче определим его радиус и искомое отношение.
Анализ покаэяэает, что в решение не входит величина катета и,следовательно,решение второй задачи будет решением и основной задачи. Если бы решение зависело от величины катета, ги иилидиая задача не имела бы решения.
Решение можно записать в виде 1.
Логической предпосылкой такой замены задач является пропорциональное увеличение радиуса при увеличении линейного размера треугольников.
(скорость) будет падать с увеличением времени.
Прежде всего,надо выразить высоту воды как функцию време-ни. Пусть прошло -Ь единиц времени, объем воды TT* J-t . С дру-гой стороны V - ЖХг 6/J . но X - Ь * • Следова-тельно, (U = -Т^г?2^ /3, • Отсюда можно определитьфункцию Ш={3ц,- ^>4с ■£/&}/3. Момент времени *«\ при котором
L - Ао, Определится ёо = S"По * /•
Следовательнс,
dk\ VJ-. 7? i €Ж±-»
В этом примере целесообразно использоватьобратный метод анализа задачи. Наиболееочевидным треугольником, содержащим ис-комый радиус является 6ЛЗ'(33 '= 2Л).Задача была бы решена,если бы былоизвестно ребро и угол Аь'О .
Таким образом,иы приходим к трем задачам-
Рио- 1*2 определение ребра, определение' I Л^О
и определение диаметра. Легко получить, что сторона основания
определяется а,- {2 4 4р ос)*'*} &= (¿¿£-=¿/2, 4у(*А±'0):
Д х £ /('2 • со^) = си {1+ 2 Ыуг<£)/(2с^о<).
Таким образом,мы получим возможность решить задачу весьма коротким методом.
Прежде всего,уточним задачу - за единицу времени добавляется один и тот же объем воды. Следовательно,с течением времени высота в конусе Судет увеличиваться, но так как плошадь коуга увеличивается, то кожно предположить, что темп увеличения
Этот же результат можно пшучить существенно быстрее,если воспользоваться тем,что \ 3 1у £ 4 р т.к. точка,в которой требуется определить производную, зависит от £
2. ПОНЯТИЕ АЛГОРИТМА 2.1. Интуитивное понятие алгоритма
В своей повседневной жизни чедове! постоянно сталкивается с правилами.предписывающими последовательность действии, ведущих к достижению некоторого результата. Это аогут быть правила пользования телефоном-автоматом, умножения в столбик, рецепт приготовления какого-нибудь блюда, метод решения квадратного уравнения и многие другие. Эти правила могут храниться в голове людей и передаваться из поколения в поколение,от стеэших к младшим (например, профессиональные секреты в древности). Они могут быть написаны на телефоне-автомате, напечатаны в поваренной книге или учебнике арифметики. Эти правила различными людьми в различных ситуациях могут называться по-разному. Например, рецепт, метод, способ, процесс, инструкция, программа и др. Но математик скажет, что все это примеры алгоритмов. Мы сталкиваемся с ними на каждом шагу, может быть, даже не замечая этого. .Невозможно представить жизнь человека без использования алгоритмов, которые может быть, самыми надежными путями ведут его к решении сложнейших проблем.
Также невозможно представить математику без понятия алгоритме. Это понятие возникло и развивается вместе с математикой. Еяе в древности стели возникать различные вычислительные процессы, которые позволяли вычислять искомые величины путем чисТо механического применения определенных правил и инструкций «. определенны* исходным данным. Их стали называть алгоритмами.
Термин алгоритма происходит от имени средневекового узбекского математика Аль-Хорезми, который еще в 825 году дал правило выполнения четырех арифметических действий в десятичной системе счисления. Их называли алгоризмами. Со временем слово алго-ризм превратилось в слово алгоритм и в это понятие стали вкладывать всякое точное предписание о выполнении в определенном порядке некоторых дегствий для достижения нужного результата. Вплоть до 30-х годов нкшего столетия это понятие алгоритма в основе смей не менялось, хотя приобретало все большую и бОЛоЯуВ отчетливость. Ко все же такое представление ос алгоритме остается интуитивным, т.е. основанным на обширном человеческом опыте и является еще недостаточно четким и строгим. И это естественно, так как понятие алгоритма в широком смысле относится к основным понятиям математики,, таким как:число, множество, прямая и т,д. и. не может быть сведено к другим понятиям. Содержание этого понятия непрерывно меняется,обогащается по мере накопления человеческого опыта. Все же можно заметить нечто постоянное, неизменное, неотделимое от алгоритма и что в будущем может только ^таногиться яснее, богаче. Рассмотрим такие характерные для алгоритма черты. ; •
V . 2.2», Цекрторае свойства алгоритмов
Прежде всего бросается: в глаза, что каждый алгоритм предполагает наличие некоторых.исходных данных, преобразуя которые с помощью определенной цепочки действий, он- приводит к искомому результату. Всякое,простое дейбтзие, определенное ьягооитмом, называюсь в^гом- алгоритме.' Таким образом, 'алгоритм разбивает псоцесе получения искового результата но дискрет--иув последовательность действий .(вйгое), шшмняем'их над исходными (для данном лага) 'данными. Для алгоритма характерно,,что ста последовательность является конечной., У то значит»' что' ляго-рггм заканчивает свое работу через конечное число вагокя ' го число может сыть очень б'ольиим и можно не зкатъ заранее <&ол\ -ко необходимо выполнить шагов, чтоои для иоикретногз ИСХОДИЛИ
данного получить результат. Говорят, что алгоритм обладает свойством конечности.
В процессе выполнения иагов алгоритма получаются некоторые промежуточные данные. Можно сквзеть, что алгоритм определяет процесс последовательного построения величин таким ооразом, что для одного вага они являются выходными данными, а для следующего - исходными. Для первого шага существует система исходных данных, внешняя по отношению к алгоритму (т.е. такие данные вводятся, задаются, считаются известными и т.д.). Для последнего шага выходные данные являются искомыми результатами. Свойство представимости алгоритма в виде дискретной последовательности шагов называется дискретностью.
Переход от одной системы величин к следующей должен быть достаточно простым и локальным, т.е. наг алгоритма должен быть элементарным. Если же допускать неограниченную сложность иьгоъ алгоритма, можно прийти к выводу, что алгоритмом нужно считать СЯКре требование решить какую-нибудь задачу, требуя только, чтобы сна имела решение. Но что значит потребовать, чтобы шаг алгоритма был простым и локальным. Ведь то, что просто инженеру может быть сложно для старшеклассника и,наверняка,будет совсем непонятно первокласснику. Значит алгоритм, написанный для инженера, не будет алгоритмом для первоклассника, так как он, лапример, не умеет вычислять определенный интеграл. Мы приходим к выводу, что алгоритм нельзя рассматривать оторвано от исполнители алгоритма.
Чтобы исполнитель мог выполнить алгоритм, необходимо,, чтобы алгоритм был понятен для исполнителя. Иными словами, исполнитель должен знать, уметь, быть в состоянии выполнить любви лег алгоритма. То есть для исполнителя выполнение алгоритму представляет собой задачу, которую он должен уметь решать. Полная ясность будет лишь тогда, когда известно, что надо делать, чтобы выполнить алгоритм. Можно сказать, что исполнителю должен быть известен алгоритм выполнения алгоритмов, которые поступают ему для выполнения.
Значит, исполнителем алгоритмов может быть чело-пик1 ей знает как ввполнять алгоритм, животное, если оно специальным образом дресироваяо, механическое устройство, если оно соответствующим образом устроено.
Но если алгоритм способно выполнять животное или даже механическое устройство, это значит, что исполнитель алгоритма не только не нуждается в какой-то фентезии, но, более того, алгоритм не оставляет место для проявления этих качеств в порядке его выполнения, если исполнитель ими обладает. Выполняя алгоритм,действует механически. И это является одним из важнейших качеств алгоритма. После того, как алгоритм создан, выполнение его становится скучной, однообразной и утомительной работой, неоправданным расходом человеческой энергии. Такую работу нужнее всего и легче всего, переложить на плечи автоматов. Мы живем в эпоху научно-технической революции, одной из важнейших черт которой является автоматизация труда. Автоматизация освобождает человека от бремени однообразной, утомительной работы, оставляет для него самое главное, самое существенное, требующее разносторонних знаний, изобретательности, интуиции, творческого порыва и вдохновения, усилий ума, воли, эмоций, выработанных многовековой историей общественного развития. За человеком остается логическая деятельность на высшем этапе обобщения, ведущем к сознательному принятию тех или иных наиболее ответственных решений, программированию работы автоматов. Именно для создания новых алгоритмов понадобятся все эти человеческие качества. Эта работа не под силу ни одному другому существу на земле. Богатство, человечества во многом будет определяться совершенством набора таких алгоритмов, которыми оно располагает. А исполнение алгоритмов будет поручено механическим и электронным устройствам.
Применяя один и тот же алгоритм к одним и тем же исходным данным, мы вправе ожидать одних и тех же результатов. Если же провести более детальный анализ процесса выполнения алгоритма путем фиксации промежуточных результатов, получаемых после каждого шага, можно заметить, что для одних и тех же исходных данных возникающие последовательности одинаковы. Более того, действия,выполняемые на каждом вагу, однозначны незавиоимо от исходных данных алгоритма. Отсюда следует, что система величин, получаемая после выполнения рассматриваемого шага, однозначно определяется системой величин, полученной всеми предыдущими шагами. Такая особенность алгоритмического процесса называется определённостью (детерминированностью) алгоритма.
Алгоритм, как правило, строится для различных вариантов исходных данных. Говорят, что для каждого алгоритма существует некоторый класс допустимых исходных данных. Свойства допустимых всех исходных данных из данного класса называются массовостью алгоритма.Причем число элементов в этом классе может быть бесконечным или конечным и даже нулевым. Сам алгоритм и допустимые исходные данные всегда
доводятся до исполнителя в некоторой форме. Часто этой формой является текст на некотором языке. Чтобы не возникало неопределенности, этот язык должен быть строгим и формальным. Как правило, каждый алгоритм связан только с двумя языками: на одном он сформулирован сам, а предположения другого являются допустимыми для него вариантами исходных данных. Первый язык обычно называют алгоритмическим, а второй - языком операндов (языком данных).
Если алгоритм, отправляясь от некоторого допустимого входного данного, приводит к результату, то говорят/ что алгоритм применим к- этому данному. Если же данное допустимо, но результат получить нельзя,то говорят, что алгоритм к этому данному не применим. Неприменимость алгоритма к допустимому исходному данному будет заключаться в том, что он или никогда не закончится или в процессе своего выполнения натолкнется на препятствие.
При реальном выполнении алгоритма, исполнитель на его выполнение затрачивает определенные ресурсы (время, память и т.д.) и эти ресурсы,как правило, ограничены.
И если не учитывать реальные возможности исполнителя, а требовать лишь, чтобы алгоритм закончил свою работу за конечное число шагов, то можно говорить лишь о потенциальной выполнимости алгоритма. Например, известны многие алгоритмы, основанные на прямом переборе. Они, как правило, требуют конечного, ко очень большого числа шагов для получения результата. Так существует алгоритм выбора наилучшего хода при игре в шахматы. Но для выполнения одного хода даже при использовании грандиозных возможностей современной вычислительной техники потребуются сотни лет работы ЭВМ. Ясно, что такой алгоритм з настоящее время не имеет сколько-нибудь существенной практической ценности. Поэтому на практике- важна реальная выполнимость алгоритма.
2.3. Пример
По заданным действительным коэффициентам квадратного трехчлена определить его корни.
Сначала уточним постановку задачи. Прежде всего,напомним, что коэффициент при X... должен быть отличен от нуля,и решение такой задачи существует в классе комплексных чисел. Исходными денными являются всевозможные тройки действительных чисел Л , Ь , С 1*0
Результатами являются либо два действительных корня, либо действительная часть и коэффициент при мнимой части комплексных корней. Результатом является также указатель типа корней.
Со школьного курса известно, что для действительных корней х{1г= (~в ± -чж?)/^2Л) > а мя комплексных-в/
Хг= {чж - в*/, где Хх -действительная часть; _!сг - коэффициент при мнимой части. Указанные формулы определяют метод решения задачи. Будем считать, что мы можем оперировать только с действительными числами. Свойство применимости алгоритма к любой тройке (т.е. для любых таких троек алгоритм выдает результат) определяет его массовость.
Так как существуют случаи комплексных и действительных корней, то, очевидно,должны существовать части алгоритма для обработки этих случаев (различные пути реализации - различные алгоритмические процессы для различных вариантов исходных данных).
Выбор ветви определяется знаком дискриминанта, вычисление которого является первым шагом алгоритма: Ъ = - %АС. При Ь^О должны вычислять комплексные корни, а при Ъ> ^-действительные. Следовательно, вторым шагом алгоритма является проверка знака и выбор пути. На третьем шаге мы определяем действительные корни и задаем признак действительных корней (например, Р = 2). На шаге 3 ' определяем части комплексных корней и задаем признак (Р ■ 0). Четвертый шаг реализирует выдачу результатов (^.^, р)-
Для каждой конкретной тройки мы будем идти только по одному из двух возможных путей:
шаг I — таг 2 — шаг 3 >— шаг ч;
шаг I -«-шаг 2 —шаг 3 -—-шаг 4.
Зидно, что в различных путях имеются общие части (шаги I,
?,ч).
Очевидно,построенный алгоритм является конечным, дискретным, результативным.
При составлении алгоритма мы считаем, что исполнитель может реализовать любой шаг (в том числе 3 и 3).
Если исполнитель умеет выполнять только Ч арифметических действия, то в этом случае шаги 3 и 3 являются невыполнимыми. Следовательно,для такого исполнителя приведенная схема не является алгоритмом.
Эти шаги содержат самостоятельную задачу. - извлечение
квадратного корня с заданной погрешностью из положительного числа D • Наиболее просто это реализовать следующей схемой:
Шаг 5 - значению Z задается Ъ . '
Шаг 6 - вычисляется Z¿ ( по формуле (Z +Ъ/2)/2).
Шаг 7 - проверяется, если I ¿ - Zsi ¿ ¿ , то результатом является Zx , если | 2 - ¿i I * { , то ¿ - г1 и повторяется схема,начиная с шага б.
Можно показать, что алгоритм конечный, т.е. для любого ¿?c наступит момент, когда ¡¿-¿¿¡^ á
Возвратимся к постановке задачи. Так как тройки чисел яв-ляются внешними данными, то среди них могут оказаться и такие,у которых В этом случае схема не является алгоритмом,
т.к. вычисление по формулам осуществить невозможно. Для расширения области исходных данных мы должны дополнить алгоритм третьей ветвью - решение линейного уравнения. Эта ветвь содержит шаги:
lar 8- если 8*0 , то определяется корень Xt = - С/6 и задается £>= і . Переход на шаг Ч .
Шаг 9- если С = о , то задать Р- 3 (решение неопределенное). Переход на шаг Ч.
lar Ю- Р = Ч (решение не существует). Переход на шагч.
Шаг 0- если J = О , то перейти на шаг 8, если не равно, то перейти на шаг I.
Выполнение алгоритма начинается с шага 0.
2.ч-. Связь интуитивного понятия алгоритма и строгого определения алгоритма
Свойства алгоритма, рассмотренные выше, дают некотороецельное представление о понятии алгоритма. Такое представлениеоб алгоритме известно всем математикам и долгое время такогопонимания алгоритма хватало для практики. Действительно, хотяэто понятие и не строгое, но оно настолько ясное, что у мате-матиков не возникало сколько-нибудь существенных расхожденийв том, считать предложенную совокупность правил алгоритмом илинет. \
Но в начале'XX века появилась необходимость в строгом математическом определении понятия алгоритма. Одно дело - доказать существование1 алгоритма, другое - доказать отсутствие алгоритма. Первое можно сделать путем построения процесса, решающего задачу;в этом случае достаточно и интуитивного понятия алгоритма, чтобы удостовериться в том, что описанный процесс есть алгоритм. Доказать несуществование алгоритма таким путем невозможно. Для этого недостаточно знать, что такое алгоритм.
В 20-х годах XX века эта проблема стала одной из центральных математических проблем. Решение этой проблемы было получено в середине 30-х годов в работах математиков Гильберта, Гёделя, Чёрча, Клини, Поста и Тьюринга. Эти работы положили начало теории алгоритмов, которая в настоящее время имеет огромное значение и,в первую очередь, служит теоретической основой при создании ЭВМ и их математического обеспечения.
Формальное определение понятия алгоритма было получено в терминах рекурсивных функций, в терминах машин Тьюринга-Поста и позднее в терминах нормальных алгоритмов Маркова. Как оказалось, эти три определения алгоритма являются эквивалентными. Это значит, что научные результаты, полученные с помощью алгоритмов, изученных в одной из этих теорий, могут быть также получены с помощью алгоритмов, изученных в любой другой.
Связь любой из этих теорий со всеми алгоритмами в интуитивном смысле осуществляется с помощью основных тезисов этих теорий. Суть этих тезисов заключается в том, что они утверждают о совпадении класса алгоритмов в интуитивном смысле с классом алгоритмов, определенных в каждой из этих теорий. Эти тезисы недоказуемы, но до сих пор они хорошо подтверждались практикой. То есть любой из практически полученных алгоритмов можно было записать в терминах любой из этих теорий.
3. СПОСОБЫ ИЗОБРАЖЕНИЯ АЛГОРИТМОВ 3.1. Связь алгоритма и метода решения задачи
После того, как задача поставлена математически, необходимо разбить нашу задачу на ряд подзадач, решать которые мы уже умеем,т.е. знаем метод их решения. Таким образом формируется некоторый план решения всей задачи. После этого можно приступать к разработке алгоритма.
Переход к алгоритмизации решения задачи связен с дальнейшей конкретизацией возможного исполнителя. Если метод ориентировен на достаточно широкий класс пользователей, обладающих разносторонними знаниями и возможностями, то алгоритм предполагает, что исполнитель способен выполнять довольно ограниченный набор операций, но выполняет их чисто механически, в строго определенном порядке, который и задается алгоритмом. Именно в этом кроется основное различие между методом и алгоритмом решения одной и той же задачи.
Значит,прежде чем приступать к составлению алгоритма решения задачи необходимо четко определить набор элементарных операций, которые мы вправе использовать для описания решения задачи, т.е. необходимо выбрать исполнителя или некоторое множество исполнителей алгоритма.
Набор элементарных операций и исполнитель взаимосвязаны. Если мы начинаем использовать некоторые операции, не предусмотренные нами ранее, то тем самым мы заменяем допустимых исполнителей. В примере об алгоритме решения квадратного уравнения мы можем в шаге 3 и 3'использовать операцию извлечения квадратного корня или расписать процесс извлечения квадратного корня вплоть до четырёх арифметических действий (шаги 4-7). В зависимости от этого будет различным набор элементарных операций, а значит и исполнитель алгоритма.
3 дальнейшем такой элементарный шаг алгоритма мы будем называть оператором. То есть оператор - это некоторая операция (действие, шаг), которую на данном уровне детализации можно рассматривать как единое целое, и эта операция может быть выполнена испг .ли" лем
3.2. Общая структура оператора и набор основных операторов
От постановки задачи до создания алгоритма её решения и получения результатов проходит, как. правило, значительное время. От первых набросков алгоритма.которые зарождаются в голове человека, до законченного алгоритма, пригодного к выполнению, алгоритм претерпевает существенные изменения. Любой промежуточный этап создания алгоритма и его окончательный вариант должны быть каким-то способом записаны.
Существуют различные способы изображения алгоритмов, но все они основаны на представлении алгоритма в виде последовательности элементарных действий, т.е. в виде последовательноети оперйторов> Чтобы изображать алгоритмы, надо, прежде всего, уметь изображать операторы, из которых строятся алгоритмы.
Разрабатывая алгоритм решения квадратного уравнения, мы -заметили,что каждый оператор может иметь имя (шаг I, шаг 2, и т.д.) для ссылки на него Из другого места алгоритма, и, как правило, содержит описание определенных действий (например, вычисление дискриминацта п0 формуле Т) = 6 - ЧЛС )„ Кроме этого каждый оператор должен указать исполнителю алгоритма своего преемника, т.е. имя оператрра, который должен быть выполнен вслед за этим оператором.
Таким образом, действие оператора можно разделить на преобразование информации и выбор преемника (передача управления другому оператору). Часто операторы выполняются последовательно, т.е. преемциком является следующий по написанию оператор. В этом случае имя преемнике не указывается. Но есть операторы, в которых преемник зь,дается обязательно (например, шаг 2,7,9,0).
3 дальнейшем будем считать, что всякий оператор состоит не солее чем 1,3 трёх частей (полей):
^ п<зле имени > : <: поле описания действия 7-і имя преемникам Наличие всьх трёх полей необязательно,но наличие хотя бы одной части в операторе необходимо.
Гели Ьператор не содержит поле имени, то будем его называть неименованцым. Если же оператор состоит из одного имени, то будем называть ег0 пустым.
Операторы, основным назначением которых является выбор преемника, называются операторами перехода. Только в таких операторах 'удем Допускать имя преемника, т.е. кы несколько сузим понятие оператора, считая что оператор или осуществляет преобразование информации (следующим выполняемым оператором является следующий по напи,Санию), или определяет имя преемника (операторы перехода^.
Ориентируясь, в основном, на задачи вычислительного характера, введем н,а(5ор допустимых в дальнейшем операторов.
Отмети,м> ЧТо процесс решения задачи состоит во взаимодействии зчказчи.ча и, исполнителя алгоритма. Заказчик подготавливает алгоритм в достГуПНоу ддя исполнителя виде и снесжает его исходными данными. '••'с;:,олнитель в соответствии с алгоритмом обрабатывает исходные де.ННуе и зыдает результаты в удобном для заказчика виде.
Таким об пазом, заказчик для исполнителя выступает в качестве внешней сре.ды, откуда к нему поступают исходные данные для ооработки, и куда он должен выдать результаты этой обработки. Вся же обработка информации происходит во внутренней памяти, где исполнитель хранит алгоритм, исходные и промежуточные данные, сами результаты.
Внутренняя память состоит из определенных полей, ячеек памяти, предназначенных для хранения информации. Будем считать, что с именем любой переменной, используемой в задаче, связано место в памяти , где хранится ее текущее значение.
Так как вся обработка происходит во внутренней памяти, первое, что необходимо сделать исполнителю, это ввести исходные данные во внутреннюю память на места соответствующих переменных. Эту работу выполняет специальный оператор ввода (обозначим ВВОД). После обработки исходных данных полученные результаты необходимо вывести во внешнюю среду. Это будет делать оператор вывода (ВЫВОД). Наиболее часто мы будем требовать печать результатов на бумаге. Такой оператор вывода назовем оператором печати (ПЕЧАТЬ). В этих операторах указывается список имен переменных, значения которых необходимо ввести или вывести (например, ВВОД (А.В.С), ВЫВОД (XI.X2.X3), ПЕЧАТЬ (Х1.Х2.Р)).
Далее рассмотрим группу арифметических операторов, осуществляющих преобразование информации:
1. Оператор изменения приращения, модификации (М). Этотоператор по определенному закону меняет значение некоторой пе-ременной. Как правило,оператор модификации задается в виде
/--/' + а- . Эту запись следует понимать следующим образом: к старому (прежнему, текущему) значению переменной прибавляется значение выражения а и полученный результат замещает текущее значение. Для подчеркивания этого факта мы иногда будем использовать запись /:= \ + а~ или i ■«— ) + о- вместо записи \ ~ и-а. (наиболее часто используемой).
2. Общий арифметический оператор (А) вычисляет выражениеи запоминает его результат в качестве значения некоторой пере-менной. Частным случаем арифметического выражения может бытьконстанта или другая переменная. Тогда этот оператор будет осуще-ствлять простую пересылку константы или значения переменной наместо другой переменной. Например, оператор \р£ замещает те-кущее значение / числом 5' , а оператор А - X замещаеттекущее значение к. текущим значением переменной х . Частовместо слова "замещает" в дальнейшем мы будем использовать слово"присваивает".
Для записи общего арифметического оператора часто также используются символы: =" или,,—" . И это неслучайно. Можно заметить, что оператор модификации является частным случаем оператора А, когда выражение в правой части содержит в качестве слагаемого переменную >, стоящую в левой части. Такое искусственное выделение оператора модификации из арифметического оператора вызвано его важностью для записи алгоритмов, его ролью в вычислительном процессе.
Далее рассмотрим группу операторов управления (перехода). Главное назначение этих операторов - менять нормальный ( последовательный) порядок вычисления операторов.
3. Оператор безусловной передачи управления (БПУ) передает управление оператору с именем, стоящим в поле преемника этого оператора. Например,БПУ М; .
Ч. Оператор условной передачи управления (УПУ) проверяет некоторое условие. Если это условие выполняется, то следующим будет выполняться оператор с именем, стоящим в поле преемника, в в противном случае оператор будет выполняться как пустой, т.е. за ним будет выполняться следующий по порядку оператор. При записи этого оператора в скобках указывается проверяемое им условие и после скобок-имя оператора - преемника, т.е. оператора, получающего управление в случае выполнения этого условия. Например, УЛУ ( / *3)Р ; .
К операторам управления следует отнести оператор останова (ОСТАНОВ). Этот оператор останавливает вычислительный процесс. Наличие хотя бы одного такого оператора в алгоритме необходимо, т.к. алгоритм обладает свойством конечности и его выполнение рано или поздно должно прекратиться.
Таким об разом,с помощью введенных операторов можно записать вычислительные алгоритмы, учитывая следующие правила:
алгоритм начинает свою работу с первого, по порядку оператора;
все операторы выполняются последовательно друг за другом; #
изменение порядка выполнения операторов можно осуществить с помощью операторов перехода;
алгоритм прекращает свою работу при выполнении оператора' останова.
Все эти правила будут выполняться независимо от способов изображения алгоритма. Существуют различные способы изображения алгоритма, но все они выступают лишь различной формой, в
которую вкладывается суть алгоритма, его содержание. Из всех известных способов изображения алгоритмов мы рассмотрим следующие наиболее важные и распространенные способы: формульно-сло-весный, язык операторных схем и блок-схемный. Каждый из этих способов обладает определенными достоинствами и недостатками и используется на определенном эгапе разработки алгоритма.
3.3. Форнульно-словесный способ записи алгоритмов
При этом способе записи алгоритма содержание последователь ных этапов вычислительного процесса задается в произвольной форме на естественном языке с испльзованием математической символики. Мы уже использовали способ при разработке алгоритма решения квадратного уравнения. Для большей строгости, удобства и обозримости выпишем этот алгоритм последовательно, сжато, без подробных пояснений, Теперь нам ясна необходимость ввода исходных данных, поэтому добавим шаг, осуществляющий ввод произвольной тройки действительных чисел.
Шаг I. Ввод коэффициентов А, В, С.
Шаг 2. Если Л фО , то перейти к шагу 8.
Шаг 3. Если ъ*0 , то перейти к шагу 12.
Шаг Ч. Если С* о , то перейти к шагу 13.
Шаг 5. Задать Р= :3 (решение неопределенное).
Шаг б. Вывод результатов: Х1>Хца Р.
Шаг 7. Останов.
Шаг 8. Вычислить I) = Ьг-ЧЛС .
Шаг 9. Если I) <- С , то перейти к шагу II.
Шаг 10. Вычислить
X, * I- Ь + №)/(24) ) *г - (- в - Г5)/(2А).
Задать Р--2 .Перейти к шагу 6.
Шаг II. Вычислить
задать Р - 0 . Перейти к шагу 6.
Шаг 12. Вычислить л1* -с/в .
Задать - Р - 1 . Перейти к шагу 6. Шаг 13. Задать Р-Н (решения не существует).
i
1 Перейти к шагу 6.
Мы немного изменили порядок шагов алгоритма, но ясно, что приведенный алгоритм решает ту же задачу, что и алгоритм в примере 2.3. '
Приведенный способ изображения алгоритмов общепринят в математике и понятен многим специалистам без специальной подготовки. С помощью данного способа можно описывать алгоритм с произвольной степенью детализации.
Но этот способ обладает и рядом недостатков. Прежде все-го.при данном способе записи алгоритма отсутствуют более или менее строгая формализация и наглядность вычислительного процесса. Достеточно сложный алгоритм становится труднообозримым. Кроме того,содержание каждого шага подлежит более подробному и строгому описанию. При такой записи довольно трудно разобраться в структуре всего алгоритма. Более формальной, строгой,компактной является запись алгоритма на языке операторных схем.
3.4. Операторные схемы записі алгоритмов
Операторная схема- это аналитическая форма записи алгоритма в виде последовательности операторов.
Операторы в операторной схеме изображаются определенными символами и снабжаются индексами в порядке их следования на схеме. В условном операторе перехода в скобках указывается проверяемое условие. Операторы отделяются друг от друга символом";".
Для записи операторОЕ мы будем испгльзовать обозначения, введенные в разделе 3.2. Для записи всего алгоритма будем использовать формальную структуру оператора, ; усмотренную в разделе 3.2.
Если арифметический оператор или оператор модификации можно полностью записать на схеме, то его будем записывать з виде Я - В , где б - выражение. Например, / " к *-> или
м; &. - 5-<1Х г ¡2. 2 ;.Рсли же действие записать
затруднительно,то можно записать Я (І, -<^) - обо?чачает оператор .вычислявший / и <Ьц . »1ногда указывается Я і , Аг } М}различные варианты арифметических операторов. В этом случае алгоритм сопровождается специальной таолицей расшифровки операторов.
Введенная формальная схема позволяет записывать алгоритмы по мощности совпадающие с алгоритмами, записанными с помощью формульно-словесного способа. Так алгоритм решения квадратного уравнения при таком способе записи будет выглядеть следующим образом:
ЪЬОЬ (Я, в, С); УП У (А-О) £6 УР \ АРНУА Ю :
УПУ ( В - О) ЛИНЧР; ВРНУЛН) УПУ (С - О) НЕТ КОР;
решнеопр: й*з; БПУ м ; нет кор: Р=у; ьпч м;Шйур : м< -с/з; ьпу м; К5УР: в= вг-чяс;
УПУ(Ь'О) Н'ОМПИ; В* «ЯГ; Яг* (-в-1-ы)/(2Ю; хг = (-в-ы)у(гй); Р«г; слу комлк:ы= <ГБ; х1 * -в/(2А);хг^ т/(Щ?--о-} м: печатыл!,^ ^осг.
Следует обратить внимание на использование имен операторов. В этой схеме мы использовали имена, несущие смысловую нагрузку. Это облегчает понимание и чтение алгоритма. Если изобразительное средство допускает такое использование имен, этим всегда следует пользоваться.
В литературе по программированию принят несколько другой вариант записи операторных схем. Операторы также изображаются символами с индексацией, но переходы изображаются стрелками. Отсутствие передачи управления от оператора слева к следующему оператору справа обозначается точкой с запятой. Для компактности записей з начале и конце стрелок ставятся номера,с помощью которых обозначены операторы - преемники управления. Более подробно с этим можно познакомиться в [1 _] .
Наш алгоритм будет выглядеть следующим образом:
. у г —15 I *-П
8боо, (л,в,с) уцуг (я*о) упч; (6*0) упу!, (с?о)
й3 Л£ЧХТЬв и,,!,^)^ уПУ, (0-0) й9 4*г~~';
Видно, что операторные схемы более компактны, поддаются строгой формализации, но требуют вести таблицу, в которой описываются действия, выполняемые операторами. Благодаря своей компактности алгоритмы, записанные с помощью операторных схем, более обозримы, а формальный характер их записи позволяет рассматривать операторные схемы как промежуточный этап при создании языков программирования. Но все же при разработке алгоритмов схемы используются редко. Здесь наиболее часто программисты
используют язык блок-схемы.
пуск-останов (вход-выход из подпрограмм). Определяет" начало, конец, прерывание процесса обработки данных;
комментарий к символу. Поясняет смысл данного символа.
Рассмотрим некоторые правила ведения блок-схем. Нормальным направлением линий потока считается направление сверху вниз и слева направо и стрелками не обозначается. Во всех других случаях обозначение направления стрелками обязательно. Линии потока проводятся к середине символа.
• Изменение линий потока возможно только по углом 90*. Мес-то слияния линий потока рекомендуется обозначать точкой.Пересечение линий потока Слияние линий потока
[< ТЕКСТА
3.5. Елок - схема - рабочий инструмент программиста
Блок-схема - это графическое изображение логической структуры алгоритма с помощью геометрических фигур. Эти геометрические структуры мы в дальнейшем будем называть блоками или символами. Внутри блоков записываются краткие указания о характере выполняемых ими действий. В зависимости от этих действий блоки имеют и различную геометрическую конфигурацию. Таким образом, даже не читая содержимое этих, блоков, по их внешнему виду можно судить о характере действий, и о структуре самого алгоритма в целом.
Существуют строгие требования к начертанию и выполнению блок-схемы, определяемые ГОСТом - 19427 - 74 и ГОСТом - 19428-74. Эти ГОСТы описывают перечень всех символов, их наименование, форму символов и размеры, а также правила их соединения в единую схему. Мы приведем здесь краткие выдержки из указанных правил. По назначению и характеру отображаемых функций символы делятся на основные и вспомогательные.
Основные символы используются для представления ввода-вывода данных и их обработки. Нам будут необходимы следующие символы:
'/■ / -ввод-вывод (операторы ВВОД и ВЫВОД);
- печать (оператор ПЕЧАТЬ);
решение (разветвление) указывает выбор направления выполнения алгоритма или программы в зависимости от некоторых условий (оператор УПУ);
- процесс обработки информации;
>
- линия потока. Изображает последователь-
, ность связей между символами (может быть
реализовано оператором БПУ).
Вспомогательные символы предназначены для пояснения отдель-ных элементов схемы и обозначения связей между ними.Мы будем использовать следующие символы: 5
О
соединитель. Указывает связи между прерванными линиями потока на одном листе;
межстраничный соединитель.Указывает связи между линиями потока на разных листах;
- 27 - .
(См. ), например так, как изображено на рис. 3.3.

Записи
внутри символа читается слева направо
и сверху вниз, независимо от направления
линии потока. Для удобства нахождения
символов на блок-схеме задаются их
координаты в виде цифр, букв и сочетания
букв и цифр. Координаты символа
проставляются вверху слева в разрыве
его контура. Если символу присвоен
идентификатор (наименование), то.он
помещается слева над символом. Справа
же может быть помещена краткая информация
- описание символа. Комментарий
помещается на свободном месте и содержит
любой текст.
Для соединения удаленных друг от друга блоков можно использовать соединитель. Для этого такая длинная линия потока разрывается и в начале и в конце обрыва помещается символ-соединитель внутри которого указывается буква, цифра или сочетание букв и цифр. Наименованием соединителя является номер (идентификатор) блока-преемника управления.
Рис. 3.1. Использование межстраничного соединителя
нет-
Рис. 3.2. Возможные способы записи блока-решения при числе выходов не более трех Если число выходов больше трех, можно поступать по-разному
Р' I р=г р --з ZEH.
Рис. 3.3. Изображение флока - решения при числе выходов более трех
Для более сложных задач сначала разрабатывают принципиальную блок-схему, которая отражает основные этапы алгоритма. После тщательного анализа принципиальной блок-схемы приступают к разработке детальной блок-схемы. В такой блок-схеме в деталях отражены всевозможные логические связи между этапами переработки данных и элементарные операции, выполняемые в них.
Работа нсд алгоритмом, как правило, всегда содержит этап разработки блок-схемы алгоритма. И пренебрегать этим этапом не следует, особенно начинающим программистам. Но и для профессионального программиста составление блок-схемы в процессе работы не является лишним. Запись алгоритма в виде блок-схемы позволяет упорядочить наши представления об алгоритме, увидеть его структуру, проследить все логические связи между блоками, выявить логические ошибки. Поэтому блок-схемы часто называют рабочим инструментом программиста.
Даже опытному программисту трудно с первого раза разработать правильную блок-схему. Часто процесс разработки алгоритма с помощью блок-схемы представляет собой ряд последовательных приближений к окончательному варианту. Поэтому ясно, что при работе с блок-схемой предпочтительно пользоваться не ручкой, а карандашом и резинкой.
В блск-схеме используются имена различных переменных. Их может быть очень много и их смысл бывает трудно удержать в памяти* Поэтому часто необходимо иметь таблицу, где поясняется физический смысл перемениесли таковой имеется, и её назначение. Очень облегчает эту задачу использование имен переменных таким образом, чтобы их имена напоминали об их физическом смысле.
Например: ШП.ДАВЛ, СКОР и т.д.
Такая информация будет очень полезна в дальнейшем при эксплуатации и развитии программы, реализующей данный алгоритм.
р |
- г |
ъ |
-- Ш |
|
|
*1 |
|
Для
примера запишем алгоритм решения
квадратного уравнения в виде блок-схемы
Приведенный алгоритм по результату эквивалентен описанным ранее, однако он требует несколько меньшего количества операций. Следует обратить внимание,что идентификаторы блоков расшифровываются следующим образом:
ДДК - два действительных корня. КК - комплексные корни. КО - корень один. КН - корней нет. КЕМ - корней бесконечное множество (неопределенное решение). Такой.выбор идентификаторов позволяет легче понимать блок-схему.
После того как блок-схема разработана, её необходимо проверить на правильность. Существуют формальные правила проверки блок-схем. Они относятся к любой блок-схеме независимо от алгоритма, который она списывает. Приведем их:
і. 3 блок-схеме должно быть не более одного блока без входящей линии потока (блок НАЧАЛО) и любой блок, не имеющий выходящейлинии потока,должен быть блоком КОНЕЦ (их может быть несколько).Все остальные блоки (за исключением блока решения) должны иметьровно один вход и один выход. . • \х
2. Для каждого блока должен существовать \хотя бы один путь по линиям потока,ведущий к нему от блока НАЧАЛО, и хотя бы один путь, соединяющий его с блоком КОНЕЦ. Если хотя бы одно из этих правил не выполняется, то можно формально заключить, что блок-схема составлена неверно.
Если же блок-схема удовлетворяет этим двум требованиям, необходимо убедиться,что она логически правильна,!.е.убедиться,что -она описывает алгоритм,который делает именно то ,что необходимо.
4. ОСНОВНОЕ СТРУКТУРНЫЕ ЭЛЕМЕНТЫ АЛГОРИТМОВ
4.1. Линейные и ветвящиеся участки алгоритмов Наиболее часто в алгоритме существуют группы операторов, которые и расположены последовательно и выполняются последовательно. Такая группа образует линейную ветвь алгоритма. Характерным признаком линейного участка является отсутствие имен у всех операторов, кроме первого,и преемников у всех операторов,кроме последнего.
В линейном участке имя первого оператора выступает как имя всей последовательности, как имя одного составного оператора (действия), который мы разбили на отдельные части для удобства выполнения или более полного описания действия.
і
Типичное изображение линейного участка приведено на рис.4.1.
Линейность участка определяется как самой задачей,так и теми возможностями (тем набором операций), которыми располагает исполнитель. Так,если исполнитель знает как решить задачу, то вся она условно может быть объявлена одним большим, сложным, но известным оператором.
Далее для конкретизации действия такой оператор распадается на ряд подзадач: ввод исходных данных, преобразование информации, вывод результатов
Рис. 4.1.
■ ш: печйть су); остянОд;.
(но и на этом уровне алгоритм, как правило, будет линейным). Линейный участок может содержать любые операторы кроме операторов передачи управления. На блок-схеме он имеет только один вход и только один выход.
Часто в зависимости от исходных данных либо от промежуточных результатов (зависящих от исходных данных) может изменяться последовательность выполняемых операторов. В этом случае алгоритм содержит оператор проверки условия и выбора пути в вычислительном процессе в зависимости от выполнения условия. Этот оператор образует как бы вершину, из которой выходят различные линейные ветви^см. рис. 4.2). Разветвление связано с реализацией в алгоритме различных случаев, которые могут появляться при реализации алгоритма.
Основной, внутренней причиной разветвления, является возможность группировки исходных данных в отдельные классы (группы),, для каждого из которых должен быть реализован один путь в алгоритме. Например,коэффициенты квадратного трехчлена можно разделить на группы следующим образом:
а) корней не существует ( СФО- любое, Я^О, );
б) корней бесчисленное множество (с^о, я-о, 6 = 0 );
в) корень один ( Л = О, в*0- любые, С - любые);
г) корки действительные (»=0, В^-1/ЯС ?0>Я,Ъ,С - любые);
д) корни комплексные (Я*С, Вг- 4НС-О, II, ь, с - любые).
В алгоритме решения квадратного уравнения присутствуют все пять ветвей, но для конкретного набора исходных данных будет реализовы-ваться только один. Таким образом,в алгоритме для каждого набора исходных данных выделяется последовательность операторов, которые будут выполняться - вычислительный процесс для данного набора. Все остальные операторы для исполнителя будут невыполняемыми (вне поля зрения), недоступными, несуществующими .
Для другого набора вычислительный процесс может измениться, другим примером ветвящегося процесса является вычисление функций, заданных различными аналитическими выражениями на различных промежутках
Г 1Р4(Х) х^а
I % ,х) х г В Алгоритм можно записать в виде:
ВЫ.-01А); Ш (Л*<*-)^; У = ь (л;; ы/у Л/1' м: УПъ
\х* ь) *и\ у= Ъ(Х)\ цпу „И1 ; мь : у и) •
В этом алгоритме ^(^),%^), %{*■) могут быть сколь угодно сложными.
Пусть заданы числа 6> с . Требуется построить алгоритм выбора минимального. Он может быть записан в виде
ЬЛУ(и.-У'У 1&*с)м1; мз: У -- с; 511У 'лг \ м I: у - 6; ЬПУ м&; м: упу {&?с) мз\ Ш -.печать (у); остянов;.
4.2. Общая структура циклического процессаПредположим, что каждому элементу массива из 4 чисел необхо-димо присвоить значение равное I. Наиболее просто такая задача ре-шается последовательностью операторов -1 '> %-^>
Если количество элементов будет равно 100, то аналогичный метод будет очень громоздким, а если необходимо I присвоить переменному количеству элементов (М), то этот метод вообще неприменим.
Анализ выписанных операторов показывает, что они выполняют однотипные действия и отличаются только индексом элемента. Напрашивается вопрос: как записать один оператор, но так, чтобы вместо выполнения 4 оп>--паторов по I разу конструируемый оператор выполнялся бы 4 раза, т.е. чтобы пои каждом выполнении конструируемый оператор выполнял бы действие последовательно I, 2, 3, 4 операторов.Сделаем эквивалентное преобразование операторов
*-у; % - *, "( -1 Ч- х> 1~ «•'*•<•; 1 > 1 г ¿¿"-¿1
Мы видим, что два оператора ( I и ь ■■ ) повторяются 4 рч-за, поэтому мы их выпишем I раз, а операторами передачи управления заставим их выполняться 4 раза. Алгоритм запишется
Последовательность многократно выполняемых операторов называют циклом, а вычислительный процесс, содержащий цикл, называют циклическим. Операторы цикле содержат переменные, изменяющиеся при каждом прохождении цикла; яти переменные называются переменными цикла. Очень часто среди переменных цикла выделяется одна главная,
ведущая, которая определяет, как правило, значения остальных.
эта переменная называется параметром ( в некоторых случаях индексом) цикла. В циклическом процессе можно выделить следующие 4 группы операторов:
а) операторы,формирующие начальные значения переменнымцикла;
б) операторы,выполняющие преобразование информации (оничасто называются областью цикла, телом цикла);
в) модификатор параметра'цикла. этот оператор изменяетзначение параметра цикла, чтобы при новом прохождении цикла вы-бирались новые, другие, следующие значения;
проверка условия выполнения тела цикла. обычно это условие содержит переменные цикла (наиболее часто-параметр) и при некоторых значениях условие выполняется, а при других условие не выполняется. при построении цикла операции, независящие от переменных цикла, желательно выносить из цикла.
так, если элементам массива требовалось бы присвоить зна-чение Ип. {6.Л ) *■ с , то алгоритм
р: л,- * ал (о-б +Ж/г)* с1; **<>.*; У'1У(±*У)Р;.
заставил бы У раз вычислять одно и то же выражение (иногда довольно трудоемкое). более рациональным является алгоритм 1~-1> М* кЛ(&3*Я/2)+£*; ^■■йг--Х> ¿-¿+1; улу(14У)Р;, все переменные цикла, значения которых используются для формирования других переменных должны быть определены или в теле цикла или до входа в цикл. например, в операторах ^ '-4*6^
С- *£ переменные ^ и С должны быть определены ранее.
следует принять за правило проверку определенности переменных цикла. это значение должно формироваться раньше его использования в том же вычислительном процессе.типичная ошибка -формирование значения в одной ветви, а его использование в д гугой.
следует обратить внимание на обозначение стандартных !ун.-:ций и констант, появляющихся в алгоритме - оно должно .сыть понятным исполнителю. например , С для эвм никак не связано п иигчтм 2. &1 Ь2 И . если константа многократно используется в алгоритме, то для нее вводят ос означение (лучше сказать переменную .значением которой является константа). каждый цикл необходимо проверить на правильность построения и ''ункциониоования.
теоретической предпосылкой для анализа циклического процесса является метод математической индукции. этот метод требует выполняемость цикла для первого шага, что предполагает и определимость переменных и правильное преобразование информации (правильную последовательность операторов). считая, что выполнился цикл с одним значением параметра, проверяем его выполнимость для следующего. особое требование предъявляется к условию выхода из цикла,т.к. этот оператор определяет количество повторений цикла. в этом операторе может быть записано условие, которое или всегда выполняется,или никогда не выполняется - например, упу ( <2. ^ 6 ) р • > если ^ и 3 не являются переменными цикла. второй типичной ошибкой является неправильный выбор помеченного оператора. например, алгоритм
р; I =у; &(*1'> упу (г* ч)Р \ приведет к бесконеч-
ному циклу,т.к. при проверке условия I всегда будет равно 2 . в этом примере мы блок начального формирования включили в тело цикла ошибочно., неправильно.
по количеству реализаций, прохождений циклы можно разделить на циклы с возможным нулевым количеством и циклы с обязательным выполнением тела. в первом случае в зависимости от переменных цикла тело может не выполняться ни одного раза и,следовательно, после формирования начальных значений должен стоять оператор упу. этот оператор должен иметь условие (в этом случавшие продолжения цикла, а выхода из цикла и в качестве метки в этом операторе выступает метка оператора, расположенного после цикла. он является первым оператором цикла и для возвра-та к нему последним оператором цикла должен быть ьпум, где М ~ метка упу (т.е. упу должен быть помеченным). таким образом, •добавляя возможность иметь "пустой" (невыполнимый)цикл,мы приходим к необходимости добавления "лишнего" оператора (бпу;. во втором случае операторы цикла выполняются хотя бы один раз, т.е. проверка условия стоит после операторов преобразования информации. наиболее часто в цикле существует специальный оператор модификации параметра, но иногда он,как и другие переменные цикла,изменяется операторами преобразования информации.
оператор модификации может быть расположен либо после тела цикла,либо до него. в первом случае начальные значения параметра формируются для первого прохождения, а во втором - на шаг меньше.
в теле цикла могут быть опепаторы условной или безусловной передачи управления, прекращающие выполнение цикла,т.е.
операторы.выводящие из цикла. Простейший пример - найти номер первого отрицательного элемента в массиве 100 чисел (для простоты будем считать, что он существует) і і\ Р: у л у (а,- ¿0) м; і-с+і -} упу (і * юс*) р; м: ...
После работы алгоритма переменная і будет иметь искомое число. Однако, если все числа положительные, то мы не найдем отрицательного числа, но все равно после окончания цикла попадем на оператор /и и.следозательно, решим задачу неверно. Поэтому лучше алгоритм изменить
і й: ипуісь -о)лі\ і -г * і; у/іщі *юе)р; печлгь '('о'гриц-істельных эммангоб нет), огтяноь • м: ...
Вместо печати и останова может быть любая ветвь,т.е. мы имеем
разветвляющийся пооцесс.
4.3. Виды циклов
По структуре циклы можно разделить на простые и сложные. Простым циклом называется такой цикл, который не содержит внутри себя других циклов. В предыдущем пункте мы рассматривали структуру такого цикла. Сложным циклом называется такой, который внутри себя содержит, имеет хотя бы один цикл (который в свою очередь может быть сложным). В этом случае внутренний цикл необходимо рассматривать как сложный оператор, целиком принадлежащий внешнему циклу. Подготовка начальных значений для переменных внутреннего цикла осуществляется операторами внешнего цикла. Параметры внутреннего и внешнего цикла не могут быть одной и той же переменной.
Из внутреннего цикла возможен выход во внешний цикл, а обратная передача управления невозможна - вход в циьл должен осуществляться только через операторы подготовки начальных значений. В сложном цикле могут сыть параллельные вложенные циклы. Параметрами этих циклов может выступать одна и та же переменная, но для каждого цикла должны быть свои операторы Формирования начальных значений.
¡¡0 количеству шагов, реализаций, проходов циклы делятся на циклы с известным количеством и циклы с неизвестным количеством повторений.
Циклы первого типа связываются с переменной, которая может принимать только целочисленные значения и которая с каждым похождением цикла изменяет свое значение на одну и -у же величину. Обычно параметр цикла "считает" номер прохождения такого цикла, поэтому они часто называются циклами со счетчиками. Пусть необходимо вычислить ^(0:01)> }(о.02)> . .. /(0.^5) . Наиболее просто алгоритм записать в виде: Х=о.а; и:? )А>\ П£Ч/П'о^)3 X=*>0.«; У/?У(-•• )Р . В операторе УПУ не выписано условие продолжения цикле, потому что оно не совсем элементарно. Действительно УПУ (х р с.ЗЬ )Р записать нельзя,так как из-за приближенного представления ни при каком шаге X не будет точно 0.55 . Величина,полученная сложением 35 раз по Сб'Лможет быть и немного меньше 0.35 и немного больше 0.35. Поэтому, условие продолжения можно записать УПУ (IX ~0-.д51'О.ССэ' )р, считая, что погрешность не превзойдет 0.005. Более просто цикл можно организовать следующим образом;
1=Г> р;р=Л0.О1-1); печять(п; 1 = ^1,>Ут(с±35)Р .
Сложение целых чисел исполнитель должен выполнять точно.
В общем случае цикл со счетчиком имеет структуруI *ух; р: . . , ; С~с+Уг-\ зпу(с±Уз)Р .
В этом случае У1 называется начальным значением счетчика, Уз -его конечным значением, а У& - шагом изменения. Указанная структура цикла предполагает выполнение цикла хотя бы один раз. При УЗъаЧколичество повторений определяется как [{У3-У^)/У2,\*^, где [ X ] -целая часть числа X •
Циклы с неизвестным количеством повторений имеют различные логические условия выхода из цикла, содержащие переменные цикла, значения которых изменяются при каждом прохождении цикла.
Из большого разнообразия условий выхода часто выделяют условие сходимости параметра. В этом случае значения параметра, вычисленные при последовательных прохождениях цикла,рассматри- . ваются как числовая последовательность XI, Щ , • • •>•*»., которая может сходиться при п. — •**
Циклы этого типа обычно реализуют формулы
хп^-- Л-*»,*.); 1**1* >.
и называются итерационными циклами. Следует сразу же подчеркнуть, что хотя В записи формулы фигурируют многие величиных^ у £ . . ^ , однако такая интерпретация является нет»- , пильной, неосуществимой ,т'.к. мы не знаем количества повторений. Более правильной является схема,где по "предыдущим", старим значениям л и I вычисляется "новые" значения ь и Л ,
которые для нового шага станут старыми и т.д. Алгоритм может быть записан
В этом алгоритме мы в качестве € взяли допустимую погрешность определения корня.
В теле цикла любого вида могут быть дополнительные условия выхода из цикла, при выполнении которых цикл прекращается. Например, найти в массиве из 100. чисел номер первого элемента, модуль которого больше 10 (если таковой существует)
р- УПУ (I ал? ю) м ; /"•■-1*1; упу (/ * 100) р;печать С лн&внп опу... ; м; ...
Таким образом,цикл может давать ветвящийся процесс при выходе из тела цикла.
3 , ОСНОВНЫЕ ВЫЧИСЛИТЕЛЬНЫЕ АЛГОРИТМЫ 5.1. Алгоритмы обработки массивов
Сумма элементов массива. Требуется определить величину
по формуле и.^ * ■ ■ ■ г Ягу.
Для решения задачи необходимо образовать цикл, при каждом прохождении которого к уже накопленной сумме должен добавляться новый элемент массива, т.е. к прежнему значению £■-и, * и.е. * ■ ■. «• и.к добавляется элемент :сСгх , Оператором,реализующим это действие является 5 »• о' ♦ и; , при переменном, изменяющемся на каждом шаге значении с , которое выступает параметром цикла. Для! того, чтобы после окончания цикла 6' содержало только и1'^г.г "' * 'V,необходимо, чтобы в начальный момент (до первого сложения) значение 6' было равно 0. Алгоритм можно записать в виде
3=0; 1 = 1; м: &+£ц ; ¿-¿'1-4; учу (/*у)м;.
Оператор I £ устанавливает начальное значение для номера элемента массива; условный оператор обеспечивает повторение цикла, необходимое количество раз пои У у с . Оператор О-м0же" """*«ен оператором 3=и., тогда изменятся и запись алгоритма
Незначительное изменение алгоритма существенно изменило его запись, для того, чтобы алгоритм был применим и при У I условный оператор располагается первым оператором в теле цикла,т.к. цикл в этом случае не выполняется ни одного раза. После оператора модификации теперь располагается оператор безусловной передачи управления для прохождения цикла. Меткой М помечен оператор,следующий после цикла. Заметим, что в первом алгоритме дополнительно выполнялся один оператор $ = 0 , а во втором Л- і выполняется дополнительно оператор 61)1 м 1 ; .
Скалярное произведение векторов и, и 6 определяется по формуле 3= аі61*і<-а6г* ■■■ + 6-у 6у Л здесь параметром цикла выступает номер элемента массива. Основной оператор тела цикла имеет вид $= 3 *•&*'& , поэтому начальным значением для 3 будет 0. Алгоритм можно записать в виде
5-е; ¿=1; м'• £- з+бъЪл і*і+£\ упу{і^л')М;.
С точки зрения структуры алгоритма приведенные алгоритмы -эквивалентны, это циклы суммирования. Если положить 4' - і , то алгоритмы будут совпадать, т.е. первая задача может рассматриваться как частный случай второй.
Произведение матрицы о£ на вектор 6 дает в резуль-тате вектор С , каждый элемент которого вычисляется по форму-ле -
где с'= {■> -<-іУ . Очевидно, что алгоритм решения задачи должен содержать цикл для вычисления (формирования) каждого элемента массива с . Этот цикл по і должен повториться (выполниться) У раз. В свою очередь,вычисление любого элемента С/ представляет скалярное произведение вектора ¿2-, являющегося 1-ой строкой матрицы об , на вектор 6 \ осу-г ществляется циклическим процессом по предыдущему алгоритму. Таким образом,произведение матрицы на вектор осуществляется двойным циклом
у/іу{/*-^): } і /'і; упу(і і .
(В алгоритме фигурными скобками выделен внутренний цикл.)
для определения максимального элемента массива необходимо знать его номер (положение в массиве) и его величину. Для поиска такого элемента необходимы попарные сравнения элементов массива и для сокращения работы мы введем понятие условногс текущего максимума, т.е. введем переменнув, которая после обработки I элементов массива будет содержать максимальный из них. При добавлении £>/ элемента мы должны сравнить
этот новый элемент с имеющимся промежуточным максимумом. Этот максимум может остаться прежним, если (¿-¿ + 1 "мало" или поменяется, если в.,\,1 оказалось больше,чем все Лля правильной работы алгоритма необходимо первоначальное формирование текущего максимума, которое можно осуществить двумя методами. В первом методе выбирается очень малое по величине число (например, М , где М - наибольшее по модулю число, с которым может оперирсвать исполнитель). Во втором случае берется значение первого элемента массива в качестве начального значения условього максимума и сравнение может начинаться со 2-го элемента. Учитывая, что массив может содяржать один элемент при сравнении,начияач со 2-го, необходимо изменить положение условного оператора в цикле, поэтому более целесообразно начинать сравнение с первого элемента массива. Наряду с переменной, содержащей значение текущего максимума, необходимо ввести еще одну переменнув, в которой будет содержаться номер максимального элемента. Иногда текущее значение максимума посылается в качестве значения, например, первого элемента массива, однако такое изменение информации очень часто приводит в дальнейшем к ошибкам. Алгоритм может быть записан в виде
После работы алгоритма переменная В будет содержать значение максимального элемента, а переменная # - его номер.
-Упорядочение массива по возрастанию (или по убыванию) можноосуществить различными методами. Одним из эффективных методовявляется метод "вставки", в котором последовательно упорядочи-вается всё большая часть массива,т.е. йг / и.^ 0.^ / аг схл ...При каждом прохождении цикла в упорядоченную часть добавляетсяодин новый элемент. Считая, что Й<.» %«'■•■ > уже упоря-дочено, ишется место для й.,-ц в отрезке массива. Для этогопоследовательно сравнивается на каждом шаге "вставленный"элемент с предыдущим и если необходимо их меняют местами. Встав-ленный элем.. бк всплывает среди упорядоченных элементов
до своего места. Все элементы с большими величинами опустятся на одно положение вниз. Алгоритм можно записать
: -1; Ш: /. £; л£: у ну (и- * й^н ) м; £ - -
Для того,чтобы обменять содержимое &• ч между собой, .iC~
пользуя операции пересылки, необходимо вспомогательное поле te ,куда мы временно спрячем одно значение, освобождая поле ¿¿v длясодержимого Если бы мы записали ú¿ - ufíij - (у , то
очевидно, что старое значение «£,• будет потеряно и в обоих полях будет одно и тоже .значение.
Внешний цикл будет выполняться У -I раз и мы будем считать, что этот алгоритм не будет применяться к массиву из одного числа. .Можно снять это ограничение, но оператор УПУ (¿>¿ У-і ^поставить первым в теле внешнего цикла. Если входной массив уже упорядочен, то каждый внутренний цикл будет выполняться I раз, если же исходный массив упорядочен по убывание,то внутренний цикл будет выполняться с раз, т.е. цикл будет работать максимальное время. Мы рассмотрели алгоритмы обработки произвольного массива, т.е.,если необходимо определить сумму элементов массива .і , а не й, то в алгоритме заменится только обозначение массива. Менее очевидно,что построенные алгоритмы легко применить к части массива в этом случае изменяются только операторы начального формирования параметра цикла. Если же необходимо рассматривать чередующиеся элементы массива (например, только четные,каждый пятый и т.д.), то изменяется только оператор модификации.