CMR  1.3.0
algorithm.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "matroid_decomposition.hpp"
4 #include "find_wheel_minor.hpp"
5 #include "matroid_separate.hpp"
6 #include "nested_minor_sequence.hpp"
7 #include "find_minor_sequence.hpp"
8 #include "graphicness.hpp"
9 #include "r10.hpp"
10 #include "enumeration.hpp"
11 #include "logger.hpp"
12 
13 namespace tu
14 {
16 
17  template <typename MatroidType, typename MatrixType>
18  std::pair<bool, decomposed_matroid*> decompose_binary_matroid(MatroidType& matroid, MatrixType& matrix,
19  matroid_element_set extra_elements, bool construct_decomposition, logger& log);
20 
21  template <typename MatroidType, typename MatrixType>
22  std::pair<bool, decomposed_matroid*> decompose_with_minor_sequence(matroid_permuted<MatroidType>& permuted_matroid,
23  matrix_permuted<MatrixType>& permuted_matrix, nested_minor_sequence& nested_minors,
24  matroid_element_set extra_elements, bool construct_decomposition, logger& log)
25  {
26  separation sep = find_minor_sequence(permuted_matroid, permuted_matrix, nested_minors, extra_elements, log);
27  if (sep.is_valid())
28  {
29  if (log.is_progressive())
30  {
31  log.line() << " --> " << (sep.rank() + 1) << "-SEP";
32  std::cout << log << std::endl;
33  log.clear();
34  log.indent();
35  }
36  else if (log.is_verbose())
37  {
38  std::cout << "Found a " << (sep.rank() + 1) << "-separation instead." << std::endl;
39  }
40 
41  integer_matroid upper_left_matroid;
42  integer_matrix upper_left_matrix;
43  integer_matroid lower_right_matroid;
44  integer_matrix lower_right_matrix;
45 
46  sep.create_components(permuted_matroid, permuted_matrix, upper_left_matroid, upper_left_matrix,
47  lower_right_matroid, lower_right_matrix);
48 
49  if (log.is_verbose())
50  {
51  std::cout << "Summands are " << upper_left_matrix.size1() << " x " << upper_left_matrix.size2() << " and "
52  << lower_right_matrix.size1() << " x " << lower_right_matrix.size2() << "." << std::endl;
53  }
54 
56  matroid_element_set upper_left_extra_elements, lower_right_extra_elements;
57  if (sep.rank() == 0)
58  {
59  matroid_element_set upper_left_elements = upper_left_matroid.get_elements();
60  matroid_element_set lower_right_elements = lower_right_matroid.get_elements();
61 
62  std::set_difference(extra_elements.begin(), extra_elements.end(), lower_right_elements.begin(),
63  lower_right_elements.end(), std::inserter(upper_left_extra_elements, upper_left_extra_elements.end()));
64  std::set_difference(extra_elements.begin(), extra_elements.end(), upper_left_elements.begin(),
65  upper_left_elements.end(), std::inserter(lower_right_extra_elements, lower_right_extra_elements.end()));
66  }
67  else
68  {
69  std::copy(extra_elements.begin(), extra_elements.end(), std::inserter(upper_left_extra_elements,
70  upper_left_extra_elements.end()));
71  std::copy(extra_elements.begin(), extra_elements.end(), std::inserter(lower_right_extra_elements,
72  lower_right_extra_elements.end()));
73  }
74 
75  matroid_permuted<integer_matroid> permuted_upper_left_matroid(upper_left_matroid);
76  matrix_permuted<integer_matrix> permuted_upper_left_matrix(upper_left_matrix);
77 
78  if (sep.has_special_swap())
79  {
80  if (sep.has_special_row_swap())
81  matroid_permute1(permuted_upper_left_matroid, permuted_upper_left_matrix, upper_left_matroid.size1() - 1,
82  sep.get_special_swap_index());
83  else
84  matroid_permute2(permuted_upper_left_matroid, permuted_upper_left_matrix, upper_left_matroid.size2() - 1,
85  sep.get_special_swap_index());
86  }
87 
88  if (log.is_progressive())
89  {
90  log.line() << "(" << upper_left_matrix.size1() << " x " << upper_left_matrix.size2() << ") W3";
91  std::cout << log;
92  }
93  else if (log.is_verbose())
94  {
95  std::cout << "Proceeding search for a sequence of nested minors in binary "
96  << permuted_upper_left_matroid.size1() << " x " << permuted_upper_left_matrix.size2() << " matroid."
97  << std::endl;
98  }
99 
100  std::pair<bool, decomposed_matroid*> upper_left_result = decompose_with_minor_sequence(
101  permuted_upper_left_matroid, permuted_upper_left_matrix, nested_minors, upper_left_extra_elements,
102  construct_decomposition, log);
103 
104  if (!construct_decomposition && !upper_left_result.first)
105  {
106  log.unindent();
107  return std::pair<bool, decomposed_matroid*>(false, NULL);
108  }
109 
110  std::pair<bool, decomposed_matroid*> lower_right_result = decompose_binary_matroid(lower_right_matroid,
111  lower_right_matrix, lower_right_extra_elements, construct_decomposition, log);
112 
113  if (log.is_progressive())
114  {
115  log.unindent();
116  }
117 
118  if (construct_decomposition)
119  {
120  int type = sep.rank() == 0 ? static_cast<int>(decomposed_matroid_separator::ONE_SEPARATION)
121  : static_cast<int>(decomposed_matroid_separator::TWO_SEPARATION);
122 
123  return std::pair<bool, decomposed_matroid*>(lower_right_result.first && upper_left_result.first,
124  new decomposed_matroid_separator(upper_left_result.second, lower_right_result.second, type,
125  matroid_elements(permuted_matroid), extra_elements));
126  }
127  else
128  return std::pair<bool, decomposed_matroid*>(lower_right_result.first, NULL);
129  }
130 
131  if (log.is_verbose())
132  {
133  std::cout << "Constructed sequence of " << (nested_minors.size() + 1)
134  << " 3-connected nested minors starting with W3." << std::endl;
135  }
136 
137  size_t largest_graphic_minor = 0;
138  matroid_graph* graph = construct_matroid_graph(permuted_matroid, permuted_matrix, nested_minors,
139  largest_graphic_minor);
140 
141  if (log.is_progressive())
142  {
143  log.line() << (graph == NULL ? ", NON-GRAPHIC" : ", GRAPHIC");
144  std::cout << log;
145  }
146  else if (log.is_verbose())
147  std::cout << "Matroid is " << (graph == NULL ? "not " : "") << "graphic." << std::endl;
148 
149  if (!construct_decomposition && graph)
150  {
151  if (log.is_progressive())
152  {
153  log.clear();
154  std::cout << " --> REGULAR" << std::endl;
155  }
156  else if (log.is_verbose())
157  {
158  std::cout << "Graphic matroids are always regular." << std::endl;
159  }
160 
161  delete graph;
162  return std::make_pair(true, (decomposed_matroid*) NULL);
163  }
164 
165  size_t largest_cographic_minor = 0;
166  matroid_graph* cograph = construct_matroid_graph(make_transposed_matroid(permuted_matroid), make_transposed_matrix(
167  permuted_matrix), make_transposed_nested_minor_sequence(nested_minors), largest_cographic_minor);
168 
169  if (log.is_progressive())
170  {
171  log.line() << (cograph == NULL ? ", NON-COGRAPHIC" : ", COGRAPHIC");
172  std::cout << log;
173  }
174  else if (log.is_verbose())
175  {
176  std::cout << "Matroid is " << (cograph == NULL ? "not " : "") << "cographic." << std::endl;
177  }
178 
179  if (!construct_decomposition && cograph)
180  {
181  if (log.is_progressive())
182  {
183  log.clear();
184  std::cout << " --> REGULAR" << std::endl;
185  }
186  else if (log.is_verbose())
187  {
188  std::cout << "Cographic matroids are always regular." << std::endl;
189  }
190 
191  delete cograph;
192  return std::make_pair(true, (decomposed_matroid*) NULL);
193  }
194 
195  if (construct_decomposition && (graph || cograph))
196  {
197  if (log.is_progressive())
198  {
199  log.clear();
200  std::cout << std::endl;
201  }
202  else if (log.is_verbose())
203  {
204  if (graph && cograph)
205  std::cout << "Planar matroids are always regular." << std::endl;
206  else if (graph && cograph == NULL)
207  std::cout << "Graphic matroids are always regular." << std::endl;
208  else if (graph == NULL && cograph)
209  std::cout << "Cographic matroids are always regular." << std::endl;
210 
211  }
212 
213  return std::make_pair(true, new decomposed_matroid_leaf(graph, cograph, false,
214  matroid_elements(permuted_matroid), extra_elements));
215  }
216 
217  if (is_r10(permuted_matrix))
218  {
219  if (log.is_progressive())
220  {
221  log.line() << ", R10 --> REGULAR";
222  std::cout << log << std::endl;
223  log.clear();
224  }
225  else if (log.is_verbose())
226  {
227  std::cout << "Matroid is isomorphic to R10 and thus regular." << std::endl;
228  }
229 
230  if (construct_decomposition)
231  {
232  return std::make_pair(true, new decomposed_matroid_leaf(NULL, NULL, true, matroid_elements(permuted_matroid),
233  extra_elements));
234  }
235  else
236  return std::make_pair(true, (decomposed_matroid*) NULL);
237  }
238  else
239  {
240  if (log.is_progressive())
241  {
242  log.line() << ", NOT R10";
243  std::cout << log;
244  }
245  else if (log.is_verbose())
246  std::cout << "Matroid is not isomorphic to R10." << std::endl;
247  }
248 
249  size_t new_size = largest_graphic_minor > largest_cographic_minor ? largest_graphic_minor : largest_cographic_minor;
250  if (log.is_progressive())
251  {
252  log.line() << ", (CO)GRAPHIC LEN: " << new_size;
253  std::cout << log;
254  }
255  else if (log.is_verbose())
256  std::cout << "Sequence is (co)graphic until N_" << new_size << "." << std::endl;
257 
258  std::size_t minSize = 0;
259  std::size_t numElements = 6;
260  for (minSize = 0; minSize < nested_minors.size() && numElements < 8; ++minSize)
261  {
262  numElements += nested_minors.get_extension_height(minSize) + nested_minors.get_extension_width(minSize);
263  }
264 
265  if (new_size < minSize)
266  {
267  new_size = minSize;
268  if (log.is_progressive())
269  {
270  log.line() << ", EXTENDING TO " << new_size;
271  std::cout << log;
272  }
273  else if (log.is_verbose())
274  std::cout << "Sequence extended by to N_" << new_size << " to achieve minimum size." << std::endl;
275  }
276 
277  nested_minors.resize(new_size);
278 
279  sep = enumerate_separations(permuted_matroid, permuted_matrix, nested_minors, extra_elements, log);
280  if (sep.is_valid())
281  {
282  if (log.is_progressive())
283  {
284  log.line() << " --> " << (sep.rank() + 1) << "-SEP";
285  std::cout << log << std::endl;
286  log.clear();
287  log.indent();
288  }
289  else if (log.is_verbose())
290  {
291  std::cout << "Found a (3|4)-separation." << std::endl;
292  }
293 
294  integer_matroid upper_left_matroid;
295  integer_matrix upper_left_matrix;
296  integer_matroid lower_right_matroid;
297  integer_matrix lower_right_matrix;
298 
299  sep.create_components(permuted_matroid, permuted_matrix, upper_left_matroid, upper_left_matrix,
300  lower_right_matroid, lower_right_matrix);
301 
302  if (log.is_verbose())
303  {
304  std::cout << "Summands are " << upper_left_matrix.size1() << " x " << upper_left_matrix.size2() << " and "
305  << lower_right_matrix.size1() << " x " << lower_right_matrix.size2() << "." << std::endl;
306  }
307 
308  matroid_permuted<integer_matroid> permuted_upper_left_matroid(upper_left_matroid);
309  matrix_permuted<integer_matrix> permuted_upper_left_matrix(upper_left_matrix);
310 
311  std::pair<bool, decomposed_matroid*> upper_left_result = decompose_binary_matroid(permuted_upper_left_matroid,
312  permuted_upper_left_matrix, extra_elements, construct_decomposition, log);
313 
314  if (!construct_decomposition && !upper_left_result.first)
315  {
316  if (log.is_progressive())
317  {
318  log.unindent();
319  }
320  return std::pair<bool, decomposed_matroid*>(false, NULL);
321  }
322 
323  std::pair<bool, decomposed_matroid*> lower_right_result = decompose_binary_matroid(lower_right_matroid,
324  lower_right_matrix, extra_elements, construct_decomposition, log);
325 
326  if (log.is_progressive())
327  {
328  log.unindent();
329  }
330 
331  if (construct_decomposition)
332  return std::make_pair(lower_right_result.first && upper_left_result.first,
333  (decomposed_matroid *) (new decomposed_matroid_separator(upper_left_result.second,
334  lower_right_result.second, decomposed_matroid_separator::THREE_SEPARATION, matroid_elements(
335  permuted_matroid), extra_elements)));
336  else
337  return std::pair<bool, decomposed_matroid*>(lower_right_result.first, NULL);
338  }
339 
340  if (construct_decomposition)
341  return std::make_pair(false, new decomposed_matroid_leaf(NULL, NULL, false, matroid_elements(permuted_matroid),
342  extra_elements));
343  else
344  return std::make_pair(false, (decomposed_matroid*) NULL);
345  }
346 
355  template <typename MatroidType, typename MatrixType>
356  matroid_graph* construct_small_matroid_graph(MatroidType& matroid, MatrixType& matrix)
357  {
358  assert(matroid.size1() <= 2 || matroid.size2() <= 2);
359 
360  matroid_graph* graph = new matroid_graph(matroid.size1() + 1);
361 
362  if (matroid.size1() == 0)
363  {
364  for (size_t column = 0; column < matroid.size2(); ++column)
365  {
366  boost::add_edge(boost::vertex(0, *graph), boost::vertex(0, *graph), matroid.name2(0), *graph);
367  }
368  }
369  else if (matroid.size2() == 0)
370  {
371  for (size_t row = 0; row < matroid.size1(); ++row)
372  {
373  boost::add_edge(boost::vertex(row, *graph), boost::vertex(row + 1, *graph), matroid.name1(row), *graph);
374  }
375  }
376  else if (matroid.size1() >= 3 && matroid.size2() == 1)
377  {
378  size_t current_edge_vertex = 0;
379  size_t current_free_vertex = matroid.size1();
380 
381  for (size_t row = 0; row < matroid.size1(); ++row)
382  {
383  if (matrix(row, 0) == 0)
384  {
385  boost::add_edge(boost::vertex(current_free_vertex - 1, *graph), boost::vertex(current_free_vertex, *graph),
386  matroid.name1(row), *graph);
387  --current_free_vertex;
388  }
389  else
390  {
391  boost::add_edge(boost::vertex(current_edge_vertex, *graph), boost::vertex(current_edge_vertex + 1, *graph),
392  matroid.name1(row), *graph);
393  ++current_edge_vertex;
394  }
395  }
396 
397  assert(current_edge_vertex == current_free_vertex);
398 
399  boost::add_edge(boost::vertex(0, *graph), boost::vertex(current_edge_vertex, *graph), matroid.name2(0), *graph);
400  }
401  else if (matroid.size1() >= 3 && matroid.size2() == 2)
402  {
403  size_t count[4] =
404  { 0, 0, 0, 0 };
405  for (size_t row = 0; row < matroid.size1(); ++row)
406  {
407  count[((matrix(row, 0) != 0) ? 2 : 0) + ((matrix(row, 1) != 0) ? 1 : 0)]++;
408  }
409 
410  size_t vertex[4];
411  vertex[0] = 0;
412  vertex[1] = count[1];
413  vertex[2] = vertex[1] + count[3];
414  vertex[3] = vertex[2] + count[2];
415 
416  boost::add_edge(boost::vertex(vertex[0], *graph), boost::vertex(vertex[2], *graph), matroid.name2(1), *graph);
417  boost::add_edge(boost::vertex(vertex[1], *graph), boost::vertex(vertex[3], *graph), matroid.name2(0), *graph);
418 
419  for (size_t row = 0; row < matroid.size1(); ++row)
420  {
421  int element = matroid.name1(row);
422  switch (((matrix(row, 0) != 0) ? 2 : 0) + ((matrix(row, 1) != 0) ? 1 : 0))
423  {
424  case 1:
425  boost::add_edge(boost::vertex(vertex[0], *graph), boost::vertex(vertex[0] + 1, *graph), element, *graph);
426  ++vertex[0];
427  break;
428  case 2:
429  boost::add_edge(boost::vertex(vertex[2], *graph), boost::vertex(vertex[2] + 1, *graph), element, *graph);
430  ++vertex[2];
431  break;
432  case 3:
433  boost::add_edge(boost::vertex(vertex[1], *graph), boost::vertex(vertex[1] + 1, *graph), element, *graph);
434  ++vertex[1];
435  break;
436  default:
437  assert(matrix(row, 0) == 0 && matrix(row, 1) == 0);
438  boost::add_edge(boost::vertex(vertex[3], *graph), boost::vertex(vertex[3] + 1, *graph), element, *graph);
439  ++vertex[3];
440  break;
441  }
442  }
443  }
444  else
445  {
446  assert(matroid.size1() <= 2);
447 
448  for (size_t row = 0; row < matroid.size1(); ++row)
449  {
450  boost::add_edge(boost::vertex(row, *graph), boost::vertex(row + 1, *graph), matroid.name1(row), *graph);
451  }
452 
453  for (size_t column = 0; column < matroid.size2(); ++column)
454  {
455  size_t end_vertex, start_vertex = 0;
456  while (start_vertex < matroid.size1() && matrix(start_vertex, column) == 0)
457  {
458  ++start_vertex;
459  }
460  end_vertex = start_vertex;
461  while (end_vertex < matroid.size1() && matrix(end_vertex, column) == 1)
462  {
463  ++end_vertex;
464  }
465 
466  boost::add_edge(boost::vertex(start_vertex, *graph), boost::vertex(end_vertex, *graph), matroid.name2(column),
467  *graph);
468  }
469  }
470 
471  return graph;
472  }
473 
483  template <typename MatroidType, typename MatrixType>
484  std::pair<bool, decomposed_matroid*> decompose_binary_matroid(MatroidType& matroid, MatrixType& matrix,
485  matroid_element_set extra_elements, bool construct_decomposition, logger& log)
486  {
487  assert(is_zero_one_matrix(matrix));
488 
489  if (log.is_progressive())
490  {
491  log.clear();
492  log.line() << "(" << matrix.size1() << " x " << matrix.size2() << ")";
493  std::cout << log;
494  }
495  else if (log.is_verbose())
496  {
497  std::cout << "Decomposing binary " << matrix.size1() << " x " << matrix.size2() << " matroid." << std::endl;
498  }
499 
500  if (matroid.size1() <= 2 || matroid.size2() <= 2)
501  {
502  if (log.is_progressive())
503  {
504  log.line() << " TRIVIAL --> REGULAR";
505  std::cout << log << std::endl;
506  log.clear();
507  }
508  else if (log.is_verbose())
509  {
510  std::cout << "The matroid is trivial and thus regular." << std::endl;
511  }
512 
513  if (construct_decomposition)
514  {
515  matroid_transposed<MatroidType> transposed_matroid(matroid);
516  matrix_transposed<MatrixType> transposed_matrix(matrix);
517  matroid_graph* g = construct_small_matroid_graph(matroid, matrix);
518  matroid_graph* c = construct_small_matroid_graph(transposed_matroid, transposed_matrix);
519 
520  return std::make_pair(true, new decomposed_matroid_leaf(g, c, false, matroid_elements(matroid), extra_elements));
521  }
522  else
523  {
524  return std::make_pair(true, (decomposed_matroid*) NULL);
525  }
526  }
527 
528  typedef matroid_permuted<MatroidType> permuted_matroid_type;
529  typedef matrix_permuted<MatrixType> permuted_marix_type;
530 
531  permuted_matroid_type permuted_matroid(matroid);
532  permuted_marix_type permuted_matrix(matrix);
533 
534  if (log.is_progressive())
535  {
536  log.line() << " W3";
537  std::cout << log;
538  }
539  else if (log.is_verbose())
540  {
541  std::cout << "Searching for a W3 minor." << std::endl;
542  }
543 
545 
546  separation sep = find_wheel_minor(permuted_matroid, permuted_matrix, extra_elements);
547 
548  if (sep.is_valid())
549  {
551  if (log.is_progressive())
552  {
553  log.line() << " --> " << (sep.rank() + 1) << "-separation";
554  std::cout << log << std::endl;
555  log.clear();
556  log.indent();
557  }
558  else if (log.is_verbose())
559  {
560  std::cout << "Found a " << (sep.rank() + 1) << "-separation instead." << std::endl;
561  }
562 
563  integer_matroid upper_left_matroid;
564  integer_matrix upper_left_matrix;
565  integer_matroid lower_right_matroid;
566  integer_matrix lower_right_matrix;
567 
568  sep.create_components(permuted_matroid, permuted_matrix, upper_left_matroid, upper_left_matrix,
569  lower_right_matroid, lower_right_matrix);
570 
572  matroid_element_set upper_left_extra_elements, lower_right_extra_elements;
573  if (sep.rank() == 0 && false)
574  {
575  matroid_element_set upper_left_elements = upper_left_matroid.get_elements();
576  matroid_element_set lower_right_elements = lower_right_matroid.get_elements();
577 
578  std::set_difference(extra_elements.begin(), extra_elements.end(), lower_right_elements.begin(),
579  lower_right_elements.end(), std::inserter(upper_left_extra_elements, upper_left_extra_elements.end()));
580  std::set_difference(extra_elements.begin(), extra_elements.end(), upper_left_elements.begin(),
581  upper_left_elements.end(), std::inserter(lower_right_extra_elements, lower_right_extra_elements.end()));
582  }
583  else
584  {
585  std::copy(extra_elements.begin(), extra_elements.end(), std::inserter(upper_left_extra_elements,
586  upper_left_extra_elements.end()));
587  std::copy(extra_elements.begin(), extra_elements.end(), std::inserter(lower_right_extra_elements,
588  lower_right_extra_elements.end()));
589  }
590 
591  if (log.is_verbose())
592  {
593  std::cout << "Summands are " << upper_left_matrix.size1() << " x " << upper_left_matrix.size2() << " and "
594  << lower_right_matrix.size1() << " x " << lower_right_matrix.size2() << "." << std::endl;
595  }
596 
597  std::pair<bool, decomposed_matroid*> upper_left_result = decompose_binary_matroid(upper_left_matroid,
598  upper_left_matrix, upper_left_extra_elements, construct_decomposition, log);
599 
600  if (!construct_decomposition && !upper_left_result.first)
601  {
602  if (log.is_progressive())
603  {
604  log.unindent();
605  }
606  return std::pair<bool, decomposed_matroid*>(false, NULL);
607  }
608 
609  std::pair<bool, decomposed_matroid*> lower_right_result = decompose_binary_matroid(lower_right_matroid,
610  lower_right_matrix, lower_right_extra_elements, construct_decomposition, log);
611 
612  if (log.is_progressive())
613  {
614  log.unindent();
615  }
616 
617  if (construct_decomposition)
618  {
619  int type = sep.rank() == 0 ? static_cast<int>(decomposed_matroid_separator::ONE_SEPARATION)
620  : static_cast<int>(decomposed_matroid_separator::TWO_SEPARATION);
621 
622  return std::pair<bool, decomposed_matroid*>(lower_right_result.first && upper_left_result.first,
623  new decomposed_matroid_separator(upper_left_result.second, lower_right_result.second, type,
624  matroid_elements(permuted_matroid), extra_elements));
625  }
626  else
627  return std::pair<bool, decomposed_matroid*>(lower_right_result.first && upper_left_result.first, NULL);
628  }
629 
630  if (log.is_verbose())
631  {
632  std::cout << "Searching for a sequence of nested minors in binary " << permuted_matrix.size1() << " x "
633  << permuted_matrix.size2() << " matroid." << std::endl;
634  }
635 
636  nested_minor_sequence nested_minors;
637 
638  return decompose_with_minor_sequence(permuted_matroid, permuted_matrix, nested_minors, extra_elements,
639  construct_decomposition, log);
640  }
641 
642 } /* namespace tu */
Definition: algorithm.hpp:14
std::pair< bool, decomposed_matroid * > decompose_with_minor_sequence(matroid_permuted< MatroidType > &permuted_matroid, matrix_permuted< MatrixType > &permuted_matrix, nested_minor_sequence &nested_minors, matroid_element_set extra_elements, bool construct_decomposition, logger &log)
Definition: algorithm.hpp:22
std::pair< bool, decomposed_matroid * > decompose_binary_matroid(MatroidType &matroid, MatrixType &matrix, matroid_element_set extra_elements, bool construct_decomposition, logger &log)
Forward declaration.
Definition: algorithm.hpp:484
matroid_graph * construct_small_matroid_graph(MatroidType &matroid, MatrixType &matrix)
Definition: algorithm.hpp:356