Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Моделирование и оптимизация в LINGO

..pdf
Скачиваний:
10
Добавлен:
12.11.2023
Размер:
2.55 Mб
Скачать

N, ACCURACY = 12,.02 ;

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

N, ACCURACY = ?,.02 ;

Тогда при каждом решении задачи LINGO будет запрашивать значение этого параметра. Знак ? можно применять и для значений атрибутов отдельных элементов множества:

DATA:

X = 8 12 ?;

Y = 74 45 66; SET2 Z=

A92

B?

C23

D82;

ENDDATA

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

@TEXT, @OLE, @ODBC или @POINTER для обмена соответствен-

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

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

SETS:

DAYS / MO..SU/: NEEDS;

ENDSETS

DATA:

NEEDS = 35; ENDDATA

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

21

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

SETS:

YEARS /1..5/: STORE; ENDSETS

DATA:

STORE = 2500, 2700, , , ; ENDDATA

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

Для задания случайных значений в разделе DATA используется функция @QRAND. Она генерирует последовательность квазислучайных чисел с равномерным распределением в интервале (0,1), которая заполняет таблицу данных случайными значениями. Таблица может быть как одномерной, так и многомерной. Для придания разнообразия последовательностям функция имеет один числовой аргумент SEED, значение которого может вводиться непосредственно в модель или вырабатываться программой. Если он опущен, LINGO использует системные часы для получения его значения. Заметим, что функцию @QRAND можно применять только в разделе

DATA.

На скриншоте показаны примеры заполнения случайными числами строки, двумерной и трехмерной таблицы с помощью функции @QRAND (рис. 1).

Для получения случайных чисел в разделе CALC или MM используют функцию @RAND(SEED), которая возвращает псевдослучайное значение из интервала (0,1). Она применяется также для получения последовательности псевдослучайных чисел с равномерным распределением.

22

Рис. 1

5. РАЗДЕЛЫ МОДЕЛИ INIT И CALC

Эти разделы являются необязательными частями модели. INIT-секция применяется в основном для ввода стартовых то-

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

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

23

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

Пример определения секции INIT при решении системы неравенств:

INIT

X = 0.9;

Y = 0.01; ENDINIT

X^2 + Y^2 <= 1; X – Y >=0.5;

Как отмечалось ранее, раздел CALC добавляется к модели при необходимости предварительной обработки исходных данных. Например, исходные данные представляют собой ряды результатов измерений нескольких параметров. Для решения задачи нужны средние значения параметров, дисперсии, корреляционные и ковариационные матрицы. В этом случае целесообразно создать раздел CALC и в нем описать соответствующие вычисления. Эти вычисления можно поместить и в раздел ММ, но тогда решатель получит для оптимизации увеличенную модель, что скажется на времени решения (так как вычисление выражений CALC-секции выполняется не в оптимизаторе).

CALC-секция начинается со слова CALC: и оканчивается ключевым словом ENDCALC. В этом разделе каждое выражение должно быть представлено в виде оператора присваивания: с левой стороны равенства – одна переменная, а справа – любое математическое выражение. Это выражение может содержать только те переменные, которые введены ранее в разделе данных и/или в разделе CALC. Пример вычисления среднего значения:

DATA:

A, B, C, D = 7, 15, ?, 10; ENDDATA

CALC:

AVG = A + B + C + D; AVG = AVG/4;

ENDCALC

24

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

Следует иметь в виду, что переменная, вычисленная в CALCсекции, помечается как фиксированная и она не может быть изменена решателем при новом прогоне модели. Чтобы сделать ее снова свободной, к ней в конце вычисления применяется специальная функция @RELEASE. Кроме того, в этой секции можно писать скрипт, задающий ход решения (см. главу 7).

6. ОСНОВНЫЕ ФУНКЦИИ ПОСТРОЕНИЯ МОДЕЛИ

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

ли в LINGO.

