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

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

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

В результате выполнения этого запроса в БД Library создаются 3 новые таблицы с введенными исходными данными. Одна из таблиц приведена на рис. 20.

Рис. 20

Вней не заполнен последний столбец, соответствующий переменным. Теперь загрузим в LINGO нашу модель и решим ее. При этом все исходные данные будут импортированы из БД, а решение экспортировано в нее: в столбце X появятся результаты решения задачи (рис. 21).

Втаблице EQUIPMENTS (здесь она не показана) также заполнится столбец атрибута TWORK, по которому определяется значение критерия.

101

Рис. 21

Замечание: при создании источника данных и при запуске решения требуется авторизация в Oracle.

Результаты решения выдаются в виде следующего текстового отчета:

Local optimal solution found.

784.0000

Objective value:

Objective bound:

784.0000

Infeasibilities:

0.000000

Extended solver steps:

2

Total solver iterations:

654

Elapsed runtime seconds:

9.58

102

Export Summary Report

 

---------------------

ODBC BASED

Transfer Method:

ODBC Data Source:

Production1

Data Table Name:

PR_EQS

Columns Specified:

1

X

12

LINGO Column Length:

Database Column Length:

12

Export Summary Report

 

---------------------

ODBC BASED

Transfer Method:

ODBC Data Source:

Production1

Data Table Name:

EQUIPMENTS

Columns Specified:

1

TWORK

3

LINGO Column Length:

Database Column Length:

3

Model Class:

 

PINLP

Total variables:

 

16

Nonlinear variables:

 

3

Integer variables:

 

18

Total constraints:

 

8

Nonlinear constraints:

 

1

Total nonzeros:

 

26

Nonlinear nonzeros:

 

3

Model Title: Production1

 

 

Variable

Value

Reduced Cost

TIME

784.0000

0.000000

...

...

...

Этот отчет полностью идентичен отчету, полученному с использованием БД Access (за исключением значения времени выполнения).

103

8.3.4. Использование БД SQL Server

Начинаем с создания таблиц задачи в имеющейся БД master. Для этого открываем SQL Server Management Studio и пишем запрос, как показано на скриншоте (рис. 22).

Рис. 22

104

В результате выполнения запроса в БД master создаются 3 таблицы, содержащие исходные данные задачи Production1 (модель тождественна Production).

Теперь определим БД как источник ODBC, сначала присвоив ему имя Production1, а затем выбрав для него драйвер SQL Server (рис. 23).

Рис. 23

Выполняем следующие шаги: в LINGO загружаем и решаем модель Production1, открываем в БД таблицы PR_EQS и EQUIPMENTS и убеждаемся, что решение экспортировано в БД

(рис. 24).

Полученный при этом текстовый отчет о решении здесь не показан, так как он идентичен отчету с БД Oracle.

Приведенные примеры с тремя СУБД достаточно подробно представили технологию создания источника данных ODBC.

105

Рис. 24

8.4. Взаимодействие с внешними приложениями

Для взаимодействия с приложениями пользователя LINGO

использует под Windows стандарт Dynamic Link Library (DLL),

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

106

Помимо основной библиотеки имеется много дополнительных компонентов DLL, которые устанавливаются как часть нормальной инсталляции LINGO.

