Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Понятие переменной в программировании. Виды и типы переменных (ТЕОРЕТИЧЕСКИЕ АСПЕКТЫ ИССЛЕДОВАНИЯ ПЕРЕМЕННЫХ В ПРОГРАММИРОВАНИИ)

Содержание:

ВВЕДЕНИЕ

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

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

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

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

- рассмотреть теоретические аспекты исследования переменных в программировании;

- изучить отличие переменной от константы.

Объект исследования - переменные.

Предмет исследования - исследование понятие переменной в программировании, виды и типы переменных.

Структура работы состоит из введения, основной части, заключения и списка литературы.

Теоретической и методологической базой данной работы послужили труды российских и зарубежных авторов в области информатики, материалы периодических изданий и сети Интернет.

ГЛАВА 1 ТЕОРЕТИЧЕСКИЕ АСПЕКТЫ ИССЛЕДОВАНИЯ ПЕРЕМЕННЫХ В ПРОГРАММИРОВАНИИ

1.1 Понятие и типы переменных

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

Переменная характеризуется:

  • Именем («обозначением ячейки памяти»)
  • Значением (данными, содержащимися в переменной в конкретный момент времени)
  • Типом (определяющим: а) какие значения может принимать переменная; б) какие операции можно производить с этими значениями; в) как данные представлены в памяти компьютера)

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

Простые типы

Дискретные (можно перечислить возможные значения):

  • целые (integer, longint)
  • символьный (char)
  • логический (boolean)
  • диапазон (часть значений стандартного дискретного типа, например, 1..100)
  • перечисляемый (явно перечислены все допустмые значения)

Вещественные (real, double, extended) — служат для представления действительных чисел с ограниченной точностью.

Структурированные типы

  • Массив (фиксированное количество данных одного типа)
  • Строка
  • Запись (связанные данные, в общем случае, разных типов)
  • Множество
  • Файл (данные одного типа, хранящиеся на внешнем носителе)

var 
  имена переменных : тип;
...
  имена переменных : тип;

Например:

var 
  a, b, c: real;
  i, n: integer;
  f: boolean;

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

Оператор ввода нужен, чтобы компьютер получил исходные данные. В программе на Pascal он записывается следующим образом:

read(переменные);

или

readln(переменные);

При выполнении оператора программа будет приостановлена, пока пользователь не наберет на клавиатуре значения и не нажмет клавишу «Enter». Затем введенные значения будут помещены в переменные, указанные как параметры процедуры ввода. Например, при выполнении оператора

read(a, b);

компьютер будет ожидать ввода двух значений, которые затем будут помещены в переменные a и b.

Операторы read и readln отличаются тем, что во втором случае после ввода данных будет переведена строка, т.е. последующие сообщения компьютера будут выводиться с новой строки.

Оператор вывода нужен, чтобы компьютер показал результаты работы программы или какие-либо вспомогательные сообщения. В программе на Pascal он записывается следующим образом:

write(выражения);

или

writeln(выражения);

При выполнении оператора вычисляются значения выражений, после чего эти значения выводятся на экран монитора. Например, при выполнении оператора

write(a + b, c);

на экран будет выведена сумма переменных a и b, а также значение переменной c. Если нужно вывести на экран какое-либо текстовое сообщение, его нужно заключить в апострофы (одиночные кавычки):

write('Нет решения');

Операторы write и writeln отличаются тем, что во втором случае после вывода данных будет переведена строка, т.е. последующие сообщения компьютера будут выводиться с новой строки.

Для того чтобы переменная получила или изменила свое значение, используется оператор присваивания. В Pascal он записывается следующим образом:

переменная := выражение;

Тип переменной должен совпадать с типом выражения либо быть «более широким» совместимым (т.е. вещественной переменной можно присвоить значение целого выражения; строковой переменной можно присвоить значение символьного выражения).

Компьютер сначала вычисляет значение выражения в правой части оператора присваивания, затем помещает его в переменную, указанную слева от символа присваивания «:=».

Например, при выполнении оператора

x := a + b;

переменная x получит значение суммы переменных a и b. При выполнении оператора

n := n + 1

значение переменной n увеличится на единицу.

При присваивании переменной нового значения старое будет потеряно безвозвратно. Например, после выполнения операторов

a := b;

b := a;

обе переменные будут иметь одинаковые значения, равные тому, которое имела переменная b.

Рассмотрим, как составить простую программу, выполняющую какие-либо вычисления. Для этого нам нужно:

  1. Проанализировав условие задачи, выделить исходные данные и результаты. Выбрать для них имена переменных (если они не заданы в условии). Определить тип данных.
  2. Построить математическую модель задачи — описание в виде набора математических соотношений.
  3. Разработать (или подобрать из известных) алгоритм решения задачи — последовательность действий, приводящую от исходных данных к результатам за конечное число шагов. (Не забудьте, что сначала компьютер должен получить значения исходных данных, а после нахождения результатов — вывести эти результаты на экран).
  4. Если в процессе решения используются промежуточные данные, выбрать имена переменных и определить их тип.
  5. Записать программу в соответствии с правилами синтаксиса языка программирования (в нашем случае — Pascal).

Рассмотрим простейший пример.

Задача

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

Решение

1) Определим исходные данные и результаты задачи. В данном случае они явно указаны в условии: исходная величина — радиус, результаты — длина окружности и площадь круга. Используем для них традиционные обозначения: R, L и S, соответственно. Все эти переменные могут принимать как целые, так и дробные числовые значения, поэтому следует использовать вещественный тип данных, например, Real.

