< GLPK

This page describes a C++ class that wraps the C-style GLPK vectors ia, ja, and ar. The class can be used directly with C++ or via language bindings for Java and R created with SWIG.

IAJAAR.H project

IAJAAR.H is a small project that provides the specialized triple container class IAJAAR. The purpose of this C++ class is to offer more convenient problem build calls than those available using straight C code. The author is Nigel Galloway.

C++ class IAJAAR definition

The C++ IAJAAR class definition is:

//  File: 'iajaar.h'
//  Provides: C++ class 'IAJAAR'

class IAJAAR
{
private:
  int *    xia;
  int *    xja;
  double * xar;
  int      entry;
  int      maxSize;
public:
 ~IAJAAR();                                  // destructor, deallocate memory
  IAJAAR(int s);                             // constructor, s is maximum array length
  const int * ia();                          // return C-style int array
  const int * ja();                          // return C-style int array
  const double * ar();                       // return C-style double array
  void Add(int row, int col, double value);
  int ne();                                  // return number of entries
};

The member function IAJAAR::Add adds 3-tuples (triples) in the form (row, col, value). The respective arrays can be later retrieved using the member functions IAJAAR::ia, IAJAAR::ja, and IAJAAR::ar. The member function IAJAAR::ne returns the current number of entries.

IAJAAR is designed to work with the following GLPK routine:

void glp_load_matrix(glp_prob *lp, int ne, const int ia[], const int ja[], const double ar[]);


It would be possible to reformulate class IAJAAR using std::vectors internally. That would omit the need to pre-specify the maximum size s in advance, although an optional hint could be given.

C++ usage

Usage with C++ is straightforward no special language bindings are required. A description of the underlying problem is can be found on the project website.

//  File: 'igst10yo.cpp'
//  An example of using IAJAAR.H with GLPK in C++.
//  Usage: 'igst10yo.cpp 6.5 7' will calculate 6.5 divided by 7.
//  Nigel Galloway / July 2009

#include <iostream>
#include <stdlib.h>
#include "iajaar.h"          // see above on wikipage
#include "glpk.h"

int main(int argc, char * argv[])
{
  double Q = atof(argv[1]);
  int    N = atoi(argv[2]);
  IAJAAR * igst10yo = new IAJAAR(5*N);
  glp_prob * lp = glp_create_prob();
  // col 1 is M
  // cols 2 .. N+1 is a sample of N numbers which sum to Q
  // cols N+2 .. 2*N+1 are v[1..N]
  glp_add_rows(lp,N+2);
  glp_add_cols(lp,2*N+1);
  for(int i=1; i<=2*N+1; i++) glp_set_col_bnds(lp,i,GLP_FR,0,0);
  glp_set_row_bnds(lp,N+1,GLP_FX,Q,Q);
  glp_set_row_bnds(lp,N+2,GLP_FX,0,0);
  try {
    for(int i=1; i<=N; i++) {
      glp_set_row_bnds(lp,i,GLP_FX,0,0);
      igst10yo->Add(i,i+1,-1);
      igst10yo->Add(i,1,1);
      igst10yo->Add(i,i+N+1,1);
      igst10yo->Add(N+1,i+1,1);
      igst10yo->Add(N+2,i+N+1,1);
    }
  } catch (char * error) {
    std::cout << error << std::endl;
  }
  glp_load_matrix(lp,igst10yo->ne(),igst10yo->ia(),igst10yo->ja(),igst10yo->ar());
  glp_simplex(lp,NULL);
  double Result = glp_get_col_prim(lp,1);
  std::cout << "The arithmetic mean of a sample of " << N
            << " numbers whose sum is " << Q << " is " << Result
            << std::endl;
  delete igst10yo;
  glp_delete_prob(lp);
  return 0;
}

Python usage

IAJAAR can be used with Python. This February 2011 posting explains more.

Java usage

Java usage requires dedicated language bindings. Unlike the C++ example, Q and N are hardcoded.

/*
  File: 'gmst10yo.java'
  Usage: 'java -classpath IAJAAR_JAVA.jar;GLPK_JAVA.jar;. gmst10yo'
  will calculate 22 divided by 7.
  Modify Q and N below to try alternatives.
  Nigel Galloway / July 2009
*/

import org.gnu.glpk.*;

public class gmst10yo {
  static {
    System.loadLibrary("IAJAAR_JAVA");
  }
  public static void main(String argv[]) {
    double Q = 22;
    int N = 7;
    IAJAAR t = new IAJAAR(3*N);
    glp_prob lp = GLPK.glp_create_prob();
    GLPK.glp_add_rows(lp,N+1);
    /* col 1 is M
       cols 2 .. N+1 are S[n]
    */
    GLPK.glp_add_cols(lp,N+1);
    for(int i=1; i<=N+1; i++) GLPK.glp_set_col_bnds(lp,i,GLPK.GLP_FR,0,0);
    t.Add(1,1,1);
    t.Add(1,2,1);
    t.Add(N+1,2,1);
    GLPK.glp_set_row_bnds(lp,N+1,GLPK.GLP_FX,0,0);
    GLPK.glp_set_row_bnds(lp,1,GLPK.GLP_FX,Q,Q);
    for(int i=2; i<=N; i++){
            GLPK.glp_set_row_bnds(lp,i,GLPK.GLP_FX,0,0);
            t.Add(i,1,1);
            t.Add(i,i+1,1);
            t.Add(N+1,i+1,1);
    }
    GLPK.glp_load_matrix(lp,t.ne(),t.ia(),t.ja(),t.ar());
    GLPK.glp_simplex(lp,null);
    double Result = GLPK.glp_get_col_prim(lp,1);
    GLPK.glp_delete_prob(lp);
    System.out.println("The arithmetic mean of a sample of " + N 
                       + " numbers which sum to " + Q + " is " + Result);
  }
}

R usage

R usage requires dedicated language bindings. Unlike the C++ example, Q and N are hard-coded.

#  File: 'gist10yo.R'
#  Nigel Galloway / July 2009

dyn.load(paste("GLPK_R", .Platform$dynlib.ext, sep=""))
source("GLPKconstants.R")
source("GLPK_R.R")
cacheMetaData(1)
Q <- 22
N <- 7
t <- IAJAAR(6)
lp <- glp_create_prob()
glp_add_rows(lp,3)
#  col 1 is M
#  col 2 is v1
#  col 3 is v2
glp_add_cols(lp,3)
glp_set_col_bnds(lp,1,GLP_FR,0,0)
glp_set_col_bnds(lp,2,GLP_FR,0,0)
glp_set_col_bnds(lp,3,GLP_FR,0,0)
IAJAAR_Add(t,1,1,1)
IAJAAR_Add(t,1,2,1)
IAJAAR_Add(t,2,1,1)
IAJAAR_Add(t,2,3,1)
IAJAAR_Add(t,3,2,1)
IAJAAR_Add(t,3,3,N-1)
glp_set_row_bnds(lp,1,GLP_FX,Q,Q)
glp_set_row_bnds(lp,2,GLP_FX,0,0)
glp_set_row_bnds(lp,3,GLP_FX,0,0)
loadMatrix(t,lp);
delete(t)
if (glp_simplex(lp,t)==0) {
  R <- glp_get_col_prim(lp,1)
  print(sprintf("The arithmetic mean of a sample of %f numbers which sum to %f is %f",N,Q,R))
} else {
  print("No solution")
}

Further information is available from the project website. In particular, the source code for iajaar.cpp is worth reviewing.

This article is issued from Wikibooks. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.