以我的习惯,在MATLAB安装目录下新建一个名为works的文件夹,将Staff.m和STAFFPTR.lng文件放在这个文件目录下,然后把Lingd15.h和Lingd15.lib放在LINGO安装目录下,好,开始吧。
1. STAFFPTR.lng
MODEL:
SETS:
DAYS / MON TUE WED THU FRI SAT SUN/:
NEEDS, START, ONDUTY;
ENDSETS
[OBJECTIVE] MIN = @SUM( DAYS( I): START( I));
@FOR( DAYS( TODAY):
! Calculate number on duty;
ONDUTY( TODAY) =
@SUM( DAYS( D)| D #LE# 5:
START( @WRAP( TODAY - D + 1, @SIZE( DAYS))));
! Enforce staffing requirement;
ONDUTY( TODAY) >= NEEDS( TODAY);
@GIN( START);
);
DATA:
NEEDS = @POINTER( 1);
@POINTER( 2) = START;
@POINTER( 3) = ONDUTY;
@POINTER( 4) = OBJECTIVE;
@POINTER( 5) = @STATUS();
ENDDATA
END
2. Staff.m
clear; clc;
% By default, Lingo API is in the d:\LINGO15 folder
addpath('D:\\LINGO15');
% Load the Lingo API
loadlibrary('Lingd15', 'Lingd15.h');
if ~libisloaded('Lingd15')
error('Cannot load LINGO library');
end
% Print out LINGO library functions
libfunctions('Lingd15', '-full');
% Create the Lingo environment
pLingo = calllib('Lingd15', 'LScreateEnvLng');
if ~( exist('pLingo', 'var') && isa(pLingo, 'lib.pointer') )
error('Cannot create LINGO environment object');
end
% Open a Lingo log file
nError = calllib('Lingd15', 'LSopenLogFileLng', pLingo, 'D:\\LINGO15\\testLingoLib15.log');
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot open LINGO log file');
end
% Staffing needs
dNeeds = [1 4 3 7 2 5 3];
% Pointers to memory transfer areas
dNeedsPtr = libpointer('doublePtr', dNeeds);
dStartPtr = libpointer('doublePtr', zeros(1, 7));
dOnDutyPtr = libpointer('doublePtr', zeros(1, 7));
dStatusPtr = libpointer('doublePtr', -1);
dTotalPtr = libpointer('doublePtr', 0);
nPointerNowPtr = libpointer('int32Ptr', 0);
% Pass memory transfer pointers to LINGO
nError = calllib('Lingd15', 'LSsetPointerLng', pLingo, dNeedsPtr, nPointerNowPtr);
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot assign pointer');
end
nError = calllib('Lingd15', 'LSsetPointerLng', pLingo, dStartPtr, nPointerNowPtr);
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot assign pointer');
end
nError = calllib('Lingd15', 'LSsetPointerLng', pLingo, dOnDutyPtr, nPointerNowPtr);
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot assign pointer');
end
nError = calllib('Lingd15', 'LSsetPointerLng', pLingo, dTotalPtr, nPointerNowPtr);
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot assign pointer');
end
nError = calllib('Lingd15', 'LSsetPointerLng', pLingo, dStatusPtr, nPointerNowPtr);
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot assign pointer');
end
% Set up the command script
csScript = 'SET ECHOIN 1 \n';
csScript = [csScript 'TAKE STAFFPTR.lng \n'];
csScript = [csScript 'GO \n'];
csScript = [csScript 'QUIT \n'];
% Run the script
nError = calllib('Lingd15', 'LSexecuteScriptLng', pLingo, sprintf(csScript));
if ~strcmp( nError, 'LSERR_NO_ERROR_LNG')
error('Cannot execute script');
end
% Close log file
calllib('Lingd15', 'LScloseLogFileLng', pLingo);
% Optimal?
if get(dStatusPtr, 'value')
error('Unable to solve!');
else
% Display solution
disp(['Start : ' num2str(dStartPtr.value)]);
disp(['Needs : ' num2str(dNeedsPtr.value)]);
disp(['On Duty: ' num2str(dOnDutyPtr.value)]);
end
% Free Lingo environment
calllib('Lingd15', 'LSdeleteEnvLng', pLingo);
3. 注意,MATLAB当前目录为先前创建的works文件夹,运行看结果:
MATLAB显示的:
Warning: The data type 'FcnPtr' used by function LSsetCallbackErrorLng does not exist.
> In loadlibrary (line 431)
In Staff (line 7)
Warning: The data type 'FcnPtr' used by function LSsetCallbackSolverLng does not exist.
> In loadlibrary (line 431)
In Staff (line 7)
Start : 0 4 1 0 0 0 2
Needs : 1 4 3 7 2 5 3
On Duty: 2 6 7 7 5 5 3
testLingoLib15.log文件中的:
Global optimal solution found.
Objective value: 7.000000000000
Objective bound: 7.000000000000
Infeasibilities: 0.000000000000
Extended solver steps: 0
Total solver iterations: 4
Elapsed runtime seconds: 0.00
Running output operations ...
Model Class: MILP
Total variables: 14
Nonlinear variables: 0
Integer variables: 7
Total constraints: 15
Nonlinear constraints: 0
Total nonzeros: 56
Nonlinear nonzeros: 0
Variable Value Reduced Cost
NEEDS( MON) 1.000000000000 0.000000000000
NEEDS( TUE) 4.000000000000 0.000000000000
NEEDS( WED) 3.000000000000 0.000000000000
NEEDS( THU) 7.000000000000 0.000000000000
NEEDS( FRI) 2.000000000000 0.000000000000
NEEDS( SAT) 5.000000000000 0.000000000000
NEEDS( SUN) 3.000000000000 0.000000000000
START( MON) 0.000000000000 1.000000000000
START( TUE) 4.000000000000 1.000000000000
START( WED) 1.000000000000 1.000000000000
START( THU) 0.000000000000 1.000000000000
START( FRI) 0.000000000000 1.000000000000
START( SAT) 0.000000000000 1.000000000000
START( SUN) 2.000000000000 1.000000000000
ONDUTY( MON) 2.000000000000 0.000000000000
ONDUTY( TUE) 6.000000000000 0.000000000000
ONDUTY( WED) 7.000000000000 0.000000000000
ONDUTY( THU) 7.000000000000 0.000000000000
ONDUTY( FRI) 5.000000000000 0.000000000000
ONDUTY( SAT) 5.000000000000 0.000000000000
ONDUTY( SUN) 3.000000000000 0.000000000000
Row Slack or Surplus Dual Price
OBJECTIVE 7.000000000000 -1.000000000000
2 0.000000000000 0.000000000000
3 1.000000000000 0.000000000000
4 0.000000000000 0.000000000000
5 2.000000000000 0.000000000000
6 0.000000000000 0.000000000000
7 4.000000000000 0.000000000000
8 0.000000000000 0.000000000000
9 0.000000000000 0.000000000000
10 0.000000000000 0.000000000000
11 3.000000000000 0.000000000000
12 0.000000000000 0.000000000000
13 0.000000000000 0.000000000000
14 0.000000000000 0.000000000000
15 0.000000000000 0.000000000000
: QUIT
OK, done!