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.

155 lines
4.9 KiB

  1. /* glpini01.c */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied
  6. * Informatics, Moscow Aviation Institute, Moscow, Russia. All rights
  7. * reserved. E-mail: <mao@gnu.org>.
  8. *
  9. * GLPK is free software: you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  17. * License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  21. ***********************************************************************/
  22. #include "env.h"
  23. #include "prob.h"
  24. #include "triang.h"
  25. /***********************************************************************
  26. * NAME
  27. *
  28. * glp_adv_basis - construct advanced initial LP basis
  29. *
  30. * SYNOPSIS
  31. *
  32. * void glp_adv_basis(glp_prob *P, int flags);
  33. *
  34. * DESCRIPTION
  35. *
  36. * The routine glp_adv_basis constructs an advanced initial LP basis
  37. * for the specified problem object.
  38. *
  39. * The parameter flag is reserved for use in the future and should be
  40. * specified as zero.
  41. *
  42. * NOTE
  43. *
  44. * The routine glp_adv_basis should be called after the constraint
  45. * matrix has been scaled (if scaling is used). */
  46. static int mat(void *info, int k, int ind[], double val[])
  47. { glp_prob *P = info;
  48. int m = P->m;
  49. int n = P->n;
  50. GLPROW **row = P->row;
  51. GLPCOL **col = P->col;
  52. GLPAIJ *aij;
  53. int i, j, len;
  54. if (k > 0)
  55. { /* retrieve scaled row of constraint matrix */
  56. i = +k;
  57. xassert(1 <= i && i <= m);
  58. len = 0;
  59. if (row[i]->type == GLP_FX)
  60. { for (aij = row[i]->ptr; aij != NULL; aij = aij->r_next)
  61. { j = aij->col->j;
  62. if (col[j]->type != GLP_FX)
  63. { len++;
  64. ind[len] = j;
  65. val[len] = aij->row->rii * aij->val * aij->col->sjj;
  66. }
  67. }
  68. }
  69. }
  70. else
  71. { /* retrieve scaled column of constraint matrix */
  72. j = -k;
  73. xassert(1 <= j && j <= n);
  74. len = 0;
  75. if (col[j]->type != GLP_FX)
  76. { for (aij = col[j]->ptr; aij != NULL; aij = aij->c_next)
  77. { i = aij->row->i;
  78. if (row[i]->type == GLP_FX)
  79. { len++;
  80. ind[len] = i;
  81. val[len] = aij->row->rii * aij->val * aij->col->sjj;
  82. }
  83. }
  84. }
  85. }
  86. return len;
  87. }
  88. void glp_adv_basis(glp_prob *P, int flags)
  89. { int i, j, k, m, n, min_mn, size, *rn, *cn;
  90. char *flag;
  91. if (flags != 0)
  92. xerror("glp_adv_basis: flags = %d; invalid flags\n", flags);
  93. m = P->m; /* number of rows */
  94. n = P->n; /* number of columns */
  95. if (m == 0 || n == 0)
  96. { /* trivial case */
  97. glp_std_basis(P);
  98. goto done;
  99. }
  100. xprintf("Constructing initial basis...\n");
  101. /* allocate working arrays */
  102. min_mn = (m < n ? m : n);
  103. rn = talloc(1+min_mn, int);
  104. cn = talloc(1+min_mn, int);
  105. flag = talloc(1+m, char);
  106. /* make the basis empty */
  107. for (i = 1; i <= m; i++)
  108. { flag[i] = 0;
  109. glp_set_row_stat(P, i, GLP_NS);
  110. }
  111. for (j = 1; j <= n; j++)
  112. glp_set_col_stat(P, j, GLP_NS);
  113. /* find maximal triangular part of the constraint matrix;
  114. to prevent including non-fixed rows and fixed columns in the
  115. triangular part, such rows and columns are temporarily made
  116. empty by the routine mat */
  117. #if 1 /* FIXME: tolerance */
  118. size = triang(m, n, mat, P, 0.001, rn, cn);
  119. #endif
  120. xassert(0 <= size && size <= min_mn);
  121. /* include in the basis non-fixed structural variables, whose
  122. columns constitute the triangular part */
  123. for (k = 1; k <= size; k++)
  124. { i = rn[k];
  125. xassert(1 <= i && i <= m);
  126. flag[i] = 1;
  127. j = cn[k];
  128. xassert(1 <= j && j <= n);
  129. glp_set_col_stat(P, j, GLP_BS);
  130. }
  131. /* include in the basis appropriate auxiliary variables, whose
  132. unity columns preserve triangular form of the basis matrix */
  133. for (i = 1; i <= m; i++)
  134. { if (flag[i] == 0)
  135. { glp_set_row_stat(P, i, GLP_BS);
  136. if (P->row[i]->type != GLP_FX)
  137. size++;
  138. }
  139. }
  140. /* size of triangular part = (number of rows) - (number of basic
  141. fixed auxiliary variables) */
  142. xprintf("Size of triangular part is %d\n", size);
  143. /* deallocate working arrays */
  144. tfree(rn);
  145. tfree(cn);
  146. tfree(flag);
  147. done: return;
  148. }
  149. /* eof */