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

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

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

ство ее нулю означает, что новая карта, как и последующие, не может улучшить решение (их оценки не меньше нуля). Выход из цикла означает, что все возможные перспективные карты получены и на них найдено оптимальное решение непрерывной задачи. Наконец, чтобы получить целочисленное решение задачи, снова ищется минимум основной модели на том же наборе карт, но с добавлением условия целочисленности переменных (совместное решение подмоделей MASTER_PROB и INTEGER_REQ как единой модели). Тем самым завершается итерационный процесс оптимизации.

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

деле CALC.

Теперь, выполнив команду Solver/Solve либо нажав кнопку в виде мишени, получаем на дисплее отчет решения модели раскроя:

ЗАДАЧА РАСКРОЯ РУЛОНОВ

Всего использовано рулонов:

 

666

 

 

 

 

 

Совокупная ширина рулонов, м:

5328

 

 

 

 

 

Совокупная ширина лент, м:

 

5224

 

 

 

 

 

Всего остатков, %:

2.0

 

 

 

 

 

 

 

Карты раскроя (Pattern):

5

6

7

8

Ленты Заказ Факт

1

2

3

4

===========================================================

L1

250

250

1

.

.

.

1

.

.

.

L2

110

110

1

.

.

.

.

2

.

.

L3

700

700

1

.

3

.

.

.

.

2

L4

920

921

1

6

.

.

1

.

6

1

L5

535

536

1

.

.

10

1

.

1

2

===========================================================

Используется, раз:

0

0 170

0 250 55

96 95

Отчет показывает, что в решении участвовало 8 из допустимых 15 карт (сгенерировано 7), из них в оптимальный набор вошли только 5. Все потребности удовлетворяются полностью раскроем 666 рулонов, и при этом остатки составляют всего 2 %.

71

8.ИНТЕРФЕЙС С СИСТЕМАМИ ДАННЫХ

ИПРИЛОЖЕНИЯМИ

Очевидно, что небольшие объемы данных можно переместить из Excel в LINGO копированием ячеек с данными и вставкой их в секцию DATA модели справа от имени атрибута. Аналогично небольшой отчет о решении можно перенести в Word, используя команды копирования и вставки. Однако при больших объемах данных и при встраивании LINGO в систему пользователя такой метод неприемлем. Ниже рассмотрим, как в LINGO решается эта проблема.

8.1. Взаимодействие с внешними файлами

Как отмечалось в начале пособия, LINGO предоставляет возможности импорта данных из текстовых файлов формата ASCII и экспорта решений в них.

Для получения данных из текстовых файлов используется интерфейсная функция @FILE(‘filename’). При этом данные могут быть вставлены в любое место модели, что особенно удобно для секций DATA и SETS. LINGO принимает текст из файла до тех пор, пока не встретит метку конца файла либо метку конца записи в LINGO ( ). Часть файла между метками называется записью. Если в модели последует второе (третье и т.д.) обращение к этому файлу, то данные будут читаться из файла, начиная с точки остановки предшествующего обращения, т.е. со следующей записи. В модель можно включать до 16 файлов. Вложенность функций @FILE не допускается.

Для примера вернемся к задаче PRODUCTION с исходной моделью, но часть данных для секций SETS и DATA будем брать из файла production.txt. Тогда модель примет следующий вид:

MODEL: sets:

PRODUCT: order;

EQUIPMENT / @FILE('c:\GAL\production.txt')/: TWORK, K; PR_EQ (PRODUCT, EQUIPMENT): T, X;

72

endsets data:

PRODUCT=@FILE('c:\GAL\production.txt'); order= @FILE('c:\GAL\production.txt'); T = @FILE('c:\GAL\production.txt');

K = 2 1 3; enddata

MIN = TIME;

