MC_init.cpp
Go to the documentation of this file.
1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 #include <fstream>
4 #include <algorithm>
5 
6 #include "BCP_tm.hpp"
7 
8 #include "MC_init.hpp"
9 #include "MC_cut.hpp"
10 #include "MC_tm.hpp"
11 #include "MC_lp.hpp"
12 
13 //#############################################################################
14 
16 {
17  return new MC_initialize;
18 }
19 
20 //#############################################################################
21 
24 {
25  return new MC_packer;
26 }
27 
28 //-----------------------------------------------------------------------------
29 
30 void
32 {
33  const MC_cycle_cut* mc_cycle_cut = dynamic_cast<const MC_cycle_cut*>(cut);
34  if (mc_cycle_cut) {
35  mc_cycle_cut->pack(buf);
36  return;
37  }
38  const MC_explicit_dense_cut* mc_dense_cut =
39  dynamic_cast<const MC_explicit_dense_cut*>(cut);
40  if (mc_dense_cut) {
41  mc_dense_cut->pack(buf);
42  return;
43  }
44  throw BCP_fatal_error("MC_packer::pack_cut_algo() : unknown cut type!\n");
45 }
46 
47 //-----------------------------------------------------------------------------
48 
51 {
52  MC_cut_t type;
53  buf.unpack(type);
54  BCP_cut_algo* cut;
55  switch (type) {
56  case MC_cut_t__cycle: cut = new MC_cycle_cut(buf); break;
57  case MC_cut_t__explicit_dense: cut = new MC_explicit_dense_cut(buf); break;
58  default: throw BCP_fatal_error("\
59 MC_packer::unpack_cut_algo() : unknown cut type!\n");
60  }
61  return cut;
62 }
63 
64 //#############################################################################
65 
66 void MC_read_parameters(MC_tm& tm, const char * paramfile);
67 void MC_readproblem(MC_tm& tm);
68 
69 //-----------------------------------------------------------------------------
70 
73  const int argnum, const char * const * arglist)
74 {
75  MC_tm* tm = new MC_tm;
76 
77  MC_read_parameters(*tm, arglist[1]);
78  MC_readproblem(*tm);
79 
80  MC_problem &mc = tm->mc;
81  if (mc.ising_problem) {
82  const int grid = static_cast<int>(sqrt(mc.num_nodes + 1.0));
83  const int num_grid_nodes = grid * grid;
84  const bool has_extra_node = (mc.num_nodes != num_grid_nodes);
85  const double granularity = has_extra_node ? .99 : 1.99;
86  p.par.set_entry(BCP_tm_par::Granularity, granularity);
88  }
89 
90  return tm;
91 }
92 
93 //-----------------------------------------------------------------------------
94 
97 {
98  MC_lp* lp = new MC_lp;
99  return lp;
100 }
101 
102 //#############################################################################
103 
104 void MC_read_parameters(MC_tm& tm, const char * paramfile)
105 {
106  tm.tm_par.read_from_file(paramfile);
107  tm.lp_par.read_from_file(paramfile);
108 }
109 
110 //#############################################################################
111 
112 int
113 MC_components(const int n, const int m, const MC_graph_edge* edges,
114  int* component)
115 {
116  // See the MC_kruskal.cpp file.
117  // This is the same algorithm, just here we don't need all those things that
118  // are computed there
119  int * first_on_chain = component;
120  int * last_on_chain = new int[n];
121  int * next_on_chain = new int[n];
122  int * size_of_chain = new int[n];
123 
124  CoinIotaN(first_on_chain, n, 0);
125  CoinIotaN(last_on_chain, n, 0);
126  CoinFillN(next_on_chain, n, -1);
127  CoinFillN(size_of_chain, n, 1);
128 
129  int tree_size = 0;
130 
131  int label_s = -1; // shorter chain head
132  int label_l = -1; // longer chain head
133  for (int k = 0; k < m; ++k) {
134  const int i = edges[k].tail;
135  const int j = edges[k].head;
136  const int label_i = first_on_chain[i];
137  const int label_j = first_on_chain[j];
138  if (label_i == label_j)
139  continue;
140  if (size_of_chain[label_i] > size_of_chain[label_j]) {
141  label_s = label_j;
142  label_l = label_i;
143  } else {
144  label_s = label_i;
145  label_l = label_j;
146  }
147  ++tree_size;
148  for (int l = label_s; l != -1; l = next_on_chain[l]) {
149  first_on_chain[l] = label_l;
150  }
151  next_on_chain[last_on_chain[label_l]] = label_s;
152  last_on_chain[label_l] = last_on_chain[label_s];
153  size_of_chain[label_l] += size_of_chain[label_s];
154  }
155 
156  delete[] last_on_chain;
157  delete[] next_on_chain;
158  delete[] size_of_chain;
159 
160  return tree_size;
161 }
162 
163 //#############################################################################
164 
165 static void
167  const int num_nodes, const int * nodes)
168 {
169  const int * nodes_end = nodes + num_nodes;
170  // count the edges going to real neighbors
171  int outedges = 0;
172  int i, j;
173  for (i = 0; i < num_nodes; ++i) {
174  MC_adjacency_entry* adj_list = mc.nodes[nodes[i]].adj_list;
175  for (j = mc.nodes[nodes[i]].degree - 1; j >= 0; --j) {
176  if (std::find(nodes, nodes_end, adj_list[j].neighbor) == nodes_end)
177  ++outedges;
178  }
179  }
180  swstruct.num_nodes = num_nodes;
181  swstruct.num_neighbors = outedges;
182  swstruct.nodes = new int[num_nodes + outedges];
183  swstruct.neighbors = swstruct.nodes + num_nodes;
184  CoinDisjointCopyN(nodes, num_nodes, swstruct.nodes);
185  outedges = 0;
186  for (i = 0; i < num_nodes; ++i) {
187  MC_adjacency_entry* adj_list = mc.nodes[nodes[i]].adj_list;
188  for (j = mc.nodes[nodes[i]].degree - 1; j >= 0; --j) {
189  if (std::find(nodes, nodes_end, adj_list[j].neighbor) == nodes_end)
190  swstruct.neighbors[outedges++] = adj_list[j].index;
191  }
192  }
193 }
194 
195 //#############################################################################
196 
197 typedef std::pair<int,int> intpair;
198 
199 static inline bool
200 operator<(const intpair& ip0, const intpair& ip1)
201 {
202  return ((ip0.first < ip1.first) ||
203  ((ip0.first == ip1.first) && (ip0.second < ip1.second)));
204 }
205 
207 {
208  int i, j, k;
209  MC_problem &mc = tm.mc;
210 
211  std::ifstream file(tm.tm_par.entry(MC_tm_par::InputFile).c_str());
212  if (! file) {
213  throw BCP_fatal_error("Can't open input file!\n");
214  }
215 
216  char line[1000];
217 
218  double rescale = 1;
219  for (int lose = tm.tm_par.entry(MC_tm_par::DigitsToLose); lose > 0; --lose) {
220  rescale *= 10.0;
221  }
222 
223  file.getline(line, 999);
224  int len = strlen(line);
225  if (strncmp(line, "DESC: ggrid", CoinMin(len, 11)) == 0) {
226  // Ising problem generated by ggrid. Parse the info.
227  mc.ising_problem = true;
228  printf("Ising problem detected.\n");
229  file.getline(line, 999);
230  sscanf(line, "DESC: scaling: %lf", &mc.scaling_factor);
231  mc.scaling_factor /= rescale;
232  }
233  while (strncmp(line, "DESC:", CoinMin(len, 5)) == 0) {
234  file.getline(line, 999);
235  }
236 
237  sscanf(line, "%i%i", &mc.num_nodes, &mc.num_edges);
238 
239  const int n = mc.num_nodes;
240  const int m = mc.num_edges;
241  // this will be definitely enough, even for new edges to connect
242  // disconnected components.
243  mc.edges = new MC_graph_edge[m + n];
244 
245  std::map<intpair, int> edge_map;
246 
247  double cost;
248  intpair ip;
249  for (i = 0, k = 0; i < m; ++i) {
250  file.getline(line, 999);
251  sscanf(line, "%i%i%lf", &ip.first, &ip.second, &cost);
252  if (ip.first < 0 || ip.first >= n || ip.second < 0 || ip.second >= n ||
253  (ip.first == ip.second)) {
254  char errmsg[200];
255  sprintf(errmsg, " bad endnodes %i %i\n", ip.first, ip.second);
256  throw BCP_fatal_error(errmsg);
257  }
258  if (ip.first > ip.second)
259  std::swap(ip.first, ip.second);
260  const std::map<intpair, int>::const_iterator em = edge_map.find(ip);
261  if (em != edge_map.end()) {
262  printf("Warning: edge (%i,%i) appears once again.\n",
263  ip.first, ip.second);
264  printf(" Collapsing the parallel edges.\n");
265  mc.edges[em->second].cost += cost;
266  } else {
267  edge_map[ip] = k;
268  mc.edges[k].tail = ip.first;
269  mc.edges[k].head = ip.second;
270  mc.edges[k++].cost = cost;
271  }
272  }
273  mc.num_edges = k;
274 
275  file.close();
276 
277  // throw out the 0 cost edges if it's not an ising problem. For ising
278  // problems it's worth to keep the 0 cost edges because then the structure
279  // is preserved.
280  if (! mc.ising_problem) {
281  for (i = 0, k = 0; i < mc.num_edges; ++i) {
282  if (mc.edges[i].cost == 0.0) {
283  printf("Warning: Discarded edge (%i,%i) as it has final cost 0.\n",
284  mc.edges[i].tail, mc.edges[i].head);
285  } else {
286  mc.edges[k].tail = mc.edges[i].tail;
287  mc.edges[k].head = mc.edges[i].head;
288  mc.edges[k++].cost = mc.edges[i].cost;
289  }
290  }
291  mc.num_edges = k;
292 
293  // Check connectivity
294  int * components = new int[mc.num_nodes];
295  const int comp_num =
297  mc.edges, components);
298  if (comp_num > 1) {
299  printf("There are %i components in the graph. Adding 0 cost edges.\n",
300  comp_num);
301  std::set<int> seen;
302  seen.insert(components[0]);
303  for (i = 0; i < mc.num_nodes; ++i) {
304  if (seen.find(components[i]) == seen.end()) {
305  // not seen component. connect it
306  mc.edges[mc.num_edges].tail = 0;
307  mc.edges[mc.num_edges].head = i;
308  mc.edges[mc.num_edges++].cost = 0;
309  seen.insert(components[i]);
310  }
311  }
312  }
313  delete[] components;
314  }
315 
316  // rescale the edges
317  for (i = 0; i < mc.num_edges; ++i) {
318  const double c = mc.edges[i].cost;
319  mc.edges[i].cost = floor(c / rescale + 0.5);
320  }
321 
322 
323  // Negate the cost of the edges (minimizing!) and compute their sum
324  mc.sum_edge_weight = 0;
325  for (i = 0; i < mc.num_edges; ++i) {
326  const double c = - mc.edges[i].cost;
327  mc.edges[i].cost = c;
328  mc.sum_edge_weight += c;
329  }
330 
331  mc.create_adj_lists();
332 
333  if (mc.ising_problem) {
334  const int grid = static_cast<int>(sqrt(mc.num_nodes + 1.0));
335  const int num_grid_nodes = grid * grid;
336  const int num_grid_edges = 2 * num_grid_nodes;
337  const int vertical = num_grid_nodes;
338  {
339  // enumerate the 4-cycles
340  mc.ising_four_cycles = new int[num_grid_nodes * 4];
341  int * cycle = mc.ising_four_cycles;
342  for (i = 0; i < grid; ++i) {
343  for (j = 0; j < grid; ++j) {
344  // (i,j) -> (i,j+1)
345  cycle[0] = i*grid + j;
346  // (i,j+1) -> (i+1,j+1)
347  cycle[1] = vertical + i*grid + ((j+1) % grid);
348  // (i+1,j) -> (i+1,j+1)
349  cycle[2] = ((i+1) % grid) * grid + j;
350  // (i,j) -> (i+1,j)
351  cycle[3] = vertical + i*grid + j;
352  cycle += 4;
353  }
354  }
355  }
356 
357  const bool has_extra_node = (mc.num_nodes != num_grid_nodes);
358  if (has_extra_node) {
359  // enumerate the triangles
360  mc.ising_triangles = new int[2 * num_grid_nodes * 3];
361  int * triangle = mc.ising_triangles;
362  for (i = 0; i < grid; ++i) {
363  for (j = 0; j < grid; ++j) {
364  // (i,j) -> (i,j+1) -> extra_node ->
365  triangle[0] = i*grid + j;
366  triangle[1] = num_grid_edges + i*grid + j;
367  triangle[2] = num_grid_edges + i*grid + ((j+1) % grid);
368  if (triangle[1] > triangle[2])
369  std::swap(triangle[1], triangle[2]);
370  triangle += 3;
371  // (i,j) -> (i+1,j) -> extra_node ->
372  triangle[0] = vertical + i*grid + j;
373  triangle[1] = num_grid_edges + i*grid + j;
374  triangle[2] = num_grid_edges + ((i+1) % grid) * grid + j;
375  if (triangle[1] > triangle[2])
376  std::swap(triangle[1], triangle[2]);
377  triangle += 3;
378  }
379  }
380  }
381 
382  mc.num_structure_type = 5;
383 
384  mc.num_switch_structures = new int[mc.num_structure_type];
386 
387  // three-node connected structures
388  {
389  mc.num_switch_structures[0] = num_grid_nodes * 6;
390  mc.switch_structures[0] = new MC_switch_structure[num_grid_nodes * 6];
391  MC_switch_structure * next_struct = mc.switch_structures[0];
392 
393  int nodes[3];
394 
395  // enumerate the outgoing edges of three long chains
396  for (i = 0; i < grid; ++i) {
397  for (j = 0; j < grid; ++j) {
398  //-------------------------------------------------------------------
399  // the three nodes: (i-1,j), (i,j), (i+1,j)
400  // |
401  // |
402  nodes[0] = ((i+grid-1)%grid) * grid + j;
403  nodes[1] = i * grid + j;
404  nodes[2] = ((i+1)%grid) * grid + j;
405  MC_fill_structure(mc, *next_struct, 3, nodes);
406  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
407  abort();
408  ++next_struct;
409 
410  //-------------------------------------------------------------------
411  // the three nodes: (i,j-1), (i,j), (i,j+1)
412  // --
413  nodes[0] = i * grid + ((j+grid-1)%grid);
414  nodes[1] = i * grid + j;
415  nodes[2] = i * grid + ((j+1)%grid);
416  MC_fill_structure(mc, *next_struct, 3, nodes);
417  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
418  abort();
419  ++next_struct;
420 
421  //-------------------------------------------------------------------
422  // the three nodes: (i-1,j), (i,j), (i,j+1)
423  // |_
424  nodes[0] = ((i+grid-1)%grid) * grid + j;
425  nodes[1] = i * grid + j;
426  nodes[2] = i * grid + ((j+1)%grid);
427  MC_fill_structure(mc, *next_struct, 3, nodes);
428  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
429  abort();
430  ++next_struct;
431 
432  //-------------------------------------------------------------------
433  // (i,j+1), (i,j), (i+1,j)
434  // _
435  // |
436  nodes[0] = i * grid + ((j+1)%grid);
437  nodes[1] = i * grid + j;
438  nodes[2] = ((i+1)%grid) * grid + j;
439  MC_fill_structure(mc, *next_struct, 3, nodes);
440  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
441  abort();
442  ++next_struct;
443 
444  //-------------------------------------------------------------------
445  // the three nodes: (i+1,j), (i,j), (i,j-1)
446  // _
447  // |
448  nodes[0] = ((i+1)%grid) * grid + j;
449  nodes[1] = i * grid + j;
450  nodes[2] = i * grid + ((j+grid-1)%grid);
451  MC_fill_structure(mc, *next_struct, 3, nodes);
452  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
453  abort();
454  ++next_struct;
455 
456  //-------------------------------------------------------------------
457  // the three nodes: (i,j-1), (i,j), (i-1,j)
458  // _|
459  nodes[0] = i * grid + ((j+grid-1)%grid);
460  nodes[1] = i * grid + j;
461  nodes[2] = ((i+grid-1)%grid) * grid + j;
462  MC_fill_structure(mc, *next_struct, 3, nodes);
463  if (next_struct->num_neighbors != 8 + (has_extra_node ? 3 : 0))
464  abort();
465  ++next_struct;
466  }
467  }
468  }
469 
470  //=========================================================================
471 
472  // different four-node connected structures
473 
474  // first
475  {
476  mc.num_switch_structures[1] = 4 * num_grid_nodes;
477  mc.switch_structures[1] = new MC_switch_structure[4 * num_grid_nodes];
478  MC_switch_structure * next_struct = mc.switch_structures[1];
479 
480  int nodes[4];
481 
482  // List the outgoing edges from every square
483  for (i = 0; i < grid; ++i) {
484  for (j = 0; j < grid; ++j) {
485  // _|_
486  nodes[0] = i * grid + j;
487  nodes[1] = i * grid + ((j-1+grid)%grid);
488  nodes[2] = ((i-1+grid)%grid) * grid + j;
489  nodes[3] = i * grid + ((j+1)%grid);
490  MC_fill_structure(mc, *next_struct, 4, nodes);
491  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
492  abort();
493  ++next_struct;
494 
495  // |_
496  // |
497  nodes[0] = i * grid + j;
498  nodes[1] = ((i-1+grid)%grid) * grid + j;
499  nodes[2] = i * grid + ((j+1)%grid);
500  nodes[3] = ((i+1)%grid) * grid + j;
501  MC_fill_structure(mc, *next_struct, 4, nodes);
502  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
503  abort();
504  ++next_struct;
505 
506  // _ _
507  // |
508  nodes[0] = i * grid + j;
509  nodes[1] = i * grid + ((j+1)%grid);
510  nodes[2] = ((i+1)%grid) * grid + j;
511  nodes[3] = i * grid + ((j-1+grid)%grid);
512  MC_fill_structure(mc, *next_struct, 4, nodes);
513  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
514  abort();
515  ++next_struct;
516 
517  // _|
518  // |
519  nodes[0] = i * grid + j;
520  nodes[1] = ((i+1)%grid) * grid + j;
521  nodes[2] = i * grid + ((j-1+grid)%grid);
522  nodes[3] = ((i-1+grid)%grid) * grid + j;
523  MC_fill_structure(mc, *next_struct, 4, nodes);
524  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
525  abort();
526  ++next_struct;
527  }
528  }
529  }
530  //-------------------------------------------------------------------------
531  // second
532  {
533  mc.num_switch_structures[2] = 4 * num_grid_nodes;
534  mc.switch_structures[2] = new MC_switch_structure[4 * num_grid_nodes];
535  MC_switch_structure * next_struct = mc.switch_structures[2];
536 
537  int nodes[4];
538 
539  for (i = 0; i < grid; ++i) {
540  for (j = 0; j < grid; ++j) {
541  // _
542  // _|
543  nodes[0] = i * grid + j;
544  nodes[1] = i * grid + ((j+1)%grid);
545  nodes[2] = ((i-1+grid)%grid) * grid + ((j+1)%grid);
546  nodes[3] = ((i-1+grid)%grid) * grid + ((j+2)%grid);
547  MC_fill_structure(mc, *next_struct, 4, nodes);
548  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
549  abort();
550  ++next_struct;
551 
552  // _
553  // |_
554  nodes[0] = i * grid + j;
555  nodes[1] = i * grid + ((j+1)%grid);
556  nodes[2] = ((i+1)%grid) * grid + ((j+1)%grid);
557  nodes[3] = ((i+1)%grid) * grid + ((j+2)%grid);
558  MC_fill_structure(mc, *next_struct, 4, nodes);
559  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
560  abort();
561  ++next_struct;
562 
563  // |_
564  // |
565  nodes[0] = i * grid + j;
566  nodes[1] = ((i+1)%grid) * grid + j;
567  nodes[2] = ((i+1)%grid) * grid + ((j+1)%grid);
568  nodes[3] = ((i+2)%grid) * grid + ((j+1)%grid);
569  MC_fill_structure(mc, *next_struct, 4, nodes);
570  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
571  abort();
572  ++next_struct;
573 
574  // _|
575  // |
576  nodes[0] = i * grid + j;
577  nodes[1] = ((i+1)%grid) * grid + j;
578  nodes[2] = ((i+1)%grid) * grid + ((j-1+grid)%grid);
579  nodes[3] = ((i+2)%grid) * grid + ((j-1+grid)%grid);
580  MC_fill_structure(mc, *next_struct, 4, nodes);
581  if (next_struct->num_neighbors != 10 + (has_extra_node ? 4 : 0))
582  abort();
583  ++next_struct;
584  }
585  }
586  }
587  //-------------------------------------------------------------------------
588  // third
589  {
590  mc.num_switch_structures[3] = num_grid_nodes;
591  mc.switch_structures[3] = new MC_switch_structure[num_grid_nodes];
592  MC_switch_structure * next_struct = mc.switch_structures[3];
593 
594  int nodes[4];
595 
596  for (i = 0; i < grid; ++i) {
597  for (j = 0; j < grid; ++j) {
598  // the square is (i,j), (i,j+1), (i+1,j+1), (i+1,j)
599  // _
600  // |_|
601  nodes[0] = i * grid + j;
602  nodes[1] = i * grid + ((j+1)%grid);
603  nodes[2] = ((i+1)%grid) * grid + ((j+1)%grid);
604  nodes[3] = ((i+1)%grid) * grid + j;
605  MC_fill_structure(mc, *next_struct, 4, nodes);
606  if (next_struct->num_neighbors != 8 + (has_extra_node ? 4 : 0))
607  abort();
608  ++next_struct;
609  }
610  }
611  }
612 
613  //=========================================================================
614 
615  // a 6-node connected structures
616 
617  {
618  mc.num_switch_structures[4] = 2 * num_grid_nodes;
619  mc.switch_structures[4] = new MC_switch_structure[2 * num_grid_nodes];
620  MC_switch_structure * next_struct = mc.switch_structures[4];
621 
622  int nodes[6];
623 
624  for (i = 0; i < grid; ++i) {
625  for (j = 0; j < grid; ++j) {
626  // _ _
627  // |_|_|
628  nodes[0] = i * grid + j;
629  nodes[1] = i * grid + ((j+1)%grid);
630  nodes[2] = i * grid + ((j+2)%grid);
631  nodes[3] = ((i+1)%grid) * grid + j;
632  nodes[4] = ((i+1)%grid) * grid + ((j+1)%grid);
633  nodes[5] = ((i+1)%grid) * grid + ((j+2)%grid);
634  MC_fill_structure(mc, *next_struct, 6, nodes);
635  if (next_struct->num_neighbors != 10 + (has_extra_node ? 6 : 0))
636  abort();
637  ++next_struct;
638 
639  // _
640  // |_|
641  // |_|
642  nodes[0] = i * grid + j;
643  nodes[1] = i * grid + ((j+1)%grid);
644  nodes[2] = ((i+1)%grid) * grid + j;
645  nodes[3] = ((i+1)%grid) * grid + ((j+1)%grid);
646  nodes[4] = ((i+2)%grid) * grid + j;
647  nodes[5] = ((i+2)%grid) * grid + ((j+1)%grid);
648  MC_fill_structure(mc, *next_struct, 6, nodes);
649  if (next_struct->num_neighbors != 10 + (has_extra_node ? 6 : 0))
650  abort();
651  ++next_struct;
652  }
653  }
654  }
655  }
656 
657  if (tm.tm_par.entry(MC_tm_par::FeasSolFile).length() > 0) {
658  std::ifstream solfile(tm.tm_par.entry(MC_tm_par::FeasSolFile).c_str());
659  if (! solfile) {
660  throw BCP_fatal_error("Can't open feas solution file!\n");
661  }
662  int* s = new int[mc.num_nodes];
663  for (i = 0; i < mc.num_nodes; ++i) {
664  solfile.getline(line, 999);
665  sscanf(line, "%i", s+i);
666  }
667  solfile.close();
668  mc.feas_sol = new MC_feas_sol(mc.num_nodes, s, mc.num_edges, mc.edges);
669  printf("\nMC: value of input solution: %.0f\n\n", mc.feas_sol->cost);
670  }
671 }
int * ising_four_cycles
Definition: MC.hpp:105
double cost
Definition: MC.hpp:31
Definition: MC_lp.hpp:16
BCP_tm_user * tm_init(BCP_tm_prob &p, const int argnum, const char *const *arglist)
Definition: MC_init.cpp:72
int num_edges
Definition: MC.hpp:92
The minimum difference between the objective value of any two feasible solution (with different objec...
BCP_buffer & unpack(T &value)
Unpack a single object of type T.
Definition: BCP_buffer.hpp:186
void create_adj_lists()
Definition: MC.cpp:115
int head
Definition: MC.hpp:30
This is the class from which the user should derive her own algorithmic cuts.
Definition: BCP_cut.hpp:242
int num_nodes
Definition: MC.hpp:91
char entry(const chr_params key) const
MC_graph_edge * edges
Definition: MC.hpp:95
BCP_parameter_set< MC_lp_par > lp_par
Definition: MC_tm.hpp:19
??? Values: Default:
NO OLD DOC.
Definition: BCP_lp.hpp:102
int * ising_triangles
Definition: MC.hpp:107
static bool operator<(const intpair &ip0, const intpair &ip1)
Definition: MC_init.cpp:200
static char * j
Definition: OSdtoa.cpp:3622
The BCP_lp_user class is the base class from which the user can derive a problem specific class to be...
Definition: BCP_lp_user.hpp:75
USER_initialize * BCP_user_init()
Definition: MC_init.cpp:15
int tail
Definition: MC.hpp:29
void pack(BCP_buffer &buf) const
Definition: MC_cut.cpp:13
MC_switch_structure ** switch_structures
Definition: MC.hpp:111
bool ising_problem
Definition: MC.hpp:99
BCP_lp_user * lp_init(BCP_lp_prob &p)
Definition: MC_init.cpp:96
double scaling_factor
Definition: MC.hpp:102
int degree
Definition: MC.hpp:21
int MC_components(const int n, const int m, const MC_graph_edge *edges, int *component)
Definition: MC_init.cpp:113
void fint fint fint real fint real real real real real real real real real fint real fint * lp
This class is an abstract base class for the initializer class the user has to provide.
Definition: BCP_USER.hpp:160
double cost
Definition: MC.hpp:56
BCP_parameter_set< MC_tm_par > tm_par
Definition: MC_tm.hpp:18
BCP_user_pack * packer_init(BCP_user_class *p)
Definition: MC_init.cpp:23
MC_graph_node * nodes
Definition: MC.hpp:96
void read_from_file(const char *paramfile)
Simply invoke reading from a stream.
void pack(BCP_buffer &buf) const
Definition: MC_cut.cpp:29
void set_entry(const chr_params key, const char val)
virtual void pack_cut_algo(const BCP_cut_algo *cut, BCP_buffer &buf)
Pack an algorithmic cut.
Definition: MC_init.cpp:31
NO OLD DOC.
Definition: BCP_tm.hpp:136
void fint fint * k
MC_feas_sol * feas_sol
Definition: MC.hpp:114
virtual BCP_cut_algo * unpack_cut_algo(BCP_buffer &buf)
Unpack an algorithmic cut.
Definition: MC_init.cpp:50
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
BCP_parameter_set< BCP_tm_par > par
Definition: BCP_tm.hpp:168
MC_problem mc
Definition: MC_tm.hpp:23
Definition: MC_tm.hpp:16
Definition: MC.hpp:10
static void MC_fill_structure(const MC_problem &mc, MC_switch_structure &swstruct, const int num_nodes, const int *nodes)
Definition: MC_init.cpp:166
int num_neighbors
Definition: MC.hpp:43
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
std::pair< int, int > intpair
Definition: MC_init.cpp:197
int index
Definition: MC.hpp:13
void MC_read_parameters(MC_tm &tm, const char *paramfile)
Definition: MC_init.cpp:104
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
int num_structure_type
Definition: MC.hpp:109
BCP_parameter_set< BCP_lp_par > lp
Definition: BCP_tm.hpp:61
MC_adjacency_entry * adj_list
Definition: MC.hpp:22
MC_cut_t
Definition: MC_cut.hpp:21
int * num_switch_structures
Definition: MC.hpp:110
BCP_slave_params slave_pars
Definition: BCP_tm.hpp:170
The BCP_tm_user class is the base class from which the user can derive a problem specific class to be...
Definition: BCP_tm_user.hpp:58
void fint * m
double sum_edge_weight
Definition: MC.hpp:101
void fint * n
void MC_readproblem(MC_tm &tm)
Definition: MC_init.cpp:206
real c
int * neighbors
Definition: MC.hpp:45