glpnet04.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* glpnet04.c (grid-like network problem generator) */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * This code is a modified version of the program GRIDGEN, a grid-like
  6. * network problem generator developed by Yusin Lee and Jim Orlin.
  7. * The original code is publically available on the DIMACS ftp site at:
  8. * <ftp://dimacs.rutgers.edu/pub/netflow/generators/network/gridgen>.
  9. *
  10. * All changes concern only the program interface, so this modified
  11. * version produces exactly the same instances as the original version.
  12. *
  13. * Changes were made by Andrew Makhorin <mao@gnu.org>.
  14. *
  15. * GLPK is free software: you can redistribute it and/or modify it
  16. * under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation, either version 3 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  21. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  22. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  23. * License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  27. ***********************************************************************/
  28. #include "glpapi.h"
  29. /***********************************************************************
  30. * NAME
  31. *
  32. * glp_gridgen - grid-like network problem generator
  33. *
  34. * SYNOPSIS
  35. *
  36. * int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost,
  37. * const int parm[1+14]);
  38. *
  39. * DESCRIPTION
  40. *
  41. * The routine glp_gridgen is a grid-like network problem generator
  42. * developed by Yusin Lee and Jim Orlin.
  43. *
  44. * The parameter G specifies the graph object, to which the generated
  45. * problem data have to be stored. Note that on entry the graph object
  46. * is erased with the routine glp_erase_graph.
  47. *
  48. * The parameter v_rhs specifies an offset of the field of type double
  49. * in the vertex data block, to which the routine stores the supply or
  50. * demand value. If v_rhs < 0, the value is not stored.
  51. *
  52. * The parameter a_cap specifies an offset of the field of type double
  53. * in the arc data block, to which the routine stores the arc capacity.
  54. * If a_cap < 0, the capacity is not stored.
  55. *
  56. * The parameter a_cost specifies an offset of the field of type double
  57. * in the arc data block, to which the routine stores the per-unit cost
  58. * if the arc flow. If a_cost < 0, the cost is not stored.
  59. *
  60. * The array parm contains description of the network to be generated:
  61. *
  62. * parm[0] not used
  63. * parm[1] two-ways arcs indicator:
  64. * 1 - if links in both direction should be generated
  65. * 0 - otherwise
  66. * parm[2] random number seed (a positive integer)
  67. * parm[3] number of nodes (the number of nodes generated might be
  68. * slightly different to make the network a grid)
  69. * parm[4] grid width
  70. * parm[5] number of sources
  71. * parm[6] number of sinks
  72. * parm[7] average degree
  73. * parm[8] total flow
  74. * parm[9] distribution of arc costs:
  75. * 1 - uniform
  76. * 2 - exponential
  77. * parm[10] lower bound for arc cost (uniform)
  78. * 100 * lambda (exponential)
  79. * parm[11] upper bound for arc cost (uniform)
  80. * not used (exponential)
  81. * parm[12] distribution of arc capacities:
  82. * 1 - uniform
  83. * 2 - exponential
  84. * parm[13] lower bound for arc capacity (uniform)
  85. * 100 * lambda (exponential)
  86. * parm[14] upper bound for arc capacity (uniform)
  87. * not used (exponential)
  88. *
  89. * RETURNS
  90. *
  91. * If the instance was successfully generated, the routine glp_gridgen
  92. * returns zero; otherwise, if specified parameters are inconsistent,
  93. * the routine returns a non-zero error code.
  94. *
  95. * COMMENTS
  96. *
  97. * This network generator generates a grid-like network plus a super
  98. * node. In additional to the arcs connecting the nodes in the grid,
  99. * there is an arc from each supply node to the super node and from the
  100. * super node to each demand node to guarantee feasiblity. These arcs
  101. * have very high costs and very big capacities.
  102. *
  103. * The idea of this network generator is as follows: First, a grid of
  104. * n1 * n2 is generated. For example, 5 * 3. The nodes are numbered as
  105. * 1 to 15, and the supernode is numbered as n1*n2+1. Then arcs between
  106. * adjacent nodes are generated. For these arcs, the user is allowed to
  107. * specify either to generate two-way arcs or one-way arcs. If two-way
  108. * arcs are to be generated, two arcs, one in each direction, will be
  109. * generated between each adjacent node pairs. Otherwise, only one arc
  110. * will be generated. If this is the case, the arcs will be generated
  111. * in alterntive directions as shown below.
  112. *
  113. * 1 ---> 2 ---> 3 ---> 4 ---> 5
  114. * | ^ | ^ |
  115. * | | | | |
  116. * V | V | V
  117. * 6 <--- 7 <--- 8 <--- 9 <--- 10
  118. * | ^ | ^ |
  119. * | | | | |
  120. * V | V | V
  121. * 11 --->12 --->13 --->14 ---> 15
  122. *
  123. * Then the arcs between the super node and the source/sink nodes are
  124. * added as mentioned before. If the number of arcs still doesn't reach
  125. * the requirement, additional arcs will be added by uniformly picking
  126. * random node pairs. There is no checking to prevent multiple arcs
  127. * between any pair of nodes. However, there will be no self-arcs (arcs
  128. * that poins back to its tail node) in the network.
  129. *
  130. * The source and sink nodes are selected uniformly in the network, and
  131. * the imbalances of each source/sink node are also assigned by uniform
  132. * distribution. */
  133. struct stat_para
  134. { /* structure for statistical distributions */
  135. int distribution;
  136. /* the distribution: */
  137. #define UNIFORM 1 /* uniform distribution */
  138. #define EXPONENTIAL 2 /* exponential distribution */
  139. double parameter[5];
  140. /* the parameters of the distribution */
  141. };
  142. struct arcs
  143. { int from;
  144. /* the FROM node of that arc */
  145. int to;
  146. /* the TO node of that arc */
  147. int cost;
  148. /* original cost of that arc */
  149. int u;
  150. /* capacity of the arc */
  151. };
  152. struct imbalance
  153. { int node;
  154. /* Node ID */
  155. int supply;
  156. /* Supply of that node */
  157. };
  158. struct csa
  159. { /* common storage area */
  160. glp_graph *G;
  161. int v_rhs, a_cap, a_cost;
  162. int seed;
  163. /* random number seed */
  164. int seed_original;
  165. /* the original seed from input */
  166. int two_way;
  167. /* 0: generate arcs in both direction for the basic grid, except
  168. for the arcs to/from the super node. 1: o/w */
  169. int n_node;
  170. /* total number of nodes in the network, numbered 1 to n_node,
  171. including the super node, which is the last one */
  172. int n_arc;
  173. /* total number of arcs in the network, counting EVERY arc. */
  174. int n_grid_arc;
  175. /* number of arcs in the basic grid, including the arcs to/from
  176. the super node */
  177. int n_source, n_sink;
  178. /* number of source and sink nodes */
  179. int avg_degree;
  180. /* average degree, arcs to and from the super node are counted */
  181. int t_supply;
  182. /* total supply in the network */
  183. int n1, n2;
  184. /* the two edges of the network grid. n1 >= n2 */
  185. struct imbalance *source_list, *sink_list;
  186. /* head of the array of source/sink nodes */
  187. struct stat_para arc_costs;
  188. /* the distribution of arc costs */
  189. struct stat_para capacities;
  190. /* distribution of the capacities of the arcs */
  191. struct arcs *arc_list;
  192. /* head of the arc list array. Arcs in this array are in the
  193. order of grid_arcs, arcs to/from super node, and other arcs */
  194. };
  195. #define G (csa->G)
  196. #define v_rhs (csa->v_rhs)
  197. #define a_cap (csa->a_cap)
  198. #define a_cost (csa->a_cost)
  199. #define seed (csa->seed)
  200. #define seed_original (csa->seed_original)
  201. #define two_way (csa->two_way)
  202. #define n_node (csa->n_node)
  203. #define n_arc (csa->n_arc)
  204. #define n_grid_arc (csa->n_grid_arc)
  205. #define n_source (csa->n_source)
  206. #define n_sink (csa->n_sink)
  207. #define avg_degree (csa->avg_degree)
  208. #define t_supply (csa->t_supply)
  209. #define n1 (csa->n1)
  210. #define n2 (csa->n2)
  211. #define source_list (csa->source_list)
  212. #define sink_list (csa->sink_list)
  213. #define arc_costs (csa->arc_costs)
  214. #define capacities (csa->capacities)
  215. #define arc_list (csa->arc_list)
  216. static void assign_capacities(struct csa *csa);
  217. static void assign_costs(struct csa *csa);
  218. static void assign_imbalance(struct csa *csa);
  219. static int exponential(struct csa *csa, double lambda[1]);
  220. static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs
  221. *arc_ptr);
  222. static struct arcs *gen_basic_grid(struct csa *csa, struct arcs
  223. *arc_ptr);
  224. static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr);
  225. static void generate(struct csa *csa);
  226. static void output(struct csa *csa);
  227. static double randy(struct csa *csa);
  228. static void select_source_sinks(struct csa *csa);
  229. static int uniform(struct csa *csa, double a[2]);
  230. int glp_gridgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost,
  231. const int parm[1+14])
  232. { struct csa _csa, *csa = &_csa;
  233. int n, ret;
  234. G = G_;
  235. v_rhs = _v_rhs;
  236. a_cap = _a_cap;
  237. a_cost = _a_cost;
  238. if (G != NULL)
  239. { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double))
  240. xerror("glp_gridgen: v_rhs = %d; invalid offset\n", v_rhs);
  241. if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double))
  242. xerror("glp_gridgen: a_cap = %d; invalid offset\n", a_cap);
  243. if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double))
  244. xerror("glp_gridgen: a_cost = %d; invalid offset\n", a_cost)
  245. ;
  246. }
  247. /* Check the parameters for consistency. */
  248. if (!(parm[1] == 0 || parm[1] == 1))
  249. { ret = 1;
  250. goto done;
  251. }
  252. if (parm[2] < 1)
  253. { ret = 2;
  254. goto done;
  255. }
  256. if (!(10 <= parm[3] && parm[3] <= 40000))
  257. { ret = 3;
  258. goto done;
  259. }
  260. if (!(1 <= parm[4] && parm[4] <= 40000))
  261. { ret = 4;
  262. goto done;
  263. }
  264. if (!(parm[5] >= 0 && parm[6] >= 0 && parm[5] + parm[6] <=
  265. parm[3]))
  266. { ret = 5;
  267. goto done;
  268. }
  269. if (!(1 <= parm[7] && parm[7] <= parm[3]))
  270. { ret = 6;
  271. goto done;
  272. }
  273. if (parm[8] < 0)
  274. { ret = 7;
  275. goto done;
  276. }
  277. if (!(parm[9] == 1 || parm[9] == 2))
  278. { ret = 8;
  279. goto done;
  280. }
  281. if (parm[9] == 1 && parm[10] > parm[11] ||
  282. parm[9] == 2 && parm[10] < 1)
  283. { ret = 9;
  284. goto done;
  285. }
  286. if (!(parm[12] == 1 || parm[12] == 2))
  287. { ret = 10;
  288. goto done;
  289. }
  290. if (parm[12] == 1 && !(0 <= parm[13] && parm[13] <= parm[14]) ||
  291. parm[12] == 2 && parm[13] < 1)
  292. { ret = 11;
  293. goto done;
  294. }
  295. /* Initialize the graph object. */
  296. if (G != NULL)
  297. { glp_erase_graph(G, G->v_size, G->a_size);
  298. glp_set_graph_name(G, "GRIDGEN");
  299. }
  300. /* Copy the generator parameters. */
  301. two_way = parm[1];
  302. seed_original = seed = parm[2];
  303. n_node = parm[3];
  304. n = parm[4];
  305. n_source = parm[5];
  306. n_sink = parm[6];
  307. avg_degree = parm[7];
  308. t_supply = parm[8];
  309. arc_costs.distribution = parm[9];
  310. if (parm[9] == 1)
  311. { arc_costs.parameter[0] = parm[10];
  312. arc_costs.parameter[1] = parm[11];
  313. }
  314. else
  315. { arc_costs.parameter[0] = (double)parm[10] / 100.0;
  316. arc_costs.parameter[1] = 0.0;
  317. }
  318. capacities.distribution = parm[12];
  319. if (parm[12] == 1)
  320. { capacities.parameter[0] = parm[13];
  321. capacities.parameter[1] = parm[14];
  322. }
  323. else
  324. { capacities.parameter[0] = (double)parm[13] / 100.0;
  325. capacities.parameter[1] = 0.0;
  326. }
  327. /* Calculate the edge lengths of the grid according to the
  328. input. */
  329. if (n * n >= n_node)
  330. { n1 = n;
  331. n2 = (int)((double)n_node / (double)n + 0.5);
  332. }
  333. else
  334. { n2 = n;
  335. n1 = (int)((double)n_node / (double)n + 0.5);
  336. }
  337. /* Recalculate the total number of nodes and plus 1 for the super
  338. node. */
  339. n_node = n1 * n2 + 1;
  340. n_arc = n_node * avg_degree;
  341. n_grid_arc = (two_way + 1) * ((n1 - 1) * n2 + (n2 - 1) * n1) +
  342. n_source + n_sink;
  343. if (n_grid_arc > n_arc) n_arc = n_grid_arc;
  344. arc_list = xcalloc(n_arc, sizeof(struct arcs));
  345. source_list = xcalloc(n_source, sizeof(struct imbalance));
  346. sink_list = xcalloc(n_sink, sizeof(struct imbalance));
  347. /* Generate a random network. */
  348. generate(csa);
  349. /* Output the network. */
  350. output(csa);
  351. /* Free all allocated memory. */
  352. xfree(arc_list);
  353. xfree(source_list);
  354. xfree(sink_list);
  355. /* The instance has been successfully generated. */
  356. ret = 0;
  357. done: return ret;
  358. }
  359. #undef random
  360. static void assign_capacities(struct csa *csa)
  361. { /* Assign a capacity to each arc. */
  362. struct arcs *arc_ptr = arc_list;
  363. int (*random)(struct csa *csa, double *);
  364. int i;
  365. /* Determine the random number generator to use. */
  366. switch (arc_costs.distribution)
  367. { case UNIFORM:
  368. random = uniform;
  369. break;
  370. case EXPONENTIAL:
  371. random = exponential;
  372. break;
  373. default:
  374. xassert(csa != csa);
  375. }
  376. /* Assign capacities to grid arcs. */
  377. for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++)
  378. arc_ptr->u = random(csa, capacities.parameter);
  379. i = i - n_source - n_sink;
  380. /* Assign capacities to arcs to/from supernode. */
  381. for (; i < n_grid_arc; i++, arc_ptr++)
  382. arc_ptr->u = t_supply;
  383. /* Assign capacities to all other arcs. */
  384. for (; i < n_arc; i++, arc_ptr++)
  385. arc_ptr->u = random(csa, capacities.parameter);
  386. return;
  387. }
  388. static void assign_costs(struct csa *csa)
  389. { /* Assign a cost to each arc. */
  390. struct arcs *arc_ptr = arc_list;
  391. int (*random)(struct csa *csa, double *);
  392. int i;
  393. /* A high cost assigned to arcs to/from the supernode. */
  394. int high_cost;
  395. /* The maximum cost assigned to arcs in the base grid. */
  396. int max_cost = 0;
  397. /* Determine the random number generator to use. */
  398. switch (arc_costs.distribution)
  399. { case UNIFORM:
  400. random = uniform;
  401. break;
  402. case EXPONENTIAL:
  403. random = exponential;
  404. break;
  405. default:
  406. xassert(csa != csa);
  407. }
  408. /* Assign costs to arcs in the base grid. */
  409. for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++)
  410. { arc_ptr->cost = random(csa, arc_costs.parameter);
  411. if (max_cost < arc_ptr->cost) max_cost = arc_ptr->cost;
  412. }
  413. i = i - n_source - n_sink;
  414. /* Assign costs to arcs to/from the super node. */
  415. high_cost = max_cost * 2;
  416. for (; i < n_grid_arc; i++, arc_ptr++)
  417. arc_ptr->cost = high_cost;
  418. /* Assign costs to all other arcs. */
  419. for (; i < n_arc; i++, arc_ptr++)
  420. arc_ptr->cost = random(csa, arc_costs.parameter);
  421. return;
  422. }
  423. static void assign_imbalance(struct csa *csa)
  424. { /* Assign an imbalance to each node. */
  425. int total, i;
  426. double avg;
  427. struct imbalance *ptr;
  428. /* assign the supply nodes */
  429. avg = 2.0 * t_supply / n_source;
  430. do
  431. { for (i = 1, total = t_supply, ptr = source_list + 1;
  432. i < n_source; i++, ptr++)
  433. { ptr->supply = (int)(randy(csa) * avg + 0.5);
  434. total -= ptr->supply;
  435. }
  436. source_list->supply = total;
  437. }
  438. /* redo all if the assignment "overshooted" */
  439. while (total <= 0);
  440. /* assign the demand nodes */
  441. avg = -2.0 * t_supply / n_sink;
  442. do
  443. { for (i = 1, total = t_supply, ptr = sink_list + 1;
  444. i < n_sink; i++, ptr++)
  445. { ptr->supply = (int)(randy(csa) * avg - 0.5);
  446. total += ptr->supply;
  447. }
  448. sink_list->supply = - total;
  449. }
  450. while (total <= 0);
  451. return;
  452. }
  453. static int exponential(struct csa *csa, double lambda[1])
  454. { /* Returns an "exponentially distributed" integer with parameter
  455. lambda. */
  456. return ((int)(- lambda[0] * log((double)randy(csa)) + 0.5));
  457. }
  458. static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs
  459. *arc_ptr)
  460. { /* Generate an arc from each source to the supernode and from
  461. supernode to each sink. */
  462. int i;
  463. for (i = 0; i < n_source; i++, arc_ptr++)
  464. { arc_ptr->from = source_list[i].node;
  465. arc_ptr->to = n_node;
  466. }
  467. for (i = 0; i < n_sink; i++, arc_ptr++)
  468. { arc_ptr->to = sink_list[i].node;
  469. arc_ptr->from = n_node;
  470. }
  471. return arc_ptr;
  472. }
  473. static struct arcs *gen_basic_grid(struct csa *csa, struct arcs
  474. *arc_ptr)
  475. { /* Generate the basic grid. */
  476. int direction = 1, i, j, k;
  477. if (two_way)
  478. { /* Generate an arc in each direction. */
  479. for (i = 1; i < n_node; i += n1)
  480. { for (j = i, k = j + n1 - 1; j < k; j++)
  481. { arc_ptr->from = j;
  482. arc_ptr->to = j + 1;
  483. arc_ptr++;
  484. arc_ptr->from = j + 1;
  485. arc_ptr->to = j;
  486. arc_ptr++;
  487. }
  488. }
  489. for (i = 1; i <= n1; i++)
  490. { for (j = i + n1; j < n_node; j += n1)
  491. { arc_ptr->from = j;
  492. arc_ptr->to = j - n1;
  493. arc_ptr++;
  494. arc_ptr->from = j - n1;
  495. arc_ptr->to = j;
  496. arc_ptr++;
  497. }
  498. }
  499. }
  500. else
  501. { /* Generate one arc in each direction. */
  502. for (i = 1; i < n_node; i += n1)
  503. { if (direction == 1)
  504. j = i;
  505. else
  506. j = i + 1;
  507. for (k = j + n1 - 1; j < k; j++)
  508. { arc_ptr->from = j;
  509. arc_ptr->to = j + direction;
  510. arc_ptr++;
  511. }
  512. direction = - direction;
  513. }
  514. for (i = 1; i <= n1; i++)
  515. { j = i + n1;
  516. if (direction == 1)
  517. { for (; j < n_node; j += n1)
  518. { arc_ptr->from = j - n1;
  519. arc_ptr->to = j;
  520. arc_ptr++;
  521. }
  522. }
  523. else
  524. { for (; j < n_node; j += n1)
  525. { arc_ptr->from = j - n1;
  526. arc_ptr->to = j;
  527. arc_ptr++;
  528. }
  529. }
  530. direction = - direction;
  531. }
  532. }
  533. return arc_ptr;
  534. }
  535. static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr)
  536. { /* Generate random arcs to meet the specified density. */
  537. int i;
  538. double ab[2];
  539. ab[0] = 0.9;
  540. ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the
  541. supernode cannot be selected */
  542. for (i = n_grid_arc; i < n_arc; i++, arc_ptr++)
  543. { arc_ptr->from = uniform(csa, ab);
  544. arc_ptr->to = uniform(csa, ab);
  545. if (arc_ptr->from == arc_ptr->to)
  546. { arc_ptr--;
  547. i--;
  548. }
  549. }
  550. return;
  551. }
  552. static void generate(struct csa *csa)
  553. { /* Generate a random network. */
  554. struct arcs *arc_ptr = arc_list;
  555. arc_ptr = gen_basic_grid(csa, arc_ptr);
  556. select_source_sinks(csa);
  557. arc_ptr = gen_additional_arcs(csa, arc_ptr);
  558. gen_more_arcs(csa, arc_ptr);
  559. assign_costs(csa);
  560. assign_capacities(csa);
  561. assign_imbalance(csa);
  562. return;
  563. }
  564. static void output(struct csa *csa)
  565. { /* Output the network in DIMACS format. */
  566. struct arcs *arc_ptr;
  567. struct imbalance *imb_ptr;
  568. int i;
  569. if (G != NULL) goto skip;
  570. /* Output "c", "p" records. */
  571. xprintf("c generated by GRIDGEN\n");
  572. xprintf("c seed %d\n", seed_original);
  573. xprintf("c nodes %d\n", n_node);
  574. xprintf("c grid size %d X %d\n", n1, n2);
  575. xprintf("c sources %d sinks %d\n", n_source, n_sink);
  576. xprintf("c avg. degree %d\n", avg_degree);
  577. xprintf("c supply %d\n", t_supply);
  578. switch (arc_costs.distribution)
  579. { case UNIFORM:
  580. xprintf("c arc costs: UNIFORM distr. min %d max %d\n",
  581. (int)arc_costs.parameter[0],
  582. (int)arc_costs.parameter[1]);
  583. break;
  584. case EXPONENTIAL:
  585. xprintf("c arc costs: EXPONENTIAL distr. lambda %d\n",
  586. (int)arc_costs.parameter[0]);
  587. break;
  588. default:
  589. xassert(csa != csa);
  590. }
  591. switch (capacities.distribution)
  592. { case UNIFORM:
  593. xprintf("c arc caps : UNIFORM distr. min %d max %d\n",
  594. (int)capacities.parameter[0],
  595. (int)capacities.parameter[1]);
  596. break;
  597. case EXPONENTIAL:
  598. xprintf("c arc caps : EXPONENTIAL distr. %d lambda %d\n",
  599. (int)capacities.parameter[0]);
  600. break;
  601. default:
  602. xassert(csa != csa);
  603. }
  604. skip: if (G == NULL)
  605. xprintf("p min %d %d\n", n_node, n_arc);
  606. else
  607. { glp_add_vertices(G, n_node);
  608. if (v_rhs >= 0)
  609. { double zero = 0.0;
  610. for (i = 1; i <= n_node; i++)
  611. { glp_vertex *v = G->v[i];
  612. memcpy((char *)v->data + v_rhs, &zero, sizeof(double));
  613. }
  614. }
  615. }
  616. /* Output "n node supply". */
  617. for (i = 0, imb_ptr = source_list; i < n_source; i++, imb_ptr++)
  618. { if (G == NULL)
  619. xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply);
  620. else
  621. { if (v_rhs >= 0)
  622. { double temp = (double)imb_ptr->supply;
  623. glp_vertex *v = G->v[imb_ptr->node];
  624. memcpy((char *)v->data + v_rhs, &temp, sizeof(double));
  625. }
  626. }
  627. }
  628. for (i = 0, imb_ptr = sink_list; i < n_sink; i++, imb_ptr++)
  629. { if (G == NULL)
  630. xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply);
  631. else
  632. { if (v_rhs >= 0)
  633. { double temp = (double)imb_ptr->supply;
  634. glp_vertex *v = G->v[imb_ptr->node];
  635. memcpy((char *)v->data + v_rhs, &temp, sizeof(double));
  636. }
  637. }
  638. }
  639. /* Output "a from to lowcap=0 hicap cost". */
  640. for (i = 0, arc_ptr = arc_list; i < n_arc; i++, arc_ptr++)
  641. { if (G == NULL)
  642. xprintf("a %d %d 0 %d %d\n", arc_ptr->from, arc_ptr->to,
  643. arc_ptr->u, arc_ptr->cost);
  644. else
  645. { glp_arc *a = glp_add_arc(G, arc_ptr->from, arc_ptr->to);
  646. if (a_cap >= 0)
  647. { double temp = (double)arc_ptr->u;
  648. memcpy((char *)a->data + a_cap, &temp, sizeof(double));
  649. }
  650. if (a_cost >= 0)
  651. { double temp = (double)arc_ptr->cost;
  652. memcpy((char *)a->data + a_cost, &temp, sizeof(double));
  653. }
  654. }
  655. }
  656. return;
  657. }
  658. static double randy(struct csa *csa)
  659. { /* Returns a random number between 0.0 and 1.0.
  660. See Ward Cheney & David Kincaid, "Numerical Mathematics and
  661. Computing," 2Ed, pp. 335. */
  662. seed = 16807 * seed % 2147483647;
  663. if (seed < 0) seed = - seed;
  664. return seed * 4.6566128752459e-10;
  665. }
  666. static void select_source_sinks(struct csa *csa)
  667. { /* Randomly select the source nodes and sink nodes. */
  668. int i, *int_ptr;
  669. int *temp_list; /* a temporary list of nodes */
  670. struct imbalance *ptr;
  671. double ab[2]; /* parameter for random number generator */
  672. ab[0] = 0.9;
  673. ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the
  674. supernode cannot be selected */
  675. temp_list = xcalloc(n_node, sizeof(int));
  676. for (i = 0, int_ptr = temp_list; i < n_node; i++, int_ptr++)
  677. *int_ptr = 0;
  678. /* Select the source nodes. */
  679. for (i = 0, ptr = source_list; i < n_source; i++, ptr++)
  680. { ptr->node = uniform(csa, ab);
  681. if (temp_list[ptr->node] == 1) /* check for duplicates */
  682. { ptr--;
  683. i--;
  684. }
  685. else
  686. temp_list[ptr->node] = 1;
  687. }
  688. /* Select the sink nodes. */
  689. for (i = 0, ptr = sink_list; i < n_sink; i++, ptr++)
  690. { ptr->node = uniform(csa, ab);
  691. if (temp_list[ptr->node] == 1)
  692. { ptr--;
  693. i--;
  694. }
  695. else
  696. temp_list[ptr->node] = 1;
  697. }
  698. xfree(temp_list);
  699. return;
  700. }
  701. int uniform(struct csa *csa, double a[2])
  702. { /* Generates an integer uniformly selected from [a[0],a[1]]. */
  703. return (int)((a[1] - a[0]) * randy(csa) + a[0] + 0.5);
  704. }
  705. /**********************************************************************/
  706. #if 0
  707. int main(void)
  708. { int parm[1+14];
  709. double temp;
  710. scanf("%d", &parm[1]);
  711. scanf("%d", &parm[2]);
  712. scanf("%d", &parm[3]);
  713. scanf("%d", &parm[4]);
  714. scanf("%d", &parm[5]);
  715. scanf("%d", &parm[6]);
  716. scanf("%d", &parm[7]);
  717. scanf("%d", &parm[8]);
  718. scanf("%d", &parm[9]);
  719. if (parm[9] == 1)
  720. { scanf("%d", &parm[10]);
  721. scanf("%d", &parm[11]);
  722. }
  723. else
  724. { scanf("%le", &temp);
  725. parm[10] = (int)(100.0 * temp + .5);
  726. parm[11] = 0;
  727. }
  728. scanf("%d", &parm[12]);
  729. if (parm[12] == 1)
  730. { scanf("%d", &parm[13]);
  731. scanf("%d", &parm[14]);
  732. }
  733. else
  734. { scanf("%le", &temp);
  735. parm[13] = (int)(100.0 * temp + .5);
  736. parm[14] = 0;
  737. }
  738. glp_gridgen(NULL, 0, 0, 0, parm);
  739. return 0;
  740. }
  741. #endif
  742. /* eof */