Для Windows возможность вызова DLL является стандартной функцией всех сред разработки (Visual Basic, Delphi, Visual C++, C#.NET, Java и др.).

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

Для связи LINGO с внешним приложением может быть использована функция @POINTER, доступная в разделах data, init или calc. Она обеспечивает прямую связь между вызывающим приложением и решателем LINGO. Так как при этом исключается необходимость использования промежуточных файлов, прямая передача данных в LINGO и из LINGO очень эффективна по скорости.

Когда LINGO DLL вызывается, ей передается список указателей на память. В этом списке @POINTER(n) будет относиться к n-му указателю. Функция @POINTER применяется в модели только при доступе к LINGO через интерфейсы DLL или OLE.

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

Функция @POINTER при считывании и записи всех числовых данных (значений атрибутов) использует формат с плавающей запятой двойной точности. Элементы набора передаются как строки текста ASCII, причем каждый элемент разделяется символом линии, и список заканчивается нулем или ASCII 0. При этом следует выделять достаточное пространство памяти и проверять, что требуемые значения доступны в памяти.

107

Пример использования функции @POINTER:

DATA:

ORDER = @POINTER( 1); @POINTER( 2) = X; @POINTER( 3) = TWORK; @POINTER( 4) = TIME; @POINTER( 5) = @STATUS(); ENDDATA

Здесь значения атрибута ORDER считываются из первой части памяти, а экспортируемые значения атрибутов X, TWORK и TIME записываются во вторую, третью и четвертую области памяти. Значение, возвращаемое функцией @STATUS, помещается в пятую часть памяти.

LINGO DLL может экспортировать 12 функций, которые содержатся в файле Lingo16\Lingd16.Dll. Импортировать эти функции в приложение пользователя можно с помощью файла библиотеки

Lingo16\Programming Samples\Lingd16.lib. Все экспортируемые функции с кратким описанием приведены в приложении 5. Большинство из них возвращает код ошибки, который при успешном выполнении равен нулю, иначе он больше нуля (приложение 6).

8.4.1. Пример приложения

Приводимый пример взят из документации LINGO с небольшими изменениями [17]. Рассмотрим создание простого приложения

вVisual C++, используемого далее для решения задачи составления графика выхода сотрудников на работу исходя из ежедневной потребности в них (Needs).

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

внеделю. Часть сотрудников начинают свою пятидневку в понедельник, часть – во вторник и т.д. Необходимо определить, сколько сотрудников начинают свою пятидневку в определенные дни недели (Start), так, чтобы каждый день их было на работе (On Duty) не меньше потребности (Needs) при минимальном общем числе сотрудников.

108

Модель задачи в LINGO имеет следующий вид:

MODEL:

Title Staff Schedule; SETS:

DAYS / MON TUE WED THU FRI SAT SUN/: NEEDS, START, ONDUTY;

ENDSETS

[OBJECTIVE] MIN = @SUM(DAYS(I): START(I)); @FOR(DAYS(TODAY):

!Вычисление числа работающих по дням недели;

!Сегодня работают те, для кого это 1-й день, и те, кто начал;

!в предшествующие 4 дня;

ONDUTY(TODAY) = @SUM(DAYS(D)| D #LE# 5:

START(@WRAP(TODAY – D + 1,@SIZE(DAYS))));

! Удовлетворение потребности в сотрудниках;

ONDUTY(TODAY) >= NEEDS(TODAY); @GIN(START);

);

DATA:

NEEDS = @POINTER(1);

@POINTER(2) = START;

@POINTER(3) = ONDUTY; @POINTER(4) = OBJECTIVE; @POINTER(5) = @STATUS();

ENDDATA END

Для определения дня недели по порядковому номеру дня начала работы сотрудника использована функция @Wrap (см. подразд. 6.7). Функции @POINTER обеспечат обмен данными и решением между приложением и LINGO.

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

Для создания проекта приложения в Visual C++ в меню File/New выбираем Projects, записываем имя проекта Staff и выбираем MFC AppWizard(Exe) в качестве типа приложения, нажимаем OК. Затем после нажатия Next помечаем dialog based, снова нажимаем кнопку Next, чистим About box, помечаем OLE Automation и OLE

109

Controls, дважды используем Next и, наконец, кнопку Finish (поддержка OLE необходима для LINGO DLL). В результате открывается окно создания формы диалогового окна приложения. Используя диалоговый редактор, конструируем диалоговое окно (рис. 25).

Рис. 25

На этой стадии также можно получить информацию о проекте

(рис. 26).

После нажатия OK будет сгенерирован код скелетона (структуры) проекта.

Теперь используем ClassWizard в Visual C ++ для связывания переменных с каждым полем в диалоговом окне. В меню View вы-

бираем команду ClassWizard, а затем вкладку Member Variables.

Чтобы сделать LINGO DLL доступной для кода, нужно добавить в проект библиотеку импорта LINGO DLL. Для этого запускаем ко-

110

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