Замечание. В связи с очевидностью использования математических функций они не затрагиваются в этом разделе, однако для справки весь их список приводится в приложении 2.

6.1. Цикловые функции множеств

Эффективность языка моделирования в LINGO определяется возможностью применять одни и те же операции и/или соотношения последовательно ко всем элементам множества с помощью одного операторного выражения. Для реализации этой возможности LINGO имеет специальные функции, называемые функциями цикла для множеств (set looping functions или SLF). К ним относятся функции

@FOR, @SUM, @MIN, @MAX и @PROD. Первая используется в разделе ММ для генерации ограничений по всем членам множест-

25

ва, последняя – для вычисления произведения, остальные функции пояснений не требуют. Применение функции @FOR возможно и в секции CALC для задания значений атрибутам членов множества. Допускается любая вложенность SLF-функций за исключением @FOR, которая может быть вложенной только в другую функцию

@FOR.

Синтаксис SLF-функций:

@loop_function ( setname [ ( set_index_list) [ | conditional_qualifier]] : expression_list);

Как видно, обязательными аргументами функции являются имя множества (setname), которое обрабатывается данной функцией, и выражения (expression_list), применяемые ко всем элементам этого множества. При наличии условий (conditional_qualifier) действие функции будет распространяться только на те члены множества, которые им удовлетворяют.

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

За исключением функции @FOR список выражений может содержать только одно выражение. При применении @FOR этот список может включать несколько выражений, разделенных точкой с запятой. При отсутствии списка индексов все атрибуты, использованные в expression_list, должны быть определены на множестве setname.

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

SETS:

VENDORS: DEMAND; ENDSETS

DATA:

VENDORS, DEMAND = V1,21 V2,13 V3,32 V4,4; ENDDATA

TOTAL_DEMAND = @SUM(VENDORS(J): DEMAND(J));

26

При выполнении суммирования индекс J будет последовательно принимать значения от V1 до V4. Поскольку атрибут DEMAND определен для всех членов множества VENDORS, индекс можно опустить, и тогда получим

TOTAL_DEMAND = @SUM(VENDORS: DEMAND);

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

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