2) Математически задача описывается известными формулами:

L = 2 ⋅ π ⋅ R  
и S = π ⋅ R2   

3) Алгоритм в данном случае предельно прост:

  1. Ввести значение радиуса.
  2. Вычислить длину окружности по формуле [1].
  3. Вычислить площадь круга по формуле [2].
  4. Вывести значения длины окружности и площади круга на экран.

4) При вычислениях нам (точнее, компьютеру) потребуется значение π. Вообще говоря, практически все реализации Pascal имеют встроенную константу PI, но мы объявим подобную константу самостоятельно.

5) Теперь запишем программу:

program circle; { Имя программы можно выбирать произвольно }
{ В фигурных скобках записываем комментарии — этот текст компьютер пропускает }
  const p = 3.14159265358; { Объявление константы }
  var L, R, S: Real; { Все переменные одного тип }
begin
  write ('Введите величину радиуса:'); { Выводим на экран пояснение }
  readln (R); { Вводим значение и переходим на новую строку }
  L := 2 * p * R; { Операция умножения обязательно указывается! }
  S := p * R * R; { Можно записать S := p * sqr(R); }
  writeln ('L=', L:10:3, ' S=', S:10:3); { Выводим поясняющий текст }
  { и значения переменных. Для значений указан }
  { формат: всего 10 знаков, из них 3 — после точки. }
end.

1.2 Переменные в программировании

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

Переменная гибка:

  • в ней можно хранить информацию;
  • можно из неё извлекать информацию, что не повлияет на значение самой переменной;
  • в неё можно записать новые данные.

Причем, эти действия можно выполнять практически сколько угодно раз. Из названия ясно, что переменная – вещь непостоянная. Например, в языке программирования PHP переменные существуют или содержат в себе значение исключительно во время работы скрипта. Как только завершается исполнение скрипта, так и существование переменных прекращается. То есть при переходе с одной страницы web-сайта на другую, переменных и их значений прежней страницы уже нет. Это кроме случаев, когда нужные значения специально передаются другой странице.

Переменные появились с первыми языками программирования. Результат работы любой программы сводится к выполнению действий над какими-либо данными. Напомним, что память (memory) – это последовательность байтов (byte), каждый из которых принимает значения от 0 до 255. Так как байтов неимоверно много, единственный способ различать их - это присвоение каждому из них порядкового номера. Так и есть. Каждый байт оперативной памяти доступен процессору через его порядковый номер. Этот порядковый номер называется адресом байта.

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

С первыми языками программирования появилась полезная возможность связывания определенного участка оперативной памяти с символьным названием (набором символов). По сравнению с адресом название переменной может отражать содержимое этого участка памяти. Но имя переменной не единственная вещь, которая определяет переменную. Процессор может обрабатывать три вида данных: байт, слово и двойное слово[7;15].

(Термины «слово» и «двойное слово» здесь используются в узкоспециальном смысле, отражая собой размер участка памяти, выделенного под переменную.) Поэтому определение вида переменной в языках нижнего и среднего уровней происходит обычно указанием типа переменной. Эти два свойства переменной (название и тип) определяют нужный участок памяти и способ его использования. В большинстве случаев именно тип переменной определяет сколько байтов памяти захватит переменная. Например, переменной типа BYTE присвоено имя A. Процессор по названию переменной (А) определяет её место в памяти и при извлечении значения этой переменной воспользуется командой, предназначенной для извлечения байта (не слова и не двойного слова).

В общем случае, переменная – это поименованный участок оперативной памяти, используемый для временного хранения данных. В зависимости от языка программирования, объявление переменной может сопровождаться указанием его типа. Обычно в языках высокого уровня тип не указывается. Синтаксические различия между языками проявляются как раз в объявлении переменных. В C и C++ необходимо указывать тип, в PHP используется префикс $.

В современном мире программирования программист должен знать не только имя и тип переменной. Также существуют понятия пространства имен и область действия переменной. Представьте, что создается программа, в которой используются несколько переменных. Имена этих переменных составляют список, который определяет пространство имен. Представим, что в ходе создания программы мы, по ошибке, объявили две переменные с одинаковыми названиями. При попытке запуска программы его компилятор сообщит об этой ошибке. Это было бы невозможно, если бы компилятор не контролировал переменные. То есть контроль безупречности пространства имен возлагается от программиста на компилятор; что облегчает процесс создания и отладки программы. На практике, приведенный пример не во всех языках приводит к ошибке. Каждый компилятор (или интерпретатор) имеют собственные требования к пространству имен. То, что является ошибкой в одном языке (в данном случае C или C++), в других языках ошибкой может не быть.

Если раньше программы были небольшие и их исходный код располагался в одном файле, то сейчас текст кода может состоять из нескольких файлов. И запомнить уникальное имя каждой переменной, использующейся в программе, становится практически невозможным. Поэтому (и не только) было введено понятие области действия (или области существования) переменных. Область действия – понятие абстрактное. Это понятие применяется только в языках среднего и высокого уровней. Целью применения области действия является разделение пространства имен на несколько независимых частей. Так в программе могут существовать несколько переменных с одинаковыми именами и типами, не мешаю друг другу. Начинающему идея разделения области действия в пределах отдельных файлов исходного кода программы должна быть более понятна. Например, этот подход используется в PHP. Это означает, что переменная, объявленная в одном файле, может быть абсолютно недоступна в других файлах. Например, мы можем объявить переменную с именем MyVar в нескольких файлах проекта, и это не будет ошибкой.

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

