Initializing help system before first use

Accessing modeling objects and solution values

Using the Mosel libraries, it is not only possible to compile and run models, but also to access information on the different modeling objects.

Accessing sets

A complete version of a program (file ugparam1.c) for running the model `Prime' mentioned in the previous section may look as follows (we work with a model prime2 that corresponds to the one printed in Section Working with sets but with all output printing removed because we are doing this in C, furthermore all entities accessed from C must be explicitly declared as public):

#include <stdio.h>
#include "xprm_mc.h"

int main()
{
 XPRMmodel mod;
 XPRMalltypes rvalue, setitem;
 XPRMset set;
 int result, type, i, size, first, last;

 if(XPRMinit())                              /* Initialize Mosel */
  return 1;

 if(XPRMexecmod(NULL, "prime2.mos", "LIMIT=500", &result, &mod))
  return 2;                                  /* Execute the model */

 type=XPRMfindident(mod, "SPrime", &rvalue); /* Get the object 'SPrime' */
 if((XPRM_TYP(type)!=XPRM_TYP_INT)||         /* Check the type: */
    (XPRM_STR(type)!=XPRM_STR_SET))          /* it must be a set of integers */
  return 3;
 set = rvalue.set;

 size = XPRMgetsetsize(set);                 /* Get the size of the set */
 if(size>0)
 {
  first = XPRMgetfirstsetndx(set);           /* Get number of the first index */
  last = XPRMgetlastsetndx(set);             /* Get number of the last index */
  printf("Prime numbers from 2 to %d:\n", LIM);
  for(i=first;i<=last;i++)                   /* Print all set elements */
   printf(" %d,", XPRMgetelsetval(set,i,&setitem)->integer);
  printf("\n");
 }

 XPRMfinish();                               /* Finish Mosel */

 return 0;
}

To print the contents of set SPrime that contains the desired result (prime numbers between 2 and 500), we first retrieve the Mosel reference to this object using function XPRMfindident. We are then able to enumerate the elements of the set (using functions XPRMgetfirstsetndx and XPRMgetlastsetndx) and obtain their respective values with XPRMgetelsetval.

Retrieving solution values

The following program ugsol1.c executes the model `Burglar3' (the same as model `Burglar2' from Chapter Some illustrative examples but with all output printing removed and all model entities declared as public) and prints out its solution.

#include <stdio.h>
#include "xprm_rt.h"

int main()
{
 XPRMmodel mod;
 XPRMalltypes rvalue, itemname;
 XPRMarray varr, darr;
 XPRMmpvar x;
 XPRMset set;
 int indices[1], result, type;
 double val;

 if(XPRMinit())                            /* Initialize Mosel */
  return 1;

 if((mod=XPRMloadmod("burglar3.bim", NULL))==NULL)  /* Load a BIM file */
  return 2;

 if(XPRMrunmod(mod, &result, NULL))        /* Run the model (includes
                                              optimization) */
  return 3;

 if((XPRMgetprobstat(mod)&XPRM_PBRES)!=XPRM_PBOPT)
  return 4;                                /* Test whether a solution is found */

 printf("Objective value: %g\n", XPRMgetobjval(mod));
                                           /* Print the obj. function value */

 type=XPRMfindident(mod,"take",&rvalue);   /* Get the model object 'take' */
 if((XPRM_TYP(type)!=XPRM_TYP_MPVAR)||     /* Check the type: */
    (XPRM_STR(type)!=XPRM_STR_ARR))        /* it must be an `mpvar' array */
  return 5;
 varr = rvalue.array;

 type=XPRMfindident(mod,"VALUE",&rvalue);  /* Get the model object 'VALUE' */
 if((XPRM_TYP(type)!=XPRM_TYP_REAL)||      /* Check the type: */
    (XPRM_STR(type)!=XPRM_STR_ARR))        /* it must be an array of reals */
  return 6;
 darr = rvalue.array;

 type=XPRMfindident(mod,"ITEMS",&rvalue);  /* Get the model object 'ITEMS' */
 if((XPRM_TYP(type)!=XPRM_TYP_STRING)||    /* Check the type: */
    (XPRM_STR(type)!=XPRM_STR_SET))        /* it must be a set of strings */
  return 7;
 set = rvalue.set;

 XPRMgetfirstarrentry(varr, indices);      /* Get the first entry of array varr
                                              (we know that the array is dense
                                              and has a single dimension) */
 do
 {
  XPRMgetarrval(varr, indices, &x);        /* Get a variable from varr */
  XPRMgetarrval(darr, indices, &val);      /* Get the corresponding value */
  printf("take(%s): %g\t (item value: %g)\n", XPRMgetelsetval(set, indices[0],
         &itemname)->string, XPRMgetvsol(mod,x), val);
                                           /* Print the solution value */
 } while(!XPRMgetnextarrentry(varr, indices));  /* Get the next index tuple */

 XPRMfinish();                             /* Finish Mosel, clear everything */

 return 0;
}