DEMAND_2_4 = @SUM(VENDORS(J) | J #GE# 2: DEMAND(J));

Применим функции @MAX и @MIN для нахождения максимальной и минимальной потребности в вышерассмотренном примере:

MIN_DEMAND = @MIN( VENDORS( J): DEMAND( J));

MAX_DEMAND = @MAX( VENDORS( J): DEMAND( J));

Как и ранее, здесь возможен вариант без явного указания индексов:

MIN_DEMAND = @MIN( VENDORS: DEMAND);

MAX_DEMAND = @MAX( VENDORS: DEMAND);

Очевидно, что используя условия на индексы, можно применять эти функции к подмножеству продавцов, например к первым трем:

MAX_DEMAND = @MAX( VENDORS(J) | J #LE# 3: DEMAND(J));

В качестве примера применения функции @PROD вычислим вероятность выхода системы из строя, если она состоит из последовательно соединенных блоков с известными вероятностями нормальной работы (Prob):

MODEL:

SETS:

BLOCKS: Prob; ENDSETS

DATA:

Prob =.99.98.96.97; ENDDATA

FAIL = 1 – @PROD( BLOCKS( I): Prob( I)); END

27

Функция @FOR – самая важная цикловая функция, именно ее применение существенно снижает размер модели. Так, при наложении ограничений на все члены множества скалярное описание модели требует явно ввести ограничение на каждый член множества, в то время как с @FOR модель будет содержать только одно ограничение на все множество. При этом перед обращением к основному решателю LINGO сгенерирует ограничения для каждого члена множества.

Рассмотрим простые примеры.

Предположим, при формировании рациона питания продукты не должны содержать вредных веществ выше допустимой величины, равной 1,2 %. Значит, скалярная модель должна содержать столько идентичных ограничений, сколько продуктов рассматривается в задаче. С использованием функции @FOR мы получим более компактное описание:

SETS:

FOODS / MILK, MEAT, FISH, SAUSAGE/: HARMFUL_SUBSTANCES;

ENDSETS

@FOR(FOODS(J): HARMFUL_SUBSTANCES(J) <=.012);

В этом фрагменте модели фигурирует только одно ограничение, но по нему LINGO сгенерирует ограничения для каждого продукта питания.

Следующий пример иллюстрирует применение @FOR для вычисления чисел Фибоначчи:

sets:

fib/1..5/: value; endsets

value(1)=1;

value(2)=1;

@For(fib(J)|J #GT# 2: value(J)=value(J-1)+value(J-2));

LINGO выдаст такой результат:

Variable Value VALUE( 1) 1.000000 VALUE( 2) 1.000000 VALUE( 3) 2.000000 VALUE( 4) 3.000000 VALUE( 5) 5.000000

28

Как отмечалось выше, SLF функции могут быть вложенными или сами содержать вложенные функции. Исключение составляет функция @FOR, которая может быть вложенной только в другую функцию @FOR.

Приведем пример с вложенной функцией @SUM:

SETS:

SUPPLIERS /h1..h3/: a; CONSUMERS /A..D/: b;

NET (SUPPLIERS, CONSUMERS): cost, X; ENDSETS

DATA:

a=20 10 32; b= 15 8 22 6; cost=

3 1 5 2

2 2 6 4

5 3 4 1;

ENDDATA

MIN= @SUM( NET(I,J): COST(I,J)*X(I,J)); @FOR(CONSUMERS(J): @SUM(SUPPLIERS(I): X(I,J))>=b(J));

@FOR(SUPPLIERS(I): @SUM(CONSUMERS(J): X(I,J))<=a(I));

! Суммарные поставки;

Tota_delivery = @SUM( NET(I,J): X(I,J));

6.2. Функции прямых ограничений

Для моделирования прямых ограничений на переменные применяются следующие функции:

@GIN – задает целочисленный тип переменных, @BIN – задает бинарный тип переменных,

@FREE – придает вещественной переменной неограниченность по знаку,

@BND – накладывает двухсторонние ограничения,

@SOS1 – из всех переменных, к которым применена эта функция, самое большее, одна может быть больше нуля,

@SOS2 – не более двух переменных больше нуля, и если ровно 2 переменные ненулевые, то они будут смежными,

@SOS3 – точно только одна бинарная переменная равна 1,

29

@CARD – из всех переменных, описанных этой функцией, не более N переменных могут быть ненулевыми,

@SEMIC – переменная может либо равняться нулю, либо быть больше некоторой константы,

@PRIORITY – используется для назначения переменным приоритета ветвления,

@POSD – накладывает на квадратную матрицу требование быть симметричной и положительно полуопределенной.

Функции @GIN, @BIN и @FREE имеют одинаковый синтаксис:

@function(variable_name);

Примеры использования этих функций:

@GIN (X); @BIN (Y); @GIN (Product(6)) ; @BIN (Include(4)); @FOR (FOODS: @GIN (Product));

@FOR (ITEMS: @BIN (Include));

@FREE(X); @FREE (Error(6)) ; @FOR (DEVICES: @FREE(Error));

В примерах с @FOR заданный тип относится ко всем переменным поименованного множества.

Двухсторонние ограничения на переменные устанавливаются функцией @BND согласно синтаксису

@BND(lower_bound, variable_name,upper_bound);

Примеры:

@BND( -3, X, 12); @BND( 100, Temperature( 4), 500); @FOR( ITEMS: @BND( 5, Q, 20));

@FOR( ITEMS: @BND( LB, Q, UB));

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

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

@function( 'set_name', variable);

где set_name – уникальное имя набора (списка) переменных, на котором задана функция @SOS.

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

30

Соседние файлы в папке книги