1.3 Инкремент и декремент

Если необходимо изменить значение переменной на 1, то используют инкремент или декремент.

Инкремент - операция увеличения значения, хранящегося в переменной, на 1.

Пример:

x++; // значение переменной x будет увеличено на 1


Декремент - операция уменьшения значения, хранящегося в переменной, на 1.

Пример:

x--; // значение переменной x будет уменьшено на 1


Инкремент и декремент относятся к операциям присваивания. При использовании декремента и инкремента совместно с оператором присваивания "=" применяют постфиксную (x++) или префиксную (++x) запись. Первой выполняется префиксная запись.

Примеры:

y = x++;


Предположим, что в переменной x хранилось значение 5. Тогда в y будет записано значение 5, после чего значение переменной x будет увеличено на 1. Таким образом, в y будет 5, а в x - 6.

y = --x;


Если в x хранилось значение 5, то сначала будет выполнено уменьшение x до 4, а затем это значение будет присвоено переменной y. Таким образом, x и y будет присвоено значение 4.

ГЛАВА 2 ОТЛИЧИЕ ПЕРЕМЕННОЙ ОТ КОНСТАНТЫ

2.1 Калькулятор с константами

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

Согласитесь, что выражение
2 + 3 = 5
достаточно серьезно отличается от выражения:
a + b = c

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

Численные выражения, хоть что с ними делай, дают в итоге только численный результат. [14;157]

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

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

Так же и в компьютерной грамотности. Можно говорить сначала о самом низком уровне абстракции, например, об арифметике в программировании.

Калькуляторы дружат с константами

Например, возьмем калькулятор. Что он может делать? Достаточно много: выполнять ряд арифметических и даже более сложных действий.

  • Вводим на калькуляторе первое число, например, «2»,
  • нажимаем на знак «плюс»,
  • вводим второе число, скажем, «3» (см. рис. 1),
  • и затем нажимаем знак «=».

Что получим? Очевидно, значение «5». Арифметика. Но с использованием компьютерной техники – калькулятора.

константа на калькуляторе

Рис. 1. Суммирование констант 2+3 на калькуляторе (Windows 7)

Не будем дальше углубляться в возможности калькуляторов. Например, можно было бы рассмотреть более сложные калькуляторы: для инженеров, для программистов, для обработки статистических данных и пр. (см. рис. 2).

калькуляторы в Windows 7

Рис. 2. Некоторые виды калькуляторов, имеющихся в Windows 7[7;25]

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

2.2 Программы с переменными величинами

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

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

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

a + b = c,

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

C = A + B.

Здесь не случайно я пишу строчные (заглавные) буквы вместо прописных (маленьких) букв:

во-первых, чтобы отличить алгебру от программирования, а

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

Так как вместо прописных букв латиницы у нас делали строчную кириллицу, иначе где еще взять коды для русских букв?! Это связано с тем, что многие трансляторы с языков программирования у нас в стране лишь адаптировали с западных аналогов, а не разрабатывали с нуля. А там, откуда все это копировалось, русского языка не было по понятным причинам. Хотя были и примеры наших «родных» языков программирования.

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

Почему стали в программировании писать наоборот, а именно стали писать C = A + B? Трудно сказать. Так сложилось, что сначала надо было указывать результат, и лишь потом действие.

Что же дает подобное «волшебное» выражение  с буквами вместо цифр для программирования? Казалось бы, в чем разница между константами и переменными:

5 = 2 + 3 (напишем наоборот лишь для сравнения) и

C = A + B ?

константы и переменные

Рис. 3 - Рисунок 2+3

Давайте разберемся. Что может быть результатом сложения 2+3? Большинство ответит, конечно, «5». И хоть это почти правильный ответ, пожалуй, мы с этим согласимся.

Почему почти? Да потому что это правильный ответ для десятичной системы исчисления. Для четверичной системы исчисления, в которой используются только цифры от 0 до 3, ответ был бы «11», да-да, именно одиннадцать, можете не сомневаться. А в пятеричной системе исчисления, где добавляется еще цифра 4, ответ был бы «10».

Но в любом случае, о какой бы системе исчисления мы не говорили, результатом 2+3 всегда будет одно и то же число (константа). В десятичной системе (вернемся к ней теперь надолго), это «5», и только «пять».

А сколько будет A + B? Ответ очевиден: все зависит от того, чему равны A и B. Значит, результатом 2+3 всегда будет 5, а результатом A+B будут разные значения в зависимости от величин A и B.

Достаточно очевидно. Ну и что, что 5 – константа, а тут переменная? А то, что переменные – это другой уровень абстракции. За счет A+B мы теперь можем получать множество разных значений[6;22].

Как могут использоваться выражения с переменными  величинами

Допустим, A – это вес одного товара, а B – это вес другого товара. Значит, A+B – это суммарный вес обоих товаров. Значит, используя выражение C=A+B, программист может запрограммировать автоматическое суммирование двух весов.

Как он это сделает?

  • Например, сначала программист попросит ввести с клавиатуры вес первого товара (не описываю, как это можно сделать в языке программирования, поверим, что так можно сделать), и присваивает введенное значение переменной с именем A.
  • Затем он проделывает то же самое с весом второго товара, и присваивает это уже переменной B.
  • А потом пишет в своей программе теперь уже понятное нам выражение:

