glpios08.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. /* glpios08.c (clique cut generator) */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  6. * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
  7. * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
  8. * E-mail: <mao@gnu.org>.
  9. *
  10. * GLPK is free software: you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  18. * License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************/
  23. #include "glpios.h"
  24. static double get_row_lb(LPX *lp, int i)
  25. { /* this routine returns lower bound of row i or -DBL_MAX if the
  26. row has no lower bound */
  27. double lb;
  28. switch (lpx_get_row_type(lp, i))
  29. { case LPX_FR:
  30. case LPX_UP:
  31. lb = -DBL_MAX;
  32. break;
  33. case LPX_LO:
  34. case LPX_DB:
  35. case LPX_FX:
  36. lb = lpx_get_row_lb(lp, i);
  37. break;
  38. default:
  39. xassert(lp != lp);
  40. }
  41. return lb;
  42. }
  43. static double get_row_ub(LPX *lp, int i)
  44. { /* this routine returns upper bound of row i or +DBL_MAX if the
  45. row has no upper bound */
  46. double ub;
  47. switch (lpx_get_row_type(lp, i))
  48. { case LPX_FR:
  49. case LPX_LO:
  50. ub = +DBL_MAX;
  51. break;
  52. case LPX_UP:
  53. case LPX_DB:
  54. case LPX_FX:
  55. ub = lpx_get_row_ub(lp, i);
  56. break;
  57. default:
  58. xassert(lp != lp);
  59. }
  60. return ub;
  61. }
  62. static double get_col_lb(LPX *lp, int j)
  63. { /* this routine returns lower bound of column j or -DBL_MAX if
  64. the column has no lower bound */
  65. double lb;
  66. switch (lpx_get_col_type(lp, j))
  67. { case LPX_FR:
  68. case LPX_UP:
  69. lb = -DBL_MAX;
  70. break;
  71. case LPX_LO:
  72. case LPX_DB:
  73. case LPX_FX:
  74. lb = lpx_get_col_lb(lp, j);
  75. break;
  76. default:
  77. xassert(lp != lp);
  78. }
  79. return lb;
  80. }
  81. static double get_col_ub(LPX *lp, int j)
  82. { /* this routine returns upper bound of column j or +DBL_MAX if
  83. the column has no upper bound */
  84. double ub;
  85. switch (lpx_get_col_type(lp, j))
  86. { case LPX_FR:
  87. case LPX_LO:
  88. ub = +DBL_MAX;
  89. break;
  90. case LPX_UP:
  91. case LPX_DB:
  92. case LPX_FX:
  93. ub = lpx_get_col_ub(lp, j);
  94. break;
  95. default:
  96. xassert(lp != lp);
  97. }
  98. return ub;
  99. }
  100. static int is_binary(LPX *lp, int j)
  101. { /* this routine checks if variable x[j] is binary */
  102. return
  103. lpx_get_col_kind(lp, j) == LPX_IV &&
  104. lpx_get_col_type(lp, j) == LPX_DB &&
  105. lpx_get_col_lb(lp, j) == 0.0 && lpx_get_col_ub(lp, j) == 1.0;
  106. }
  107. static double eval_lf_min(LPX *lp, int len, int ind[], double val[])
  108. { /* this routine computes the minimum of a specified linear form
  109. sum a[j]*x[j]
  110. j
  111. using the formula:
  112. min = sum a[j]*lb[j] + sum a[j]*ub[j],
  113. j in J+ j in J-
  114. where J+ = {j: a[j] > 0}, J- = {j: a[j] < 0}, lb[j] and ub[j]
  115. are lower and upper bound of variable x[j], resp. */
  116. int j, t;
  117. double lb, ub, sum;
  118. sum = 0.0;
  119. for (t = 1; t <= len; t++)
  120. { j = ind[t];
  121. if (val[t] > 0.0)
  122. { lb = get_col_lb(lp, j);
  123. if (lb == -DBL_MAX)
  124. { sum = -DBL_MAX;
  125. break;
  126. }
  127. sum += val[t] * lb;
  128. }
  129. else if (val[t] < 0.0)
  130. { ub = get_col_ub(lp, j);
  131. if (ub == +DBL_MAX)
  132. { sum = -DBL_MAX;
  133. break;
  134. }
  135. sum += val[t] * ub;
  136. }
  137. else
  138. xassert(val != val);
  139. }
  140. return sum;
  141. }
  142. static double eval_lf_max(LPX *lp, int len, int ind[], double val[])
  143. { /* this routine computes the maximum of a specified linear form
  144. sum a[j]*x[j]
  145. j
  146. using the formula:
  147. max = sum a[j]*ub[j] + sum a[j]*lb[j],
  148. j in J+ j in J-
  149. where J+ = {j: a[j] > 0}, J- = {j: a[j] < 0}, lb[j] and ub[j]
  150. are lower and upper bound of variable x[j], resp. */
  151. int j, t;
  152. double lb, ub, sum;
  153. sum = 0.0;
  154. for (t = 1; t <= len; t++)
  155. { j = ind[t];
  156. if (val[t] > 0.0)
  157. { ub = get_col_ub(lp, j);
  158. if (ub == +DBL_MAX)
  159. { sum = +DBL_MAX;
  160. break;
  161. }
  162. sum += val[t] * ub;
  163. }
  164. else if (val[t] < 0.0)
  165. { lb = get_col_lb(lp, j);
  166. if (lb == -DBL_MAX)
  167. { sum = +DBL_MAX;
  168. break;
  169. }
  170. sum += val[t] * lb;
  171. }
  172. else
  173. xassert(val != val);
  174. }
  175. return sum;
  176. }
  177. /*----------------------------------------------------------------------
  178. -- probing - determine logical relation between binary variables.
  179. --
  180. -- This routine tentatively sets a binary variable to 0 and then to 1
  181. -- and examines whether another binary variable is caused to be fixed.
  182. --
  183. -- The examination is based only on one row (constraint), which is the
  184. -- following:
  185. --
  186. -- L <= sum a[j]*x[j] <= U. (1)
  187. -- j
  188. --
  189. -- Let x[p] be a probing variable, x[q] be an examined variable. Then
  190. -- (1) can be written as:
  191. --
  192. -- L <= sum a[j]*x[j] + a[p]*x[p] + a[q]*x[q] <= U, (2)
  193. -- j in J'
  194. --
  195. -- where J' = {j: j != p and j != q}.
  196. --
  197. -- Let
  198. --
  199. -- L' = L - a[p]*x[p], (3)
  200. --
  201. -- U' = U - a[p]*x[p], (4)
  202. --
  203. -- where x[p] is assumed to be fixed at 0 or 1. So (2) can be rewritten
  204. -- as follows:
  205. --
  206. -- L' <= sum a[j]*x[j] + a[q]*x[q] <= U', (5)
  207. -- j in J'
  208. --
  209. -- from where we have:
  210. --
  211. -- L' - sum a[j]*x[j] <= a[q]*x[q] <= U' - sum a[j]*x[j]. (6)
  212. -- j in J' j in J'
  213. --
  214. -- Thus,
  215. --
  216. -- min a[q]*x[q] = L' - MAX, (7)
  217. --
  218. -- max a[q]*x[q] = U' - MIN, (8)
  219. --
  220. -- where
  221. --
  222. -- MIN = min sum a[j]*x[j], (9)
  223. -- j in J'
  224. --
  225. -- MAX = max sum a[j]*x[j]. (10)
  226. -- j in J'
  227. --
  228. -- Formulae (7) and (8) allows determining implied lower and upper
  229. -- bounds of x[q].
  230. --
  231. -- Parameters len, val, L and U specify the constraint (1).
  232. --
  233. -- Parameters lf_min and lf_max specify implied lower and upper bounds
  234. -- of the linear form (1). It is assumed that these bounds are computed
  235. -- with the routines eval_lf_min and eval_lf_max (see above).
  236. --
  237. -- Parameter p specifies the probing variable x[p], which is set to 0
  238. -- (if set is 0) or to 1 (if set is 1).
  239. --
  240. -- Parameter q specifies the examined variable x[q].
  241. --
  242. -- On exit the routine returns one of the following codes:
  243. --
  244. -- 0 - there is no logical relation between x[p] and x[q];
  245. -- 1 - x[q] can take only on value 0;
  246. -- 2 - x[q] can take only on value 1. */
  247. static int probing(int len, double val[], double L, double U,
  248. double lf_min, double lf_max, int p, int set, int q)
  249. { double temp;
  250. xassert(1 <= p && p < q && q <= len);
  251. /* compute L' (3) */
  252. if (L != -DBL_MAX && set) L -= val[p];
  253. /* compute U' (4) */
  254. if (U != +DBL_MAX && set) U -= val[p];
  255. /* compute MIN (9) */
  256. if (lf_min != -DBL_MAX)
  257. { if (val[p] < 0.0) lf_min -= val[p];
  258. if (val[q] < 0.0) lf_min -= val[q];
  259. }
  260. /* compute MAX (10) */
  261. if (lf_max != +DBL_MAX)
  262. { if (val[p] > 0.0) lf_max -= val[p];
  263. if (val[q] > 0.0) lf_max -= val[q];
  264. }
  265. /* compute implied lower bound of x[q]; see (7), (8) */
  266. if (val[q] > 0.0)
  267. { if (L == -DBL_MAX || lf_max == +DBL_MAX)
  268. temp = -DBL_MAX;
  269. else
  270. temp = (L - lf_max) / val[q];
  271. }
  272. else
  273. { if (U == +DBL_MAX || lf_min == -DBL_MAX)
  274. temp = -DBL_MAX;
  275. else
  276. temp = (U - lf_min) / val[q];
  277. }
  278. if (temp > 0.001) return 2;
  279. /* compute implied upper bound of x[q]; see (7), (8) */
  280. if (val[q] > 0.0)
  281. { if (U == +DBL_MAX || lf_min == -DBL_MAX)
  282. temp = +DBL_MAX;
  283. else
  284. temp = (U - lf_min) / val[q];
  285. }
  286. else
  287. { if (L == -DBL_MAX || lf_max == +DBL_MAX)
  288. temp = +DBL_MAX;
  289. else
  290. temp = (L - lf_max) / val[q];
  291. }
  292. if (temp < 0.999) return 1;
  293. /* there is no logical relation between x[p] and x[q] */
  294. return 0;
  295. }
  296. struct COG
  297. { /* conflict graph; it represents logical relations between binary
  298. variables and has a vertex for each binary variable and its
  299. complement, and an edge between two vertices when at most one
  300. of the variables represented by the vertices can equal one in
  301. an optimal solution */
  302. int n;
  303. /* number of variables */
  304. int nb;
  305. /* number of binary variables represented in the graph (note that
  306. not all binary variables can be represented); vertices which
  307. correspond to binary variables have numbers 1, ..., nb while
  308. vertices which correspond to complements of binary variables
  309. have numbers nb+1, ..., nb+nb */
  310. int ne;
  311. /* number of edges in the graph */
  312. int *vert; /* int vert[1+n]; */
  313. /* if x[j] is a binary variable represented in the graph, vert[j]
  314. is the vertex number corresponding to x[j]; otherwise vert[j]
  315. is zero */
  316. int *orig; /* int list[1:nb]; */
  317. /* if vert[j] = k > 0, then orig[k] = j */
  318. unsigned char *a;
  319. /* adjacency matrix of the graph having 2*nb rows and columns;
  320. only strict lower triangle is stored in dense packed form */
  321. };
  322. /*----------------------------------------------------------------------
  323. -- lpx_create_cog - create the conflict graph.
  324. --
  325. -- SYNOPSIS
  326. --
  327. -- #include "glplpx.h"
  328. -- void *lpx_create_cog(LPX *lp);
  329. --
  330. -- DESCRIPTION
  331. --
  332. -- The routine lpx_create_cog creates the conflict graph for a given
  333. -- problem instance.
  334. --
  335. -- RETURNS
  336. --
  337. -- If the graph has been created, the routine returns a pointer to it.
  338. -- Otherwise the routine returns NULL. */
  339. #define MAX_NB 4000
  340. #define MAX_ROW_LEN 500
  341. static void lpx_add_cog_edge(void *_cog, int i, int j);
  342. static void *lpx_create_cog(LPX *lp)
  343. { struct COG *cog = NULL;
  344. int m, n, nb, i, j, p, q, len, *ind, *vert, *orig;
  345. double L, U, lf_min, lf_max, *val;
  346. xprintf("Creating the conflict graph...\n");
  347. m = lpx_get_num_rows(lp);
  348. n = lpx_get_num_cols(lp);
  349. /* determine which binary variables should be included in the
  350. conflict graph */
  351. nb = 0;
  352. vert = xcalloc(1+n, sizeof(int));
  353. for (j = 1; j <= n; j++) vert[j] = 0;
  354. orig = xcalloc(1+n, sizeof(int));
  355. ind = xcalloc(1+n, sizeof(int));
  356. val = xcalloc(1+n, sizeof(double));
  357. for (i = 1; i <= m; i++)
  358. { L = get_row_lb(lp, i);
  359. U = get_row_ub(lp, i);
  360. if (L == -DBL_MAX && U == +DBL_MAX) continue;
  361. len = lpx_get_mat_row(lp, i, ind, val);
  362. if (len > MAX_ROW_LEN) continue;
  363. lf_min = eval_lf_min(lp, len, ind, val);
  364. lf_max = eval_lf_max(lp, len, ind, val);
  365. for (p = 1; p <= len; p++)
  366. { if (!is_binary(lp, ind[p])) continue;
  367. for (q = p+1; q <= len; q++)
  368. { if (!is_binary(lp, ind[q])) continue;
  369. if (probing(len, val, L, U, lf_min, lf_max, p, 0, q) ||
  370. probing(len, val, L, U, lf_min, lf_max, p, 1, q))
  371. { /* there is a logical relation */
  372. /* include the first variable in the graph */
  373. j = ind[p];
  374. if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j;
  375. /* incude the second variable in the graph */
  376. j = ind[q];
  377. if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j;
  378. }
  379. }
  380. }
  381. }
  382. /* if the graph is either empty or has too many vertices, do not
  383. create it */
  384. if (nb == 0 || nb > MAX_NB)
  385. { xprintf("The conflict graph is either empty or too big\n");
  386. xfree(vert);
  387. xfree(orig);
  388. goto done;
  389. }
  390. /* create the conflict graph */
  391. cog = xmalloc(sizeof(struct COG));
  392. cog->n = n;
  393. cog->nb = nb;
  394. cog->ne = 0;
  395. cog->vert = vert;
  396. cog->orig = orig;
  397. len = nb + nb; /* number of vertices */
  398. len = (len * (len - 1)) / 2; /* number of entries in triangle */
  399. len = (len + (CHAR_BIT - 1)) / CHAR_BIT; /* bytes needed */
  400. cog->a = xmalloc(len);
  401. memset(cog->a, 0, len);
  402. for (j = 1; j <= nb; j++)
  403. { /* add edge between variable and its complement */
  404. lpx_add_cog_edge(cog, +orig[j], -orig[j]);
  405. }
  406. for (i = 1; i <= m; i++)
  407. { L = get_row_lb(lp, i);
  408. U = get_row_ub(lp, i);
  409. if (L == -DBL_MAX && U == +DBL_MAX) continue;
  410. len = lpx_get_mat_row(lp, i, ind, val);
  411. if (len > MAX_ROW_LEN) continue;
  412. lf_min = eval_lf_min(lp, len, ind, val);
  413. lf_max = eval_lf_max(lp, len, ind, val);
  414. for (p = 1; p <= len; p++)
  415. { if (!is_binary(lp, ind[p])) continue;
  416. for (q = p+1; q <= len; q++)
  417. { if (!is_binary(lp, ind[q])) continue;
  418. /* set x[p] to 0 and examine x[q] */
  419. switch (probing(len, val, L, U, lf_min, lf_max, p, 0, q))
  420. { case 0:
  421. /* no logical relation */
  422. break;
  423. case 1:
  424. /* x[p] = 0 implies x[q] = 0 */
  425. lpx_add_cog_edge(cog, -ind[p], +ind[q]);
  426. break;
  427. case 2:
  428. /* x[p] = 0 implies x[q] = 1 */
  429. lpx_add_cog_edge(cog, -ind[p], -ind[q]);
  430. break;
  431. default:
  432. xassert(lp != lp);
  433. }
  434. /* set x[p] to 1 and examine x[q] */
  435. switch (probing(len, val, L, U, lf_min, lf_max, p, 1, q))
  436. { case 0:
  437. /* no logical relation */
  438. break;
  439. case 1:
  440. /* x[p] = 1 implies x[q] = 0 */
  441. lpx_add_cog_edge(cog, +ind[p], +ind[q]);
  442. break;
  443. case 2:
  444. /* x[p] = 1 implies x[q] = 1 */
  445. lpx_add_cog_edge(cog, +ind[p], -ind[q]);
  446. break;
  447. default:
  448. xassert(lp != lp);
  449. }
  450. }
  451. }
  452. }
  453. xprintf("The conflict graph has 2*%d vertices and %d edges\n",
  454. cog->nb, cog->ne);
  455. done: xfree(ind);
  456. xfree(val);
  457. return cog;
  458. }
  459. /*----------------------------------------------------------------------
  460. -- lpx_add_cog_edge - add edge to the conflict graph.
  461. --
  462. -- SYNOPSIS
  463. --
  464. -- #include "glplpx.h"
  465. -- void lpx_add_cog_edge(void *cog, int i, int j);
  466. --
  467. -- DESCRIPTION
  468. --
  469. -- The routine lpx_add_cog_edge adds an edge to the conflict graph.
  470. -- The edge connects x[i] (if i > 0) or its complement (if i < 0) and
  471. -- x[j] (if j > 0) or its complement (if j < 0), where i and j are
  472. -- original ordinal numbers of corresponding variables. */
  473. static void lpx_add_cog_edge(void *_cog, int i, int j)
  474. { struct COG *cog = _cog;
  475. int k;
  476. xassert(i != j);
  477. /* determine indices of corresponding vertices */
  478. if (i > 0)
  479. { xassert(1 <= i && i <= cog->n);
  480. i = cog->vert[i];
  481. xassert(i != 0);
  482. }
  483. else
  484. { i = -i;
  485. xassert(1 <= i && i <= cog->n);
  486. i = cog->vert[i];
  487. xassert(i != 0);
  488. i += cog->nb;
  489. }
  490. if (j > 0)
  491. { xassert(1 <= j && j <= cog->n);
  492. j = cog->vert[j];
  493. xassert(j != 0);
  494. }
  495. else
  496. { j = -j;
  497. xassert(1 <= j && j <= cog->n);
  498. j = cog->vert[j];
  499. xassert(j != 0);
  500. j += cog->nb;
  501. }
  502. /* only lower triangle is stored, so we need i > j */
  503. if (i < j) k = i, i = j, j = k;
  504. k = ((i - 1) * (i - 2)) / 2 + (j - 1);
  505. cog->a[k / CHAR_BIT] |=
  506. (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT));
  507. cog->ne++;
  508. return;
  509. }
  510. /*----------------------------------------------------------------------
  511. -- MAXIMUM WEIGHT CLIQUE
  512. --
  513. -- Two subroutines sub() and wclique() below are intended to find a
  514. -- maximum weight clique in a given undirected graph. These subroutines
  515. -- are slightly modified version of the program WCLIQUE developed by
  516. -- Patric Ostergard <http://www.tcs.hut.fi/~pat/wclique.html> and based
  517. -- on ideas from the article "P. R. J. Ostergard, A new algorithm for
  518. -- the maximum-weight clique problem, submitted for publication", which
  519. -- in turn is a generalization of the algorithm for unweighted graphs
  520. -- presented in "P. R. J. Ostergard, A fast algorithm for the maximum
  521. -- clique problem, submitted for publication".
  522. --
  523. -- USED WITH PERMISSION OF THE AUTHOR OF THE ORIGINAL CODE. */
  524. struct dsa
  525. { /* dynamic storage area */
  526. int n;
  527. /* number of vertices */
  528. int *wt; /* int wt[0:n-1]; */
  529. /* weights */
  530. unsigned char *a;
  531. /* adjacency matrix (packed lower triangle without main diag.) */
  532. int record;
  533. /* weight of best clique */
  534. int rec_level;
  535. /* number of vertices in best clique */
  536. int *rec; /* int rec[0:n-1]; */
  537. /* best clique so far */
  538. int *clique; /* int clique[0:n-1]; */
  539. /* table for pruning */
  540. int *set; /* int set[0:n-1]; */
  541. /* current clique */
  542. };
  543. #define n (dsa->n)
  544. #define wt (dsa->wt)
  545. #define a (dsa->a)
  546. #define record (dsa->record)
  547. #define rec_level (dsa->rec_level)
  548. #define rec (dsa->rec)
  549. #define clique (dsa->clique)
  550. #define set (dsa->set)
  551. #if 0
  552. static int is_edge(struct dsa *dsa, int i, int j)
  553. { /* if there is arc (i,j), the routine returns true; otherwise
  554. false; 0 <= i, j < n */
  555. int k;
  556. xassert(0 <= i && i < n);
  557. xassert(0 <= j && j < n);
  558. if (i == j) return 0;
  559. if (i < j) k = i, i = j, j = k;
  560. k = (i * (i - 1)) / 2 + j;
  561. return a[k / CHAR_BIT] &
  562. (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT));
  563. }
  564. #else
  565. #define is_edge(dsa, i, j) ((i) == (j) ? 0 : \
  566. (i) > (j) ? is_edge1(i, j) : is_edge1(j, i))
  567. #define is_edge1(i, j) is_edge2(((i) * ((i) - 1)) / 2 + (j))
  568. #define is_edge2(k) (a[(k) / CHAR_BIT] & \
  569. (unsigned char)(1 << ((CHAR_BIT - 1) - (k) % CHAR_BIT)))
  570. #endif
  571. static void sub(struct dsa *dsa, int ct, int table[], int level,
  572. int weight, int l_weight)
  573. { int i, j, k, curr_weight, left_weight, *p1, *p2, *newtable;
  574. newtable = xcalloc(n, sizeof(int));
  575. if (ct <= 0)
  576. { /* 0 or 1 elements left; include these */
  577. if (ct == 0)
  578. { set[level++] = table[0];
  579. weight += l_weight;
  580. }
  581. if (weight > record)
  582. { record = weight;
  583. rec_level = level;
  584. for (i = 0; i < level; i++) rec[i] = set[i];
  585. }
  586. goto done;
  587. }
  588. for (i = ct; i >= 0; i--)
  589. { if ((level == 0) && (i < ct)) goto done;
  590. k = table[i];
  591. if ((level > 0) && (clique[k] <= (record - weight)))
  592. goto done; /* prune */
  593. set[level] = k;
  594. curr_weight = weight + wt[k];
  595. l_weight -= wt[k];
  596. if (l_weight <= (record - curr_weight))
  597. goto done; /* prune */
  598. p1 = newtable;
  599. p2 = table;
  600. left_weight = 0;
  601. while (p2 < table + i)
  602. { j = *p2++;
  603. if (is_edge(dsa, j, k))
  604. { *p1++ = j;
  605. left_weight += wt[j];
  606. }
  607. }
  608. if (left_weight <= (record - curr_weight)) continue;
  609. sub(dsa, p1 - newtable - 1, newtable, level + 1, curr_weight,
  610. left_weight);
  611. }
  612. done: xfree(newtable);
  613. return;
  614. }
  615. static int wclique(int _n, int w[], unsigned char _a[], int sol[])
  616. { struct dsa _dsa, *dsa = &_dsa;
  617. int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos;
  618. glp_long timer;
  619. n = _n;
  620. wt = &w[1];
  621. a = _a;
  622. record = 0;
  623. rec_level = 0;
  624. rec = &sol[1];
  625. clique = xcalloc(n, sizeof(int));
  626. set = xcalloc(n, sizeof(int));
  627. used = xcalloc(n, sizeof(int));
  628. nwt = xcalloc(n, sizeof(int));
  629. pos = xcalloc(n, sizeof(int));
  630. /* start timer */
  631. timer = xtime();
  632. /* order vertices */
  633. for (i = 0; i < n; i++)
  634. { nwt[i] = 0;
  635. for (j = 0; j < n; j++)
  636. if (is_edge(dsa, i, j)) nwt[i] += wt[j];
  637. }
  638. for (i = 0; i < n; i++)
  639. used[i] = 0;
  640. for (i = n-1; i >= 0; i--)
  641. { max_wt = -1;
  642. max_nwt = -1;
  643. for (j = 0; j < n; j++)
  644. { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt
  645. && nwt[j] > max_nwt)))
  646. { max_wt = wt[j];
  647. max_nwt = nwt[j];
  648. p = j;
  649. }
  650. }
  651. pos[i] = p;
  652. used[p] = 1;
  653. for (j = 0; j < n; j++)
  654. if ((!used[j]) && (j != p) && (is_edge(dsa, p, j)))
  655. nwt[j] -= wt[p];
  656. }
  657. /* main routine */
  658. wth = 0;
  659. for (i = 0; i < n; i++)
  660. { wth += wt[pos[i]];
  661. sub(dsa, i, pos, 0, 0, wth);
  662. clique[pos[i]] = record;
  663. #if 0
  664. if (utime() >= timer + 5.0)
  665. #else
  666. if (xdifftime(xtime(), timer) >= 5.0 - 0.001)
  667. #endif
  668. { /* print current record and reset timer */
  669. xprintf("level = %d (%d); best = %d\n", i+1, n, record);
  670. #if 0
  671. timer = utime();
  672. #else
  673. timer = xtime();
  674. #endif
  675. }
  676. }
  677. xfree(clique);
  678. xfree(set);
  679. xfree(used);
  680. xfree(nwt);
  681. xfree(pos);
  682. /* return the solution found */
  683. for (i = 1; i <= rec_level; i++) sol[i]++;
  684. return rec_level;
  685. }
  686. #undef n
  687. #undef wt
  688. #undef a
  689. #undef record
  690. #undef rec_level
  691. #undef rec
  692. #undef clique
  693. #undef set
  694. /*----------------------------------------------------------------------
  695. -- lpx_clique_cut - generate cluque cut.
  696. --
  697. -- SYNOPSIS
  698. --
  699. -- #include "glplpx.h"
  700. -- int lpx_clique_cut(LPX *lp, void *cog, int ind[], double val[]);
  701. --
  702. -- DESCRIPTION
  703. --
  704. -- The routine lpx_clique_cut generates a clique cut using the conflict
  705. -- graph specified by the parameter cog.
  706. --
  707. -- If a violated clique cut has been found, it has the following form:
  708. --
  709. -- sum{j in J} a[j]*x[j] <= b.
  710. --
  711. -- Variable indices j in J are stored in elements ind[1], ..., ind[len]
  712. -- while corresponding constraint coefficients are stored in elements
  713. -- val[1], ..., val[len], where len is returned on exit. The right-hand
  714. -- side b is stored in element val[0].
  715. --
  716. -- RETURNS
  717. --
  718. -- If the cutting plane has been successfully generated, the routine
  719. -- returns 1 <= len <= n, which is the number of non-zero coefficients
  720. -- in the inequality constraint. Otherwise, the routine returns zero. */
  721. static int lpx_clique_cut(LPX *lp, void *_cog, int ind[], double val[])
  722. { struct COG *cog = _cog;
  723. int n = lpx_get_num_cols(lp);
  724. int j, t, v, card, temp, len = 0, *w, *sol;
  725. double x, sum, b, *vec;
  726. /* allocate working arrays */
  727. w = xcalloc(1 + 2 * cog->nb, sizeof(int));
  728. sol = xcalloc(1 + 2 * cog->nb, sizeof(int));
  729. vec = xcalloc(1+n, sizeof(double));
  730. /* assign weights to vertices of the conflict graph */
  731. for (t = 1; t <= cog->nb; t++)
  732. { j = cog->orig[t];
  733. x = lpx_get_col_prim(lp, j);
  734. temp = (int)(100.0 * x + 0.5);
  735. if (temp < 0) temp = 0;
  736. if (temp > 100) temp = 100;
  737. w[t] = temp;
  738. w[cog->nb + t] = 100 - temp;
  739. }
  740. /* find a clique of maximum weight */
  741. card = wclique(2 * cog->nb, w, cog->a, sol);
  742. /* compute the clique weight for unscaled values */
  743. sum = 0.0;
  744. for ( t = 1; t <= card; t++)
  745. { v = sol[t];
  746. xassert(1 <= v && v <= 2 * cog->nb);
  747. if (v <= cog->nb)
  748. { /* vertex v corresponds to binary variable x[j] */
  749. j = cog->orig[v];
  750. x = lpx_get_col_prim(lp, j);
  751. sum += x;
  752. }
  753. else
  754. { /* vertex v corresponds to the complement of x[j] */
  755. j = cog->orig[v - cog->nb];
  756. x = lpx_get_col_prim(lp, j);
  757. sum += 1.0 - x;
  758. }
  759. }
  760. /* if the sum of binary variables and their complements in the
  761. clique greater than 1, the clique cut is violated */
  762. if (sum >= 1.01)
  763. { /* construct the inquality */
  764. for (j = 1; j <= n; j++) vec[j] = 0;
  765. b = 1.0;
  766. for (t = 1; t <= card; t++)
  767. { v = sol[t];
  768. if (v <= cog->nb)
  769. { /* vertex v corresponds to binary variable x[j] */
  770. j = cog->orig[v];
  771. xassert(1 <= j && j <= n);
  772. vec[j] += 1.0;
  773. }
  774. else
  775. { /* vertex v corresponds to the complement of x[j] */
  776. j = cog->orig[v - cog->nb];
  777. xassert(1 <= j && j <= n);
  778. vec[j] -= 1.0;
  779. b -= 1.0;
  780. }
  781. }
  782. xassert(len == 0);
  783. for (j = 1; j <= n; j++)
  784. { if (vec[j] != 0.0)
  785. { len++;
  786. ind[len] = j, val[len] = vec[j];
  787. }
  788. }
  789. ind[0] = 0, val[0] = b;
  790. }
  791. /* free working arrays */
  792. xfree(w);
  793. xfree(sol);
  794. xfree(vec);
  795. /* return to the calling program */
  796. return len;
  797. }
  798. /*----------------------------------------------------------------------
  799. -- lpx_delete_cog - delete the conflict graph.
  800. --
  801. -- SYNOPSIS
  802. --
  803. -- #include "glplpx.h"
  804. -- void lpx_delete_cog(void *cog);
  805. --
  806. -- DESCRIPTION
  807. --
  808. -- The routine lpx_delete_cog deletes the conflict graph, which the
  809. -- parameter cog points to, freeing all the memory allocated to this
  810. -- object. */
  811. static void lpx_delete_cog(void *_cog)
  812. { struct COG *cog = _cog;
  813. xfree(cog->vert);
  814. xfree(cog->orig);
  815. xfree(cog->a);
  816. xfree(cog);
  817. }
  818. /**********************************************************************/
  819. void *ios_clq_init(glp_tree *tree)
  820. { /* initialize clique cut generator */
  821. glp_prob *mip = tree->mip;
  822. xassert(mip != NULL);
  823. return lpx_create_cog(mip);
  824. }
  825. /***********************************************************************
  826. * NAME
  827. *
  828. * ios_clq_gen - generate clique cuts
  829. *
  830. * SYNOPSIS
  831. *
  832. * #include "glpios.h"
  833. * void ios_clq_gen(glp_tree *tree, void *gen);
  834. *
  835. * DESCRIPTION
  836. *
  837. * The routine ios_clq_gen generates clique cuts for the current point
  838. * and adds them to the clique pool. */
  839. void ios_clq_gen(glp_tree *tree, void *gen)
  840. { int n = lpx_get_num_cols(tree->mip);
  841. int len, *ind;
  842. double *val;
  843. xassert(gen != NULL);
  844. ind = xcalloc(1+n, sizeof(int));
  845. val = xcalloc(1+n, sizeof(double));
  846. len = lpx_clique_cut(tree->mip, gen, ind, val);
  847. if (len > 0)
  848. { /* xprintf("len = %d\n", len); */
  849. glp_ios_add_row(tree, NULL, GLP_RF_CLQ, 0, len, ind, val,
  850. GLP_UP, val[0]);
  851. }
  852. xfree(ind);
  853. xfree(val);
  854. return;
  855. }
  856. /**********************************************************************/
  857. void ios_clq_term(void *gen)
  858. { /* terminate clique cut generator */
  859. xassert(gen != NULL);
  860. lpx_delete_cog(gen);
  861. return;
  862. }
  863. /* eof */