The array of variables varr is enumerated using the array functions XPRMgetfirstarrentry and XPRMgetnextarrentry. These functions may be applied to arrays of any type and dimension (for higher numbers of dimensions, merely the size of the array indices that is used to store the index-tuples has to be adapted). With these functions we run systematically through all possible combinations of index tuples, hence the hint at dense arrays in the example. In the case of sparse arrays it is preferrable to use different enumeration functions that only enumerate those entries that are defined (see next section).

Sparse arrays

In Chapter More advanced modeling features the problem `Transport' has been introduced. The objective of this problem is to calculate the flows flowpr from a set of plants to a set of sales regions that satisfy all demand and supply constraints and minimize the total cost. Not all plants may deliver goods to all regions. The flow variables flowpr are therefore defined as a sparse array. The following example (file ugarray1.c) prints out all existing entries of the array of variables.

#include <stdio.h>
#include <stdlib.h>
#include "xprm_rt.h"

int main()
{
 XPRMmodel mod;
 XPRMalltypes rvalue;
 XPRMarray varr;
 XPRMset *sets;
 int *indices, dim, result, type, i;

 if(XPRMinit())                          /* Initialize Mosel */
  return 1;

 if((mod=XPRMloadmod("transport.bim", NULL))==NULL)  /* Load a BIM file */
  return 2;

 if(XPRMrunmod(mod, &result, NULL))      /* Run the model */
  return 3;

 type=XPRMfindident(mod,"flow",&rvalue); /* Get the model object named 'flow' */
 if((XPRM_TYP(type)!=XPRM_TYP_MPVAR)||   /* Check the type: */
    (XPRM_STR(type)!=XPRM_STR_ARR))      /* it must be an array of unknowns */
  return 4;
 varr=rvalue.array;

 dim = XPRMgetarrdim(varr);              /* Get the number of dimensions of
                                            the array */
 indices = (int *)malloc(dim*sizeof(int));
 sets = (XPRMset *)malloc(dim*sizeof(XPRMset));

 XPRMgetarrsets(varr,sets);              /* Get the indexing sets  */
 XPRMgetfirstarrtruentry(varr,indices);  /* Get the first true index tuple */
 do
 {
  printf("flow(");
  for(i=0;i<dim-1;i++)
   printf("%s,",XPRMgetelsetval(sets[i],indices[i],&rvalue)->string);
  printf("%s), ",XPRMgetelsetval(sets[dim-1],indices[dim-1],&rvalue)->string);
 } while(!XPRMgetnextarrtruentry(varr,indices));  /* Get next true index tuple*/
 printf("\n");

 free(sets);
 free(indices);
 XPRMresetmod(mod);

 return 0;
}

In this example, we first get the number of indices (dimensions) of the array of variables varr (using function XPRMgetarrdim). We use this information to allocate space for the arrays sets and indices that will be used to store the indexing sets and single index tuples for this array respectively. We then read the indexing sets of the array (function XPRMgetarrsets) to be able to produce a nice printout.

The enumeration starts with the first defined index tuple, obtained with function XPRMgetfirstarrtruentry, and continues with a series of calls to XPRMgetnextarrtruentry until all defined entries have been enumerated.

At the end of the program example we have reset the model (using function XPRMresetmod), thus freeing some resources allocated to it, in particular deleting temporary files that may have been created during its execution.

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.