C = A + B

Что получается в итоге? Конечно, вы сразу догадались, что переменной C будет присвоено значение суммы весов, сохраненных в переменных A и B.

И далее программист напишет в своей программе (тоже прошу поверить, что это можно сделать средствами языка программирования): вывести на экране дисплея значение переменной C. Что мы увидим на экране? Конечно, сумму весов первого и второго товаров!

И теперь эту, один раз написанную программу, можно использовать снова, но уже для суммирования следующей пары весов.

Если еще убрать ручной ввод веса товара, и сразу автоматически ввести вес, скажем, с электронных весов (которые сейчас широко применяются в тех же супермаркетах), то на экран дисплея будет автоматически выводиться сумма весов 2-х товаров: положил одни товар, затем положил второй, и видишь сразу результат.

А если пойти дальше, и не выводить на экран сумму весов 2-х товаров, а записать это куда-то в базу данных?! А если не ограничиваться 2-я товарами, а, скажем, говорить о миллионе разных видов товаров, подлежащих взвешиванию? Почему бы и нет! Все это можно описать в виде выражений, подобных C = A + B.

И в итоге мы получим, можно без стеснения сказать, серьезную автоматизированную систему для супермаркета, где учитываются и веса всех товаров, и количество, и стоимость, а также все покупки, сделанные покупателями и прочее, и прочее и прочее. Но это стало возможным, когда появилось программирование с использованием переменных величин, тех самых A, B, C и тому подобное! Без этого уровня абстракции, без переменных не было бы программирования.

2.3 Переменные и константы

Справедливости ради, надо сказать, что цифры (простые и не очень простые числа) остались в программировании. Они тоже нужны. Их назвали иностранным словом «константы».

Константы – это величины, которые никогда и ни при каких обстоятельствах не меняют свои значения.

А что такое переменная в программировании?

Переменные, в отличие от констант, то и дело меняют свои значения, постоянно их меняют, оттого они и называются переменными величинами.

Так что наряду с выражением C = A + B, в программировании возможно как выражение C = A + 3, так и C = 2 + B.

Однако в левой части программного выражения (до знака равенства «=») константа не может употребляться. Там может быть только переменная, поскольку значение выражения, которое присваивается переменной в левой части выражения, может меняться в зависимости от значений переменных в правой части выражения. А значит, слева может быть только переменная величина[3;15].

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

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

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

ГЛАВА 3 РЕШЕНИЕ ЗАДАЧ ЛИНЕЙНОГО ПРОГРАММИРОВАНИЯ КОМПЬЮТЕРНЫМ ПЕРЕБОРОМ КОМБИНАЦИЙ ВЕЛИЧИН ИСКОМЫХ ПЕРЕМЕННЫХ

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

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

Как известно [2,3], задачи линейного программирования подразде­ляются на общие, канонические и стандартные. В общих задачах ограни­чения на переменные представлены некоторым количеством уравнений и неравенств. В канонических задачах ограничения заданы в виде уравне­ний, а в стандартных только неравенствами.

Теория и методы решения задач линейного программирования до­вольно хорошо разработаны в настоящее время. Имеется обширная лите­ратура по этим вопросам. Однако, к сожалению, все известные методы и алгоритмы весьма сложны и трудоемки. Даже решение двумерных задач графическим методом требует затратных по времени построений.

Между тем вычислительные возможности компьютеров позволяют существенно снизить затраты времени и усилий исследователей в реше­нии такого рода задач. Предлагается общее описание вычислительной программы, решающей такого рода задачи. Считается, что математическая модель задачи линейного программирования построена (записаны ограни­чения в виде равенств, неравенств, выражение целевой функции, содержа­щие искомые величины). Порядок действий:

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

209

  1. Неосновные переменные перенести в правую часть уравнений.
  2. Систему уравнений разрешить относительно основных перемен­ных аналитически, либо решать численно на каждом шаге вычислений.
  3. Составить циклы перебора значений неосновных переменных, вложенные друг в друга (для стандартных задач пункты 2,3,4 опускаются, так как деление на основные и неосновные переменные теряет смысл - за­даются изменения каждой переменной).
  4. Задать шаг изменения каждой неосновной переменной в цикле.
  5. Задать длину интервала изменения каждой неосновной перемен­ной, учитывая величины правых частей исходной системы ограничений.
  6. Внутрь системы вычислительных циклов вставить решение си­стемы линейных уравнений относительно основных переменных и провер­ку условий в виде неравенств. Если все условия выполняются, то вычис­ляется значение целевой функции.
  7. Далее при тех же условиях сравнивается значение целевой функ­ции с предыдущим лучшим ее значением и, если последнее лучше, то ее величина запоминается вместе с соответствующими величинами всех ис­комых переменных.
  8. Так продолжается, пока не будут исчерпаны все шаги в преде­лах заданных интервалов изменения переменных.
  9. Для повышения уверенности в получении оптимального резуль­тата можно повторять вычисления, уменьшая шаг и (или) увеличивая ин­тервал изменения некоторых переменных.

Далее рассматривается несколько примеров, решение которых вы­полнялось с применением языка программирования turbobasic.

Пример 1. Задача на составление смеси [1]

