You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.4 KiB

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