alpar@1: /*Find the minimum value which satisfies the linear inequality: alpar@1: a*x + b*y >= 1 {a,b,x,y Integers} {a,b > 0} {a,b entered on command line} alpar@1: alpar@1: Nigel_Galloway@operamail.com alpar@1: February 2008 alpar@1: */ alpar@1: using System; alpar@1: using System.Runtime.InteropServices; alpar@1: alpar@1: unsafe class GLPK{ alpar@1: double *lp; alpar@1: public int a; alpar@1: public int b; alpar@1: alpar@1: const string glpkLibrary = "libglpk.so"; alpar@1: readonly int GLP_FR = 1; alpar@1: readonly int GLP_IV = 2; alpar@1: readonly int GLP_DB = 4; alpar@1: struct ConstraintMatrix{ alpar@1: public fixed int ia[3]; alpar@1: public fixed int ja[3]; alpar@1: public fixed double ar[3]; alpar@1: } alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern double* glp_create_prob(); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_add_rows(double* lp, int rows); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_add_cols(double* lp, int cols); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_set_col_bnds(double* lp, int col, int bound_type, double lower_bound, double upper_bound); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_set_col_kind(double* lp, int col, int kind); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_load_matrix(double* lp, int elements, int* ia, int* ja, double* ar); alpar@1: public GLPK(int a, int b){ alpar@1: this.a = a; alpar@1: this.b = b; alpar@1: lp = glp_create_prob(); alpar@1: //Col 1 is x, Col 2 is y alpar@1: glp_add_rows(lp, 1); alpar@1: glp_add_cols(lp, 2); alpar@1: glp_set_col_bnds(lp, 1, GLP_FR, 0.0, 0.0); alpar@1: glp_set_col_bnds(lp, 2, GLP_FR, 0.0, 0.0); alpar@1: glp_set_col_kind(lp, 1, GLP_IV); alpar@1: glp_set_col_kind(lp, 2, GLP_IV); alpar@1: //Row 1 is a*x + b*y alpar@1: ConstraintMatrix CM = new ConstraintMatrix(); alpar@1: CM.ia[1]=1; CM.ja[1]=1; CM.ar[1]=a; alpar@1: CM.ia[2]=1; CM.ja[2]=2; CM.ar[2]=b; alpar@1: glp_load_matrix(lp, 2, CM.ia, CM.ja, CM.ar); alpar@1: Console.WriteLine("Hello Nigel"); alpar@1: } alpar@1: alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_set_row_bnds(double* lp, int row, int bound_type, double lower_bound, double upper_bound); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_simplex(double* lp, void* options); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_intopt(double* lp, void* options); alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern double glp_mip_col_val(double* lp, int col); alpar@1: public int betterGuess(int upper_bound){ alpar@1: //Find a new guess less than the old guess: 1 <= (a*x + b*y) <= (old guess - 1) alpar@1: glp_set_row_bnds(lp, 1, GLP_DB, 1.0, ((double)upper_bound)-0.5); alpar@1: glp_simplex(lp, null); alpar@1: glp_intopt(lp, null); alpar@1: int x = (int)glp_mip_col_val(lp, 1); alpar@1: int y = (int)glp_mip_col_val(lp, 2); alpar@1: int nextGuess = a*x + b*y; alpar@1: Console.WriteLine("x = {0}, y = {1}, a*x + b*y = {2}",x,y,nextGuess); alpar@1: return nextGuess; alpar@1: } alpar@1: alpar@1: [DllImport(glpkLibrary, SetLastError=true)] alpar@1: static extern void glp_delete_prob(double* lp); alpar@1: ~GLPK(){ alpar@1: glp_delete_prob(lp); alpar@1: Console.WriteLine("Goodbye Nigel"); alpar@1: } alpar@1: alpar@1: } alpar@1: alpar@1: class test{ alpar@1: static bool isMinimum(int a, int b, int guess){ alpar@1: Console.WriteLine("Trying {0}",guess); alpar@1: if (a%guess > 0) return false; alpar@1: if (b%guess > 0) return false; alpar@1: Console.WriteLine("Solution is {0}",guess); alpar@1: return true; alpar@1: } alpar@1: alpar@1: public static void Main(string[] args){ alpar@1: Console.WriteLine("a = {0}, b = {1}",args[0], args[1]); alpar@1: GLPK lp = new GLPK(Int32.Parse(args[0]),Int32.Parse(args[1])); alpar@1: int guess = (lp.a > lp.b) ? lp.b : lp.a; alpar@1: while (!isMinimum(lp.a,lp.b,guess)) guess = lp.betterGuess(guess); alpar@1: } alpar@1: }