Составляется комбинированный корм из трех злаков: кукурузы, ов­са и ржи. Калорийность и содержание витамина С в одном кг каждого зла­ка, а также цена одного кг злака указаны в табл. 1 ниже [1].

Таблица 1 - Калорийность, содержание витамина С в одном кг каждого злака, цена оДного кг злака

Параметры

Кукуруза

Овес

Рожь

Ккал

200

175

100

Витамин С (г)

5

1

3

Цена (руб)

6

4

1

Требуется составить наиболее дешевый комбинированный корм, 1 кг которого содержал бы не менее 125 ккал и не менее 2 г витамина С.

Решение. Обозначим содержание кукурузы, овса и ржи в 1 кг ком­бикорма символами x1, x2 и x3 (кг) соответственно. По условию задачи эти переменные удовлетворяют следующей системе ограничений:

x1 + x2 + x3 = 1, 8^1 + 7X2 + 4X3 > 5, 5xi + X2 + ЗХ3 > 2, xi > 0,X2 > 0,X3 > 0.

Требуется найти план, доставляющий минимум функции затрат

r = 6 xi + 4 X2 + X3 ® min

Ниже приведен полный текст программы в символах языка про­граммирования, решающей поставленную задачу:

r0=i000

for xi=0 to i step .00i for x2=0 to i step .00i x3=i-x2-xi

if x3>=0 and 8*xi+7*x2+4*x3>=5 and 5*xi+x2+3*x3>=2 then_ r=6*xi+4*x2+x3

if r<r0 and x3>=0 and 8*xi+7*x2+4*x3>=5 and 5*xi+x2+3*x3>=2_ then r0=r : xi0=xi : x20=x2 : x30=x3

next x2 : next xi

print r0, xi0, x20, x30

Из текста программы видно, что в качестве основной переменной выбрана x3, a x1 и x2 - неосновные переменные, могущие принимать зна­чения в интервале от 0 до i. Внутрь тела циклов изменения величин xi и x2 вставлена математическая модель задачи. Если выполняется первый набор условий при произвольной комбинации величин xi и x2, то это до­пустимая комбинация переменных и для нее вычисляется целевая функ­ция. Выполнение второго набора условий означает, что для данной комби­нации величин переменных значение целевой функции оказалось лучше прежнего, и оно запоминается вместе с соответствующими величинами всех переменных. Таким образом, в процессе счета производится улучше­ние показаний целевой функции и в итоге вычислений оказывается луч­ший результат. Это напоминает поиск в симплекс-методе, только здесь нет необходимости искать вершины выпуклых многогранников.

Вычисления с приведенными в программе числовыми данными приводят к результату: r0 » 2.002, xi0 = 0, x20 » 0.334, x30 » 0.666. Точный результат из [i]: r0 = 2, xi0 = 0, x20 =i/3, x30 = 2/3.

В другом варианте решения для изменения неосновных переменных можно использовать генератор случайных чисел rnd в интервале между 0 и i, тогда вычислительная программа несколько изменится:

r0=i000

for s=i to i000 step i

xi=rnd : x2=rnd : x3=i-x2-xi

if x3>=0 and 8*x1+7*x2+4*x3>=5 and 5*x1+x2+3*x3>=2 then_ r=6*x1+4*x2+x3

if r<r0 and x3>=0 and 8*x1+7*x2+4*x3>=5 and 5*x1+x2+3*x3>=2 then r0=r : x10=x1 : x20=x2 : x30=x3

next s : print r0, x10, x20, x30

Здесь параметр s обозначает номер шага в процессе вычислений. Ре­

зультат:

r0 » 2.002455, x10 » 0.0000241, x20 » 0.3341163, x30 » 0.665864

Пример 2. Транспортная задача [2,3].

Имеются три поставщика и четыре потребителя. Мощность по­ставщиков и спросы потребителей, а также затраты на перевозку единицы груза для каждой пары “поставщик - потребитель” сведены в табл. 2 по­ставок, расположенную ниже. Искомый объем перевозки от z-того постав­щика у-тому потребителю указан в правом нижнем углу каждой клетки и обозначен как xij. В левом верхнем углу каждой клетки приведен коэффи­циент затрат на перевозку единицы груза для каждой пары “поставщик - потребитель”.

Задача ставится следующим образом. Найти объемы перевозок Ху для каждой пары “поставщик - потребитель” так, чтобы:

  1. мощности всех поставщиков были реализованы;
  2. спросы всех потребителей были удовлетворены;
  3. суммарные затраты на перевозку были бы минимальны.

Суммарные затраты на перевозку выражаются через коэффициенты затрат следующим образом:

r = x11 + 2x12 + 5x13 + 3x14 + x21 + 6x22 + 5x23 + 2x24 + 6x31 +
+3x32 +7x33 + 4x34.

Таблица 2 - Затраты на перевозку единицы груза для каждой пары

«поставщик - потребитель»

Мощность поставщиков

Потребители и их спрос

1

2

3

4

20

110

40

110

60

1

Х11

2

Х12

5

Х13

3

Х14

120

1

Х21

6

Х22

5

Х23

2

Х24

100

6

Х31

3

Х32

7

Х33

4

Х34

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

x11 + x12 + x13 + x14 = 60,

x21 + x22 + x23 + x24 = 120, (1)

x31 + x32 + x33 + x34 = 100.

Чтобы спрос каждого из потребителей был удовлетворен, уравне­ние баланса должно быть составлено для каждого столбца таблицы поста­вок:

x11 + x21 + x31 = 20, x12 + x22 + x32 = 110, x13 + x23+ x33 = 40,

(2)

x14 + x24 + x34 = 110.

Объемы перевозимых грузов не могут быть отрицательными, по­этому

Xij>0 (i = 1,2,3; j =1,2,3,4).

Суммарные затраты должны быть минимальны

r = Хц + 2 Xj2 + 5X13 + 3xi4 + X21 + 6 X22 + 5 X23 + i

(3)

+2x24 + 6x31 + 3x32 + 7x33 + 4x34.

Особенности этой задачи таковы:

*ограничения представлены системой уравнений (транспортная за­дача задана в канонической форме);

*коэффициенты при переменных системы уравнений равны 1 или 0;

*каждая переменная входит в систему ограничений дважды: один раз в систему уравнений (1), и один раз в систему (2).

*суммарная мощность поставщиков равна суммарному спросу по­требителей (закрытая модель транспортной задачи).

Общее число переменных равно 12. Для закрытой модели транс­портной задачи ранг матрицы системы уравнений (1), (2) на единицу меньше общего числа уравнений [2]. Это максимальное число линейно не­зависимых уравнений. Отсюда имеем 6 основных (базисных) и 6 неоснов­ных переменных.

Выбор вида переменных отчасти произволен, надо только иметь в виду, что в каждом уравнении систем (1),(2) должно быть не менее одной основной и одной неосновной переменной. Ниже системы уравнений (1), (2) переписаны и в них для наглядности помечены черточкой базисные переменные.

Из этой системы выразить основные переменные через неосновные очень просто, так как коэффициенты при всех переменных равны единице:

Теперь можно записать программу вычислений искомых перемен­ных:

Интервал изменения каждой неосновной переменной задавался из следующих соображений: рассматривалась правая часть каждого уравне­ния системы (5), она не должна при предельных условиях делаться отрица­тельной. Для первого уравнения системы (5) каждое слагаемое правой ча­сти по отдельности не должно превышать число 60 (это интервал для пе­ременных x11, x12, x14). Из пятого и шестого уравнений соответственно имеем интервал 110 для x22 и x24. Наименьший интервал для x33 получается из третьего уравнения, он равен 160. Увеличение интервалов сверх найден­ных значений приведет к росту времени вычислений и не улучшит резуль­тат, уменьшение может привести к потере оптимального результата.

Наши вычисления по приведенной программе дали полное совпа­дение с оптимальным результатом в [2]:

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

Пример 3. (Взят из пособия [1]).

Мини-пекарня планирует выпечку батонов и булочек. На производ­ство одного батона расходуется 450 г муки, 10 г масла и 0.5 яйца, а на про­изводство одной булочки - 150 г муки, 5 г масла и 1 яйцо. В пекарню еже­дневно завозят 180 кг муки, 10 кг масла и 775 яиц. Прибыль от реализации батона равна 3 рублям, а от реализации булочки - 5 рублям. В день необ­ходимо производить не менее 780 единиц продукции и получать не менее 3500 рублей прибыли. Требуется разработать план, обеспечивающий мак­симальную прибыль.

Решение. Обозначим производимое в день количество батонов сим­волом x1, а x2 - число булочек. По условию задачи эти переменные удо­влетворяют следующей системе ограничений:

Третье условие в системе (6) есть ограничение на количество масла, привозимого каждый день, а четвертое - на количество муки. В последних двух условиях пропорционально изменены коэффициенты для придания записям более простого вида. Формула прибыли имеет вид:

r = 3x1 + 5x2.

Полный текст программы задачи в символах turbobasic^: r0=1 for x1=0 to 400 step 1

for x2=0 to 775 step i

if 3*xi+x2<=i200 and xi+x2/2<=500 and xi+x2>=780 and_ xi/2+x2<=775 then r=3*xi+5*x2

if r>r0 and 3*xi+x2<=i200 and xi+x2/2<=500 and xi+x2>=780_ and xi/2+x2<=775 then r0=r : xi0=xi : x20=x2

next x2, xi : print r0, xi0, x20

Интервал изменения xi вычислен в предположении, что вся мука потрачена на батоны, а интервал для x2 предполагает, что все яйца израс­ходованы только на изготовление булочек. Такие интервалы перекрывают все возможные целочисленные комбинации.

Отметим, что ограничение на прибыль можно не вводить в про­грамму. В этом случае если лучший результат окажется ниже ограничения, то задача не имеет оптимального решения. Здесь это не так, вычисления дают оптимальный результат:

rmax = 3950, xi0 =i50, x20 = 700.

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

r0=i

for s=i to i000000 step i xi=400*rnd : x2=775*rnd if 3*xi+x2<=i200 and xi+x2/2<=500 and xi+x2>=780 and_ xi/2+x2<=775 then r=3*xi+5*x2

if r>r0 and 3*xi+x2<=i200 and xi+x2/2<=500 and xi+x2>=780_ and xi/2+x2<=775 then r0=r : xi0=xi : x20=x2

next s : print r0, xi0, x20

Результат вычислений:

rmax = 3949.i77, xi0 =i49.94i, x20 = 699.87i

оказался весьма близким к точным целочисленным значениям.

Пример 4. (Взят из пособия [2])..