@FOR(PRODUCT(I)|order #NE# 0: @SUM(EQUIPMENT(J): X(I,J))=order);

@FOR(EQUIPMENT(J): @SUM(PRODUCT(I)|order #NE# 0: T(I,J)*X(I,J))- TWORK(J)=0);

TIME = @MAX(EQUIPMENT: TWORK); @FOR(PR_EQ(I,J)|order(I) #NE# 0: @GIN(X));

@FOR( EQUIPMENT(J): @CARD( 'name'+ EQUIPMENT(J), K); @FOR(PRODUCT(I)|order #NE# 0: @CARD('name'+ EQUIP-

MENT(J), X(I,J))

)

); END

Здесь в файл production.txt записываются как элементы множества, так и данные в следующем виде:

!Оборудование; 1 . . 3 ~ !Продукция; pr1 . . pr4~ !Потребность; 75 123 0 62~ !Время; 7 11 9 14 8 10 12 7 13 10 9 11

Заметим, что в файле допустим комментарий.

Функция @TEXT( ['filename', [‘a’]]) позволяет выводить данные из LINGO во внешний файл или на экран. Второй вариант имеет место при отсутствии аргументов. При указании только имени файла запись идет в создаваемый файл или, если такой файл существует, то поверх его. При добавлении аргумента ‘a’данные записываются в конец существующего файла. Функция может быть использована только в секции DATA и при этом она записывается на левой стороне выражения вывода.

73

Примеры:

Вывод X,Y в файл: @TEXT('OUT.TXT') = X,Y;

Вывод элементов множества и значений атрибута на экран:

@TEXT() = PRODUCT, VOLUME;

Вывод элементов множества и положительных значений их атрибута в конец файла:

@TEXT(‘REPORT.TXT’,’a’)=@WRITEFOR(PRODUCT(I)|VOLUME(I)#GT# 0: PRODUCT(I), ' ', VOLUME(I));

Очевидно, что данные из полученного файла могут быть переданы вовне, например, в Excel или MS Access.

Для автоматизации выполнения часто используемой последовательности команд и/или моделей можно составить сценарий команд (Command Script). Язык команд LINGO применяется в режиме командной строки (Window| Command Window), а готовый скрипт запускается открытием содержащего его файла через меню File|Take Commands. Выполнение скрипта и работа LINGO завершаются при обнаружении команды QUIT. Иначе выполнение прекратится при достижении конца файла, после чего LINGO перейдет в режим нормального ввода. Полный перечень команд с кратким описанием приведен в приложении 3.

Для примера снова обратимся к исходной модели PRODUCTION

изапишем скрипт, запуск которого приводит к решению модели

ивыводу на дисплей и в файл SOLU.TXT краткого отчета с ненулевыми значениями переменных.

Текст приводимого ниже скрипта, написанный в окне Command Window, сохраняем в файле Myscript.ltf.

SET ECHOIN 1 MODEL: sets:

PRODUCT: order;

EQUIPMENT /1..3/: TWORK, K; PR_EQ (PRODUCT, EQUIPMENT): T, X; endsets

data:

PRODUCT=pr1.. pr4; order= 75 123 0 62; T = 7 11 9

74

14 8 10

12 7 13

10 9 11; K = 2 1 3; enddata

MIN = TIME;

@FOR(PRODUCT(I)|order #NE# 0: @SUM(EQUIPMENT(J): X(I,J))=order);

@FOR(EQUIPMENT(J): @SUM(PRODUCT(I)|order #NE# 0: T(I,J)*X(I,J))- TWORK(J)=0);

TIME = @MAX(EQUIPMENT: TWORK); @FOR(PR_EQ(I,J)|order(I) #NE# 0: @GIN(X));

@FOR( EQUIPMENT(J): @CARD( 'name'+ EQUIPMENT(J), K); @FOR(PRODUCT(I)|order #NE# 0: @CARD('name'+ EQUIP-

MENT(J), X(I,J))

)

); END

SET TERSEO 1 GO

NONZ X

!Открытие файла

DIVERT SOLU.TXT

!Запись решения в файл

NONZ X

!Закрытие файла решения

RVRT

Теперь с помощью команды меню File|Take Commands открываем файл Myscript.ltf, что приводит к выполнению нашего скрипта и выводу на дисплей отчета в следующем виде:

: SET ECHOIN 1

Parameter Old Value New Value ECHOIN 1 1

: MODEL:

?sets:

?PRODUCT: order;

?EQUIPMENT /1..3/: TWORK, K;

?PR_EQ (PRODUCT, EQUIPMENT): T, X;

?endsets

?data:

?PRODUCT=pr1.. pr4;

?order= 75 123 0 62;

?T = 7 11 9

?14 8 10

75

?12 7 13

?10 9 11;

?K = 2 1 3;

?enddata

?MIN = TIME;

?@FOR(PRODUCT(I)|order #NE# 0: @SUM(EQUIPMENT(J): X(I,J))=order);

?@FOR(EQUIPMENT(J): @SUM(PRODUCT(I)|order #NE# 0: T(I,J)*X(I,J))- TWORK(J)=0);

?TIME = @MAX(EQUIPMENT: TWORK);

?@FOR(PR_EQ(I,J)|order(I) #NE# 0: @GIN(X));

?@FOR( EQUIPMENT(J): @CARD( 'name'+ EQUIPMENT(J), K);

?@FOR( PRODUCT(I)|order #NE# 0: @CARD('name'+ EQUIPMENT(J),X(I,J))

?)

?);

?END

: SET TERSEO 1

Parameter

Old Value

New Value

TERSEO

1

1

 

: GO

 

 

 

Local optimal solution found.

 

750.0000

Objective value:

 

Objective bound:

 

750.0000

Infeasibilities:

 

0.000000

Extended solver steps:

 

36

Total solver iterations:

 

2499

Elapsed runtime seconds:

 

2.33

: NONZ X

 

 

 

Local optimal solution found.

 

750.0000

Objective value:

 

Objective bound:

 

750.0000

Infeasibilities:

 

0.000000

Extended solver steps:

 

36

Total solver iterations:

 

2499

Elapsed runtime seconds:

 

2.34

 

Variable

Value

Reduced Cost

 

X( PR1, 1)

75.00000

0.000000

 

X( PR2, 2)

92.00000

0.000000

 

X( PR2, 3)

31.00000

10.00000

 

X( PR4, 1)

22.00000

0.000000

 

X( PR4, 3)

40.00000

11.00000

: !Открытие файла

 

 

: DIVERT SOLU.TXT

 

 

76

:! Запись решения в файл

:NONZ X

:! Закрытие файла решения

:RVRT

:

При этом в файл Solu.txt записываются только результаты решения задачи:

Local optimal solution found.

 

750.0000

Objective value:

 

Objective bound:

 

750.0000

Infeasibilities:

 

0.000000

Extended solver steps:

 

36

Total solver iterations:

 

2499

Elapsed runtime seconds:

 

2.30

Variable

Value

Reduced Cost

X( PR1, 1)

75.00000

0.000000

X( PR2, 2)

92.00000

0.000000

X( PR2, 3)

31.00000

10.00000

X( PR4, 1)

22.00000

0.000000

X( PR4, 3)

40.00000

11.00000

Заметим, что в отличие от данных, записанных в файл, на дисплей выводится как отчет, так и весь скрипт. Скрипт не выведется, если не введена команда SET ECHOIN 1 или в ней задано значение 0.

Если скрипт сохранить в файле с именем AUTOLG.DAT в рабочей папке LINGO, то при каждом запуске LINGO он будет выполняться.

Имеется другой способ автоматического выполнения скрипта при запуске LINGO. Для этого в командную строку запуска LINGO добавляется имя файла, содержащего скрипт, с префиксом –T.

Например, чтобы выполнялся скрипт из файла Myscript.ltf, достаточно в свойствах ярлыка LINGO в поле Объект добавить строку -tMyscript.ltf, как показано на скриншоте окна свойств

(рис. 4).

Теперь при запуске LINGO будет выполнена команда File|Take Commands, и мы автоматически получим отчет о решении, точно такой же, как в файле Solu.txt (см. выше).

77

Рис. 4

Если наряду с файлом Myscript.ltf в рабочей папке LINGO есть файл AUTOLG.DAT, то он будет выполняться перед Myscript.

Если перед именем файла поставить префикс –O, то при запуске выполнится команда File|Open и скрипт из файла считается в стандартное окно. При префиксе L автоматически выполняется команда File|Log Output и весь вывод, обычно направляемый в командное окно, посылается в файл с именем, записанным после этого префикса.

LINGO включает также служебную программу RunLingo, которая позволяет обрабатывать файлы сценариев. RunLingo вызыва-

78

ется из командной строки, где записывается вместе с файлом сцена-

рия, например: C:\LINGO16>runlingo myscript.ltf. Результаты выпол-

нения программа направляет в стандартное устройство вывода. Завершая рассмотрение работы с файлами, приведем стан-

дартные типы файлов (их расширений), принятые в LINGO:

.LG4 Файлы модели, только в Windows,

.LNG Файлы модели в текстовом формате,

.LTF Файлы скриптов,

.LDT Файлы включенных данных,

.LGR Файлы отчета.

Файлы .LG4 записываются в бинарном формате и правильно читаются только под Windows. Файл с любым другим расширением воспринимается LINGO как текстовый. Файлы .LNG могут использоваться для переноса модели на другую платформу или в приложение. Следует иметь в виду, что эти файлы не сохраняют специальное форматирование модели и, в отличие от файлов .LG4, могут не работать как контейнеры или серверы OLE.

8.2. Взаимодействие с электронной таблицей

Удобным средством хранения и манипулирования данными являются электронные таблицы. LINGO предоставляет широкие возможности взаимодействия с таблицей: импорт данных из таблицы, экспорт в нее решений, создание ссылок OLE на Excel, управление LINGO из Excel, импортирование функциональных возможно-

стей LINGO в Excel и др.

8.2.1. Импорт и экспорт данных между LINGO и Excel

Импорт данных из таблицы выполняется с помощью интерфейсной функции @OLE, которая доступна только в версии под Windows. Она обеспечивает прямую OLE передачу данных между LINGO и Excel (передачу памяти), что исключает использование промежуточных файлов. Функция применима в секциях DATA

и INIT.

79

LINGO, обнаружив функцию @OLE, загружает Excel, которая в свою очередь загружает требуемую таблицу и запрашивает диапазоны, в которых находятся нужные данные.

@OLE функция может читать в Excel как текстовые данные (элементы множеств), так и числовые атрибуты множеств. При этом допустимы только одно- и двухмерные диапазоны на одном листе, а чтение диапазона происходит слева направо и сверху вниз.

Синтаксис применения @OLE функции:

object_list = @OLE([‘spreadsheet_file’] [, range_name_list]);

Здесь object_list – список объектов модели, разделяемых запятой, который может содержать имена множеств, атрибуты и скалярные переменные;

Spreadsheet_file – имя файла таблицы, содержащего данные; Range_name_list – список имен диапазонов.

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

Применение функции @OLE для экспорта решений возможно в двух синтаксических формах. 1-я форма:

@OLE( ['spreadsheet_file’] [, range_name_list]) = object_list;

Нетрудно видеть, что в этом выражении источником решения являются объекты модели, перечисленные в списке справа, а приемником – файл Excel. Случаи отсутствия части или всех аргументов слева воспринимаются аналогично рассмотренным для импорта. Аналогичными являются и варианты задания диапазонов.

Бóльшие возможности управления экспортом дает 2-я форма:

@OLE( ['spreadsheet_file’], range_name_list) =

@WRITEFOR( setname[ ( set_index_list) [ | conditional_ qualifier]] : output_obj_1[,…,output_obj_n]);

80

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