alpar@1
|
1 |
/*Find the minimum value which satisfies the linear inequality:
|
alpar@1
|
2 |
a*x + b*y >= 1 {a,b,x,y Integers} {a,b > 0} {a,b entered on command line}
|
alpar@1
|
3 |
|
alpar@1
|
4 |
Nigel_Galloway@operamail.com
|
alpar@1
|
5 |
February 2008
|
alpar@1
|
6 |
*/
|
alpar@1
|
7 |
using System;
|
alpar@1
|
8 |
using System.Runtime.InteropServices;
|
alpar@1
|
9 |
|
alpar@1
|
10 |
unsafe class GLPK{
|
alpar@1
|
11 |
double *lp;
|
alpar@1
|
12 |
public int a;
|
alpar@1
|
13 |
public int b;
|
alpar@1
|
14 |
|
alpar@1
|
15 |
const string glpkLibrary = "libglpk.so";
|
alpar@1
|
16 |
readonly int GLP_FR = 1;
|
alpar@1
|
17 |
readonly int GLP_IV = 2;
|
alpar@1
|
18 |
readonly int GLP_DB = 4;
|
alpar@1
|
19 |
struct ConstraintMatrix{
|
alpar@1
|
20 |
public fixed int ia[3];
|
alpar@1
|
21 |
public fixed int ja[3];
|
alpar@1
|
22 |
public fixed double ar[3];
|
alpar@1
|
23 |
}
|
alpar@1
|
24 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
25 |
static extern double* glp_create_prob();
|
alpar@1
|
26 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
27 |
static extern void glp_add_rows(double* lp, int rows);
|
alpar@1
|
28 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
29 |
static extern void glp_add_cols(double* lp, int cols);
|
alpar@1
|
30 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
31 |
static extern void glp_set_col_bnds(double* lp, int col, int bound_type, double lower_bound, double upper_bound);
|
alpar@1
|
32 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
33 |
static extern void glp_set_col_kind(double* lp, int col, int kind);
|
alpar@1
|
34 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
35 |
static extern void glp_load_matrix(double* lp, int elements, int* ia, int* ja, double* ar);
|
alpar@1
|
36 |
public GLPK(int a, int b){
|
alpar@1
|
37 |
this.a = a;
|
alpar@1
|
38 |
this.b = b;
|
alpar@1
|
39 |
lp = glp_create_prob();
|
alpar@1
|
40 |
//Col 1 is x, Col 2 is y
|
alpar@1
|
41 |
glp_add_rows(lp, 1);
|
alpar@1
|
42 |
glp_add_cols(lp, 2);
|
alpar@1
|
43 |
glp_set_col_bnds(lp, 1, GLP_FR, 0.0, 0.0);
|
alpar@1
|
44 |
glp_set_col_bnds(lp, 2, GLP_FR, 0.0, 0.0);
|
alpar@1
|
45 |
glp_set_col_kind(lp, 1, GLP_IV);
|
alpar@1
|
46 |
glp_set_col_kind(lp, 2, GLP_IV);
|
alpar@1
|
47 |
//Row 1 is a*x + b*y
|
alpar@1
|
48 |
ConstraintMatrix CM = new ConstraintMatrix();
|
alpar@1
|
49 |
CM.ia[1]=1; CM.ja[1]=1; CM.ar[1]=a;
|
alpar@1
|
50 |
CM.ia[2]=1; CM.ja[2]=2; CM.ar[2]=b;
|
alpar@1
|
51 |
glp_load_matrix(lp, 2, CM.ia, CM.ja, CM.ar);
|
alpar@1
|
52 |
Console.WriteLine("Hello Nigel");
|
alpar@1
|
53 |
}
|
alpar@1
|
54 |
|
alpar@1
|
55 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
56 |
static extern void glp_set_row_bnds(double* lp, int row, int bound_type, double lower_bound, double upper_bound);
|
alpar@1
|
57 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
58 |
static extern void glp_simplex(double* lp, void* options);
|
alpar@1
|
59 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
60 |
static extern void glp_intopt(double* lp, void* options);
|
alpar@1
|
61 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
62 |
static extern double glp_mip_col_val(double* lp, int col);
|
alpar@1
|
63 |
public int betterGuess(int upper_bound){
|
alpar@1
|
64 |
//Find a new guess less than the old guess: 1 <= (a*x + b*y) <= (old guess - 1)
|
alpar@1
|
65 |
glp_set_row_bnds(lp, 1, GLP_DB, 1.0, ((double)upper_bound)-0.5);
|
alpar@1
|
66 |
glp_simplex(lp, null);
|
alpar@1
|
67 |
glp_intopt(lp, null);
|
alpar@1
|
68 |
int x = (int)glp_mip_col_val(lp, 1);
|
alpar@1
|
69 |
int y = (int)glp_mip_col_val(lp, 2);
|
alpar@1
|
70 |
int nextGuess = a*x + b*y;
|
alpar@1
|
71 |
Console.WriteLine("x = {0}, y = {1}, a*x + b*y = {2}",x,y,nextGuess);
|
alpar@1
|
72 |
return nextGuess;
|
alpar@1
|
73 |
}
|
alpar@1
|
74 |
|
alpar@1
|
75 |
[DllImport(glpkLibrary, SetLastError=true)]
|
alpar@1
|
76 |
static extern void glp_delete_prob(double* lp);
|
alpar@1
|
77 |
~GLPK(){
|
alpar@1
|
78 |
glp_delete_prob(lp);
|
alpar@1
|
79 |
Console.WriteLine("Goodbye Nigel");
|
alpar@1
|
80 |
}
|
alpar@1
|
81 |
|
alpar@1
|
82 |
}
|
alpar@1
|
83 |
|
alpar@1
|
84 |
class test{
|
alpar@1
|
85 |
static bool isMinimum(int a, int b, int guess){
|
alpar@1
|
86 |
Console.WriteLine("Trying {0}",guess);
|
alpar@1
|
87 |
if (a%guess > 0) return false;
|
alpar@1
|
88 |
if (b%guess > 0) return false;
|
alpar@1
|
89 |
Console.WriteLine("Solution is {0}",guess);
|
alpar@1
|
90 |
return true;
|
alpar@1
|
91 |
}
|
alpar@1
|
92 |
|
alpar@1
|
93 |
public static void Main(string[] args){
|
alpar@1
|
94 |
Console.WriteLine("a = {0}, b = {1}",args[0], args[1]);
|
alpar@1
|
95 |
GLPK lp = new GLPK(Int32.Parse(args[0]),Int32.Parse(args[1]));
|
alpar@1
|
96 |
int guess = (lp.a > lp.b) ? lp.b : lp.a;
|
alpar@1
|
97 |
while (!isMinimum(lp.a,lp.b,guess)) guess = lp.betterGuess(guess);
|
alpar@1
|
98 |
}
|
alpar@1
|
99 |
}
|