Имеется большое количество бревен длиной 3 м. Из них распили­ванием следует получить заготовки двух видов: длиной i.2 м и длиной 0.9 м, причем заготовок каждого вида должно быть получено не менее 50 шт. и 8i шт. соответственно. Каждое бревно можно распилить на указанные заготовки тремя способами: i) на 2 заготовки по i.2 м; 2) на i заготовку по i.2 м и 2 заготовки по 0.9 м; 3) на 3 заготовки по 0.9 м. Найти число бревен, распиливаемых каждым способом, с тем чтобы требуемые количе­ства заготовок каждого вида были получены из наименьшего числа бре­вен.

Решение. Обозначим через xi,x2,x3 числа бревен, распиливаемых соответственно 1-м, 2-м и 3-м способами. Из них можно получить 2xi + x2 заготовок по i.2 м и 2x2 + 3x3 заготовок по 0.9 м. Общее количе­ство бревен, потребное для изготовления названных заготовок, обозначим символом r. Тогда математическая модель задачи примет вид:

r = Xi + x 2 + X3 ® min

при ограничениях

2Xi + X2 > 50,

2X2 + 3x3 > 81

Все переменные - неотрицательные целые числа.

Ниже приведен полный текст программы, решающей данную зада­чу. Длины интервалов изменения переменных в циклах вычислений опре­деляются по правым частям неравенств, и они должны быть: для X1 - не менее 25, для X2 - не менее 41, для X3 - не менее 27, чтобы покрыть объ­ем, в котором может находиться оптимальная точка

r0=1000

for x1=0 to 30 step 1

for x2=0 to 50 step 1

for x3=0 to 30 step 1

if 2*x1+x2>=50 and 2*x2+3*x3>=81 then r=x1+x2+x3

if r<r0 and 2*x1+x2>=50 and 2*x2+3*x3>=81 then_

r0=r : x10=x1 : x20=x2 : x30=x3

next x3, x2, x1

print r0, x10, x20, x30

Вычисления дают нам следующий оптимальный результат:
rmin =46, X10 =4, X20 =42, X30 =0.

В учебном пособии [2] отмечается альтернативность оптимальных результатов в целочисленных задачах, и утверждается, что в этой задаче должно быть четыре таких варианта. Они приводятся, но наш результат не совпадает ни с одним из них. Лучший их результат по отношению к вели­чине отходов уступает нашему результату. Приведем его:

rmin =46, X10 =5, X20 =41, X30 =0.

В нашем случае 2.4 м бревен уходят в отходы, а в их случае - 3 м. В нашем случае делается 50 заготовок в 1.2 м и 84 заготовки длиной 0.9 м. А в их случае делается 51 заготовка в 1.2 м и 82 заготовки длиной 0.9 м. Таким образом, наш результат является пятым альтернативным вариантом, и он оказался лучше по минимуму отходов, хотя никаких дополнительных критериев, как можно видеть, в программу не вставлено.

Выводы:

  1. Суть предлагаемого метода состоит в автоматическом комбини­ровании величин искомых переменных, вычислении целевой функции для каждой допустимой комбинации и в последовательном ее улучшении.
  2. Приведенные простые примеры относятся к различающимся ви­дам задач: в первом примере решается общая задача линейного програм­мирования, во втором примере - каноническая задача, а в третьем и чет­вертом примерах - стандартная задача.
  3. Примеры наглядно иллюстрируют возможности предлагаемого метода - простоту и скорость получения результата.
  4. Предлагаемый метод несомненно имеет недостатки. Это отсут­ствие наглядности, поскольку геометрические образы и связи разнообраз­ных классических подходов остаются в стороне. Это невозможность полу­чения альтернативных результатов в целочисленных задачах. Это невоз­можность определения без специальных действий, что оптимум может иметь место не в точке, а в некоторой непрерывной области переменных. Это невозможность определения в одном вычислении, что задача не имеет конечного экстремума. Наверняка читатель найдет и другие погрешности.
  5. Для повышения точности результата следует уменьшать шаги изменения задаваемых переменных. При большом числе задаваемых пере­менных и малых шагах их изменения количество исчисляемых комбина­ций и время вычисления может быть недопустимо велико. Чтобы получить достаточную точность результата за приемлемое время, надо проводить вычисления в несколько этапов. Перед началом вычислений надо задаться сравнительно крупными шагами и интервалами изменения, обеспечиваю­щими попадание оптимума в заданный объем. Получив при этих условиях сравнительно близкую к оптимуму точку, надо выделить вокруг нее мень­ший объем. Для этого надлежит отступить от нее на величину шага в обе стороны по каждой задаваемой координате и задаться значительно мень­шими величинами шагов. Далее снова проводятся вычисления, и все дей­ствия повторяются, пока не будет достигнута приемлемая точность.
  6. Для снижения количества исчисляемых комбинаций и времени счета можно также попытаться использовать генератор случайных чисел. В первом и третьем примерах применение генератора rnd дает очень близ­кий к оптимуму результат. Однако уже в примере с транспортной задачей для числа циклов изменения переменных 107 результат качественно отли­чался от оптимального - в таблице результатов не оказалось клеток с близ­кими к нулю величинами.
  7. Если оптимум достигается не в единственной точке, а на некото­ром множестве, то предложенный метод находит только единственную точку, и положение ее зависит от выбора интервалов изменения перемен­ных, порядка их вложения в циклы и шага их изменения.
  8. В задачах с отсутствием конечного оптимума таковое может быть обнаружено несколькими попытками вычислений с увеличением интерва­лов изменения переменных. При этом целевая функция неограниченно растет по абсолютной величине.
  9. Предложенный метод может применяться и к нелинейным зада­чам, но решение и анализ систем нелинейных уравнений сильно осложнит дело для случаев аналогов общей и канонической задач нелинейного про­граммирования. Между тем препятствий для решения рассмотренным ме­тодом аналогов стандартных задач в нелинейной постановке не видно.

