Passing Set Members with @POINTER - The Code
Here is a copy of the C code we will use to drive our application:
#include <stdlib.h>
#include <string.h>
#include "..\..\lingd17.h"
/*
Solves a simple knapsack problem, passing
all data to Lingo and retrieving the optimal
set of knapsack items for display
*/
void main()
{
// input data for model:
// potential items in knapsack
char pcItems[256] = "ANT_REPEL \n BEER \n BLANKET \n"
"BRATWURST \n BROWNIES \n FRISBEE \n SALAD \n"
"WATERMELON";
// and their weights
double pdItemWeight[8] = { 1, 3, 4, 3, 3, 1, 5,10};
// and their rankings
double pdItemRank[8] = { 2, 9, 3, 8,10, 6, 4,10};
// knapsack size
double dSackSize = 15;
// other declarations
int i, nPointersNow, nError;
double dStatus=-1.0;
char pcScript[256];
char pcItemsSolution[256];
// create the LINGO environment object
pLSenvLINGO pLINGO;
pLINGO = LScreateEnvLng();
if ( !pLINGO)
{
printf( "Can''t create LINGO environment!\n");
goto FinalExit;
}
// Open LINGO's log file
nError = LSopenLogFileLng( pLINGO, "LINGO.log");
if ( nError) goto ErrorExit;
// Pass memory transfer pointers to LINGO
// @POINTER(1) - Items set
nError = LSsetPointerLng( pLINGO, (void*) pcItems,
&nPointersNow);
if ( nError) goto ErrorExit;
// @POINTER(2) - Item weights
nError = LSsetPointerLng( pLINGO, (void*) pdItemWeight,
&nPointersNow);
if ( nError) goto ErrorExit;
// @POINTER(3) - Item ranks
nError = LSsetPointerLng( pLINGO, (void*) pdItemRank,
&nPointersNow);
if ( nError) goto ErrorExit;
// @POINTER(4) - Sack size
nError = LSsetPointerLng( pLINGO, (void*) &dSackSize,
&nPointersNow);
if ( nError) goto ErrorExit;
// @POINTER(5) - Output region for optimal items set
nError = LSsetPointerLng( pLINGO, (void*) pcItemsSolution,
&nPointersNow);
if ( nError) goto ErrorExit;
// @POINTER(6) - Variable to receive solution status
nError = LSsetPointerLng( pLINGO, &dStatus, &nPointersNow);
if ( nError) goto ErrorExit;
// Here is the script we want LINGO to run:
// Load the model, solve the model, exit.
strcpy( pcScript, "TAKE SACK.LNG \n GO \n QUIT \n");
// Run the script
nError = LSexecuteScriptLng( pLINGO, pcScript);
if ( nError) goto ErrorExit;
// display solution status
printf("\nSolution status (should be 0): %d\n", (int) dStatus);
// display items in optimal sack
printf("\nItems in optimal sack:\n%s\n", pcItemsSolution);
// Close the log file
LScloseLogFileLng( pLINGO);
// All done
goto NormalExit;
ErrorExit:
printf("LINGO Error Code: %d\n", nError);
NormalExit:
LSdeleteEnvLng( pLINGO);
FinalExit: ;
}
SACK.C
There are a couple of interesting features to note in this code pertaining to the passing of set members. First off, there is the declaration of the original set members:
// potential items in knapsack
char pcItems[256] = "ANT_REPEL \n BEER \n BLANKET \n"
"BRATWURST \n BROWNIES \n FRISBEE \n SALAD \n"
"WATERMELON";
The set members are merely listed as one long string, separated by line feeds (\n). We also added blank spaces for readability, which LINGO strips out when it parses the names. Note, that since we are working in C, there is an implicit null byte at the end of this string due to the use of double quotes. This terminating null is important, because it lets LINGO know where the end of the list occurs.
We pass a pointer to the set to LINGO with the following call to LSsetPointerLng
// @POINTER(1) - Items set
nError = LSsetPointerLng( pLINGO, (void*) pcItems,
&nPointersNow);
if ( nError) goto ErrorExit;
We pass a pointer to the set to LINGO with the following call to LSsetPointerLng. For receiving the optimal set of items back from LINGO we set aside the following text array: char pcItemsSolution[256];
We let LINGO know to store the solution set in this array with the following call to LSsetPointerLng:
// @POINTER(5) - Output region for optimal items set
nError = LSsetPointerLng( pLINGO, (void*) pcItemsSolution,
&nPointersNow);
Recall that this statement in the code pairs with the following statement in the model to establish the link for receiving the optimal set of items:
!send optimal items set back to caller;
@POINTER( 5) = ITEMSUSED;
If you have Visual C/C++ 6.0 installed on your machine, you should be able to build the application by going to the \LINGO17\Programming Samples\VC++\Knapsack folder and issuing the NMAKE command. Alternatively, you may simply go to the folder and run the sack.exe executable. After running the application, you should see the following:
Solution status (should be 0): 0
Items in optimal sack:
ANT_REPEL
BEER
BLANKET
BRATWURST
BROWNIES
FRISBEE
From the solution we see that all items except the salad an watermelon are included in the optimal solution.