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.