ЗАКЛЮЧЕНИЕ

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

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

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

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

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

СПИСОК ЛИТЕРАТУРЫ

  1. Александров В. В. Экологическая роль электромагнетизма. - СПб.: Изд-во Поли- техн. ун-та, 2015. - 736 с.
  2. Барабанов А. А., Косов А. А., Ярославцев Н. А. Влияние энергетических форм природы на жизнедеятельность человека // Академический вестник УралНИИпроект РААСН. - 2015. - № 1. - С. 91-96.
  3. Бугакова Т. Ю. Вовк И. Г. Математическое моделирование пространственно-временного состояния систем по геометрическим свойствам и оценка техногенного риска методом экспоненциального сглаживания // Вестник СГГА. - 2012. - Вып. 4 (20). - С. 47-58.
  4. Винер Н. Кибернетика, или управление и связь в животном и машине; или Кибернетика и общество. - 2-е издание. - М.: Наука; Главная редакция изданий для зарубежных стран, 2013. - 344 с.
  5. Галль Л. Н. В мире сверхслабых. Нелинейная квантовая биоэнергетика: Новый взгляд на природу жизни. - 2016. - 317 с.
  6. Гуревич И. М. Оценка основных информационных характеристик Вселенной // Приложение к журналу «Информационные технологии». - 2016. - № 12. - С. 2-17.
  7. Дубров А. П. Когнитивная психофизика: основы. - 2-е изд., исп. и доп. - Ростов н/Д.: Феникс, 2012. - 301 с.
  8. Егоров В. В. Физические поля и излучения организма (на примере человека). Проблемная лекция. - М.: ФГОУ ВПО МГАВМиБ, 2016. - 64 с.
  9. Информация // Большой энциклопедический словарь. - 2-е изд., перераб. и доп. - М.: Большая Российская энциклопедия, 2015. — 1434 с.
  10. Карпик А. П., Осипов А. Г., Мурзинцев П. П. Управление территорией в геоинформационном дискурсе. - Новосибирск: СГГА, 2016. - 279 с.
  11. Концепции целостности эволюции материального мира / Ю. С. Ларионов, Н. А. Ярославцев, С. М. Приходько, Е. В. Екимов // VI Международный конгресс «Слабые и сверхслабые поля и излучения в биологии и медицине». Санкт-Петербург, 2 июня 2012 г.: сб. научных трудов. - Спб., 2012. - С. 268-269.
  12. Ларионов Ю. С. Основы эволюционной теории (Концепции естествознания и аксиомы современной биологии в свете эволюции материи): учеб. пособие. - Омск, изд. ИП Скорнякова Е. В., 2012. - 233 с.
  13. Ларионов Ю. С., Ярославцев Н. А. Зависимость скорости роста растительных тест- объектов семян пшеницы от действия электромагнитных излучений низкой интенсивности естественного происхождения // Вестник СГГА. - 2012. - Вып. 4 (20). - С. 100-106.
  14. Моисеев Н. Н. Расставание с простотой. - М.: АГРАФ, 2012. - С. 98.
  15. Першин С. М. Слабое когерентное излучение ОН и орто-Н2О мазеров как несущая в биокоммуникации: орто-Н2О, как резонансный сенсор // Человек и электромагнитные поля: сб. докладов III Международной конференции. - Саров: РФЯЦ-ВНИИЭФ, 2016. - С. 4- 12.
  16. Петров Н. В. Живой Космос. - СПб.: ООО «Береста», 2015. - 420 с.
  17. Сборник научных трудов VI Международного конгресса «Слабые и сверхслабые поля и излучения в биологии и медицине». - СПб., 2012. - 309 с.
  18. Семенков О. И. Информация. Новейший философский словарь / Сост. и гл. науч. ред. А. А. Грицанов. 3-е изд., испр. - Минск: Книжный дом, 2013. - С. 431-434.
  19. Чернавский Д. С. Синергетика и информация (динамическая теория информации). Изд. 2-е. - М.: Едиториал УРСС, 2014. - 288 с.
  20. Электромагнитный информационный подход к целостной естественнонаучной картине материального мира / Ю. С. Ларионов, В. С. Ларионов, Н. А. Ярославцев, Н. М. При- ходько, Е. И. Баранова // Вестник СГГА. - 2014. - Вып. 4 (28). - С. 158-174.
  21. Энергоинформационные взаимодействия как основа понимания целостной картины мира / Н. А. Ярославцев, Ю. С. Ларионов, С. М. Приходько, Е. В. Екимов // VI Международный конгресс «Слабые и сверхслабые поля и излучения в биологии и медицине». Санкт- Петербург, 2-6 июля 2012 г.: сб. научных трудов. - СПб., 2012. - С. 280-281.
  22. Systems and software engineering - Vocabulary: Although information will necessarily have a representation form to make it communicable, it is the interpretation of this representation (the meaning) that is relevant in the first place [Электронный ресурс]. - Доступ из: https://www/ISO org/obp/ui/#ISO:std: ISO/IEC/IEEE 24765:2010.