CMR  1.3.0
enumeration.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
5 #include "separation.hpp"
6 #include "permutations.hpp"
7 #include "comparators.hpp"
8 #include "partition.hpp"
10 #include "bipartite_graph_bfs.hpp"
11 #include "matrix_modified.hpp"
12 #include "logger.hpp"
13 
14 namespace tu
15 {
16  namespace detail
17  {
18 
25  {
26  typedef int value_type;
27 
35  _split(split)
36  {
37 
38  }
39 
49  value_type operator()(size_t i, size_t j, value_type value)
50  {
51  if (i < _split.first || j >= _split.second)
52  return value;
53  else
54  return 0;
55  }
56 
57  private:
58  size_pair_t _split;
59 
60  };
61 
72  template <typename MatroidType, typename MatrixType>
73  inline void find_column_witnesses(MatroidType& matroid, MatrixType& matrix, size_pair_t split, matroid_element_set& extra_elements)
74  {
75  binary_linear_space vector_space(matroid.size1() - split.first);
76  binary_linear_space::vector_type vector(matroid.size1() - split.first);
77  std::vector <size_t> type(split.second);
78 
79  typedef std::set <size_t> column_set_t;
80  column_set_t types[4];
81 
83  empty_bottom_left_modifier modifier(split);
84  matrix_modified <MatrixType, empty_bottom_left_modifier> modified_matrix(matrix, modifier);
85  bipartite_graph_dimensions dimensions(modified_matrix.size1(), modified_matrix.size2());
86 
87  for (size_t column = 0; column < split.second; ++column)
88  {
89  copy_partial_column(matrix, vector, column, split.first, matrix.size1());
90  vector_space.insert_checked(vector);
91  size_t type = vector_space.find(vector);
92 
93  assert (type < 4);
94  types[type].insert(dimensions.column_to_index(column));
95  }
96 
97  size_t reached_column = 0;
98  size_t starting_column = 0;
99  size_t connecting_row = 0;
100 
102  size_t reached_node;
103  std::vector <bipartite_graph_bfs_node> nodes;
104  column_set_t start_nodes = types[1];
105  column_set_t end_nodes = types[2];
106  std::copy(types[3].begin(), types[3].end(), std::inserter(end_nodes, end_nodes.end()));
107 
108  if (bipartite_graph_bfs(modified_matrix, dimensions, start_nodes, end_nodes, false, nodes))
109  {
111  reached_node = 0;
112  for (column_set_t::const_iterator iter = end_nodes.begin(); iter != end_nodes.end(); ++iter)
113  {
114  if (nodes[*iter].is_reachable())
115  {
116  reached_node = *iter;
117  break;
118  }
119  }
120  }
121  else if (bipartite_graph_bfs(modified_matrix, dimensions, types[2], types[3], false, nodes))
122  {
124  reached_node = 0;
125  for (column_set_t::const_iterator iter = types[3].begin(); iter != types[3].end(); ++iter)
126  {
127  if (nodes[*iter].is_reachable())
128  {
129  reached_node = *iter;
130  break;
131  }
132  }
133  }
134  else
135  {
136  throw std::runtime_error("tu::find_column_witnesses failed to find paths between columns of different type.");
137  }
138 
140  reached_column = dimensions.index_to_column(reached_node);
141  for (size_t current_node = nodes[reached_node].predecessor; nodes[current_node].distance > 0; current_node = nodes[current_node].predecessor)
142  {
143  size_t next_node = nodes[current_node].predecessor;
144  if (nodes[current_node].distance > 1 && dimensions.is_row(current_node))
145  {
146  assert (dimensions.is_column(next_node));
147 
148  matroid_binary_pivot(matroid, matrix, dimensions.index_to_row(current_node), dimensions.index_to_column(next_node));
149  extra_elements.insert(matroid.name1(dimensions.index_to_row(current_node)));
150  extra_elements.insert(matroid.name2(dimensions.index_to_column(next_node)));
151  }
152  else if (nodes[current_node].distance == 1)
153  {
154  connecting_row = dimensions.index_to_row(current_node);
155  starting_column = dimensions.index_to_column(next_node);
156  }
157  }
158 
160  matroid_permute1(matroid, matrix, connecting_row, split.first - 1);
161  if (starting_column > reached_column)
162  std::swap(starting_column, reached_column);
163  matroid_permute2(matroid, matrix, reached_column, split.second - 1);
164  matroid_permute2(matroid, matrix, starting_column, split.second - 2);
165  }
166 
177  template <typename MatroidType, typename MatrixType>
178  inline void find_row_witnesses(MatroidType& matroid, MatrixType& matrix, size_pair_t split, matroid_element_set& extra_elements)
179  {
180  binary_linear_space vector_space(split.second);
181  binary_linear_space::vector_type vector(split.second);
182  std::vector <size_t> type(matroid.size1() - split.first);
183 
184  typedef std::set <size_t> row_set_t;
185  row_set_t types[4];
186 
188  empty_bottom_left_modifier modifier(split);
189  matrix_modified <MatrixType, empty_bottom_left_modifier> modified_matrix(matrix, modifier);
190  bipartite_graph_dimensions dimensions(modified_matrix.size1(), modified_matrix.size2());
191 
192  for (size_t row = split.first; row < matrix.size1(); ++row)
193  {
194  copy_partial_row(matrix, vector, row, 0, split.second);
195  vector_space.insert_checked(vector);
196  size_t type = vector_space.find(vector);
197  assert (type < 4);
198  types[type].insert(dimensions.row_to_index(row));
199  }
200 
201  size_t reached_node;
202  size_t reached_row = 0;
203  size_t starting_row = 0;
204  size_t connecting_column = 0;
205 
207  std::vector <bipartite_graph_bfs_node> nodes;
208  row_set_t start_nodes = types[1];
209  row_set_t end_nodes = types[2];
210  std::copy(types[3].begin(), types[3].end(), std::inserter(end_nodes, end_nodes.end()));
211 
212  if (bipartite_graph_bfs(modified_matrix, dimensions, start_nodes, end_nodes, false, nodes))
213  {
215  reached_node = 0;
216  for (row_set_t::const_iterator iter = end_nodes.begin(); iter != end_nodes.end(); ++iter)
217  {
218  if (nodes[*iter].is_reachable())
219  {
220  reached_node = *iter;
221  break;
222  }
223  }
224  }
225  else if (bipartite_graph_bfs(modified_matrix, dimensions, types[2], types[3], false, nodes))
226  {
228  reached_node = 0;
229  for (row_set_t::const_iterator iter = types[3].begin(); iter != types[3].end(); ++iter)
230  {
231  if (nodes[*iter].is_reachable())
232  {
233  reached_node = *iter;
234  break;
235  }
236  }
237  }
238  else
239  {
240  throw std::runtime_error("tu::find_row_witnesses failed to find paths between rows of different type.");
241  }
242 
244  reached_row = dimensions.index_to_row(reached_node);
245  for (size_t current_node = nodes[reached_node].predecessor; nodes[current_node].distance > 0; current_node = nodes[current_node].predecessor)
246  {
247  size_t next_node = nodes[current_node].predecessor;
248  if (nodes[current_node].distance > 1 && dimensions.is_column(current_node))
249  {
250  assert (dimensions.is_row(next_node));
251 
252  matroid_binary_pivot(matroid, matrix, dimensions.index_to_row(next_node), dimensions.index_to_column(current_node));
253  extra_elements.insert(matroid.name1(dimensions.index_to_row(next_node)));
254  extra_elements.insert(matroid.name2(dimensions.index_to_column(current_node)));
255  }
256  else if (nodes[current_node].distance == 1)
257  {
258  connecting_column = dimensions.index_to_column(current_node);
259  starting_row = dimensions.index_to_row(next_node);
260  }
261  }
262 
263  matroid_permute2(matroid, matrix, connecting_column, split.second);
264  if (starting_row < reached_row)
265  std::swap(starting_row, reached_row);
266  matroid_permute1(matroid, matrix, reached_row, split.first);
267  matroid_permute1(matroid, matrix, starting_row, split.first + 1);
268  }
269 
280  template <typename MatroidType, typename MatrixType>
281  inline separation find_witnesses(MatroidType& matroid, MatrixType& matrix, size_pair_t split, matroid_element_set& extra_elements)
282  {
283  find_column_witnesses(matroid, matrix, split, extra_elements);
284  find_row_witnesses(matroid, matrix, split, extra_elements);
285 
286  if (matrix(split.first, split.second - 2) == 0 || matrix(split.first + 1, split.second - 1) == 0)
287  matroid_permute1(matroid, matrix, split.first, split.first + 1);
288 
289  return separation(split, separation::witness_type(split.first, split.second - 2), separation::witness_type(split.first + 1, split.second - 1));
290  }
291 
300  template <typename MatroidType, typename MatrixType>
301  inline void pivot_top_right(MatroidType& matroid, MatrixType& matrix, size_pair_t& split, matroid_element_set& extra_elements)
302  {
303  for (size_t row = 0; row < split.first; ++row)
304  {
305  for (size_t column = split.second; column < matrix.size2(); ++column)
306  {
307  if (matrix(row, column) != 0)
308  {
309  matroid_binary_pivot(matroid, matrix, row, column);
310  extra_elements.insert(matroid.name1(row));
311  extra_elements.insert(matroid.name2(column));
312  matroid_permute1(matroid, matrix, row, split.first - 1);
313  matroid_permute2(matroid, matrix, column, split.second);
314  split.first--;
315  split.second++;
316  return;
317  }
318  }
319  }
320  }
321 
330  template <typename MatroidType, typename MatrixType>
331  inline void pivot_bottom_left(MatroidType& matroid, MatrixType& matrix, size_pair_t& split, matroid_element_set& extra_elements)
332  {
333  for (size_t row = split.first; row < matrix.size1(); ++row)
334  {
335  for (size_t column = 0; column < split.second; ++column)
336  {
337  if (matrix(row, column) != 0)
338  {
339  matroid_binary_pivot(matroid, matrix, row, column);
340  extra_elements.insert(matroid.name1(row));
341  extra_elements.insert(matroid.name2(column));
342  matroid_permute1(matroid, matrix, row, split.first);
343  matroid_permute2(matroid, matrix, column, split.second - 1);
344  split.first++;
345  split.second--;
346  return;
347  }
348  }
349  }
350  }
351 
362  template <typename MatroidType, typename MatrixType>
363  inline void normalize_3_4_separation(MatroidType& matroid, MatrixType& matrix, size_pair_t& split, rank_distribution ranks,
364  matroid_element_set& extra_elements)
365  {
366  if (ranks == RANK_BL_2_TR_0)
367  pivot_bottom_left(matroid, matrix, split, extra_elements);
368  else if (ranks == RANK_BL_0_TR_2)
369  pivot_top_right(matroid, matrix, split, extra_elements);
370 
372  if (2 * split.first < matroid.size1())
373  {
374  for (size_t row = 0; row < matroid.size1() / 2; ++row)
375  matroid_permute1(matroid, matrix, row, matroid.size1() - 1 - row);
376  for (size_t column = 0; column < matroid.size2() / 2; ++column)
377  matroid_permute2(matroid, matrix, column, matroid.size2() - 1 - column);
378  split = size_pair_t(matroid.size1() - split.first, matroid.size2() - split.second);
379  }
380 
382  pivot_top_right(matroid, matrix, split, extra_elements);
383  }
384 
398  template <typename MatroidType, typename MatrixType>
399  inline bool extend_to_3_4_separation(MatroidType& matroid, MatrixType& matrix, matrix_permuted <const integer_matrix>& worker_matrix,
400  size_pair_t top_left_size, size_pair_t bottom_right_size, separation& separation, matroid_element_set& extra_elements)
401  {
402  rank_distribution ranks =
403  partition(worker_matrix, top_left_size.first, top_left_size.second, bottom_right_size.first, bottom_right_size.second);
404  if (ranks == RANK_TOO_HIGH)
405  return false;
406 
407  if (top_left_size.first + top_left_size.second < 4 || bottom_right_size.first + bottom_right_size.second < 4)
408  {
409  return false;
410  }
411 
413  permutation perm1 = matrix_get_perm1(matrix);
414  permutation perm2 = matrix_get_perm2(matrix);
415  permutation row_permutation = perm1 * worker_matrix.perm1();
416  permutation column_permutation = perm2 * worker_matrix.perm2();
417 
418  matrix_set_perm1(matrix, row_permutation);
419  matrix_set_perm2(matrix, column_permutation);
420  matroid_set_perm1(matroid, row_permutation);
421  matroid_set_perm2(matroid, column_permutation);
422 
423  assert (matrix_equals(matrix, worker_matrix));
424 
426  normalize_3_4_separation(matroid, matrix, top_left_size, ranks, extra_elements);
427 
429  separation = find_witnesses(matroid, matrix, top_left_size, extra_elements);
430 
431  return true;
432  }
433 
443  template <typename MappingValue>
444  inline size_pair_t apply_mapping(permutation& permutation, std::vector <MappingValue>& mapping)
445  {
446  vector_less <MappingValue> less(mapping);
447  sort(permutation, less);
448 
449  size_t negative = 0;
450  while (negative < permutation.size() && mapping[permutation(negative)] < 0)
451  ++negative;
452 
453  size_t positive = 0;
454  while (positive < permutation.size() && mapping[permutation(permutation.size() - 1 - positive)] > 0)
455  ++positive;
456 
457  return std::make_pair(negative, positive);
458  }
459 
468  template <typename NestedMinorSequence>
469  inline size_t find_first_7_element_minor(const NestedMinorSequence& nested_minors, size_pair_t& minor_size)
470  {
471  size_t current_height = 3;
472  size_t current_width = 3;
473  for (size_t i = 0; i < nested_minors.size(); ++i)
474  {
475  if (current_height + current_width >= 8)
476  {
477  minor_size = std::make_pair(current_height, current_width);
478  return i;
479  }
480  current_height += nested_minors.get_extension_height(i);
481  current_width += nested_minors.get_extension_width(i);
482  }
483 
484  assert (current_height + current_width >= 8);
485 
486  minor_size = std::make_pair(current_height, current_width);
487  return nested_minors.size();
488  }
489 
515  template <typename MatroidType, typename MatrixType, typename MappingValue>
516  inline bool enumerate_extension(MatroidType& matroid, MatrixType& matrix, matrix_permuted <const integer_matrix>& worker_matrix, std::vector <
517  MappingValue>& row_mapping, std::vector <MappingValue>& column_mapping, size_pair_t minor_size, size_t ext_height, size_t ext_width,
518  separation& separation, matroid_element_set& extra_elements, unsigned long long& enumeration, unsigned long long& next_enumeration,
519  unsigned long long max_enumerations, unsigned int& next_percent, logger& log, size_t cut)
520  {
521  const size_t minor_length = minor_size.first + minor_size.second;
522  const size_t ext_length = ext_height + ext_width;
523 
524  for (size_t minor_enum_iter = 0; minor_enum_iter <= minor_length; ++minor_enum_iter)
525  {
527  bool minor_enum_is_row = minor_enum_iter < minor_size.first;
528  bool minor_enum_is_column = !minor_enum_is_row && minor_enum_iter != minor_length;
529  size_t minor_enum_index = minor_enum_is_column ? minor_enum_iter - minor_size.first : minor_enum_iter;
530 
531  for (size_t bits = 1; bits < (size_t) (1 << ext_length); ++bits)
532  {
534  std::fill(row_mapping.begin(), row_mapping.begin() + minor_size.first + ext_height, 1);
535  std::fill(row_mapping.begin() + minor_size.first + ext_height, row_mapping.end(), 0);
536  std::fill(column_mapping.begin(), column_mapping.begin() + minor_size.second + ext_width, 1);
537  std::fill(column_mapping.begin() + minor_size.second + ext_width, column_mapping.end(), 0);
538 
540  size_t num_enumerated = 1;
541  if (minor_enum_is_row)
542  row_mapping[minor_enum_index] = -1;
543  else if (minor_enum_is_column)
544  column_mapping[minor_enum_index] = -1;
545  else
546  num_enumerated = 0;
547 
549  for (size_t ext_enum_iter = 0; ext_enum_iter < ext_length; ++ext_enum_iter)
550  {
551  if (((bits >> ext_enum_iter) & 1) == 1)
552  {
553  ++num_enumerated;
554  if (ext_enum_iter < ext_height)
555  row_mapping[minor_size.first + ext_enum_iter] = -1;
556  else
557  column_mapping[minor_size.second + ext_enum_iter - ext_height] = -1;
558  }
559  }
560 
561  if (num_enumerated < 2)
562  continue;
563 
565  size_pair_t heights = detail::apply_mapping(worker_matrix.perm1(), row_mapping);
566  size_pair_t widths = detail::apply_mapping(worker_matrix.perm2(), column_mapping);
567 
568  ++enumeration;
569 
570  if (log.is_progressive() && enumeration == next_enumeration)
571  {
572  log.erase(cut);
573  log.line() << next_percent << "%";
574  std::cout << log;
575  next_percent++;
576  next_enumeration = (max_enumerations * next_percent) / 100;
577  }
578 
579  if (detail::extend_to_3_4_separation(matroid, matrix, worker_matrix, size_pair_t(heights.first, widths.first), size_pair_t(heights.second,
580  widths.second), separation, extra_elements))
581  {
582  return true;
583  }
584  }
585  }
586 
587  return false;
588  }
589 
590  }
591 
603  template <typename MatroidType, typename MatrixType, typename NestedMinorSequence>
604  inline separation enumerate_separations(MatroidType& matroid, MatrixType& matrix, const NestedMinorSequence& nested_minors,
605  matroid_element_set& extra_elements, logger& log)
606  {
607  typedef signed char mapping_value_t;
608 
610  if (matrix.size1() + matrix.size2() < 12)
611  {
612  if (log.is_progressive())
613  {
614  log.line() << ", TOO SMALL --> IRREGULAR";
615  std::cout << log << std::endl;
616  log.clear();
617  }
618  else if (log.is_verbose())
619  {
620  std::cout << "Matroid is too small to contain a (3|4)-separation and must be irregular." << std::endl;
621  }
622 
623  return separation();
624  }
625 
627  size_pair_t minor_size;
628  size_t minor_index = detail::find_first_7_element_minor(nested_minors, minor_size);
629  assert(minor_size.first + minor_size.second >= 8);
630  assert(minor_size.first + minor_size.second <= 10);
631 
633  const integer_matrix worker_matrix_base(matrix);
634 
635  matrix_permuted <const integer_matrix> worker_matrix(worker_matrix_base);
636  std::vector <mapping_value_t> row_mapping(worker_matrix_base.size1(), 0);
637  std::vector <mapping_value_t> column_mapping(worker_matrix_base.size2(), 0);
638  separation result;
639 
640  unsigned long long enumeration = 0;
641 
643  size_t cut = 0, full_cut = 0;
644  unsigned long long max_enumerations = 0;
645 
646  if (log.is_progressive() || log.is_verbose())
647  {
648  max_enumerations = 1L << (minor_size.first + minor_size.second);
649  size_t h = minor_size.first;
650  size_t w = minor_size.second;
651  for (size_t i = minor_index; i < nested_minors.size(); ++i)
652  {
653  switch (nested_minors.get_extension(i))
654  {
657  max_enumerations += h + w;
658  break;
660  max_enumerations += 3 * (h + w) + 1;
661  break;
664  max_enumerations += 7 * (h + w) + 4;
665  break;
666  default:
667  assert (false);
668  }
669  h += nested_minors.get_extension_height(i);
670  w += nested_minors.get_extension_width(i);
671  }
672 
673  if (log.is_progressive())
674  {
675  full_cut = log.size();
676  log.line() << ", ENUMERATING " << max_enumerations << " PARTITIONS: ";
677  cut = log.size();
678  log.line() << "0%";
679  std::cout << log;
680  }
681  else if (log.is_verbose())
682  {
683  std::cout << "Enumerating " << max_enumerations << " partitions along the sequence." << std::endl;
684  }
685  }
686 
687  unsigned long long next_enumeration = max_enumerations / 100;
688  unsigned int next_percent = 1;
689 
691  size_t limit = (1 << (minor_size.first + minor_size.second));
692  for (size_t bits = 0; bits < limit; ++bits)
693  {
694  ++enumeration;
695 
696  for (size_t row = 0; row < minor_size.first; ++row)
697  {
698  row_mapping[row] = ((bits >> row) & 0x1) ? 1 : -1;
699  }
700  for (size_t column = 0; column < minor_size.second; ++column)
701  {
702  column_mapping[column] = ((bits >> (minor_size.first + column)) & 0x1) ? 1 : -1;
703  }
704 
706  size_pair_t widths = detail::apply_mapping(worker_matrix.perm2(), column_mapping);
707  size_pair_t heights = detail::apply_mapping(worker_matrix.perm1(), row_mapping);
708 
709  if (detail::extend_to_3_4_separation(matroid, matrix, worker_matrix, size_pair_t(heights.first, widths.first), size_pair_t(heights.second,
710  widths.second), result, extra_elements))
711  {
712  return result;
713  }
714 
715  if (log.is_progressive() && enumeration == next_enumeration)
716  {
717  log.erase(cut);
718  log.line() << next_percent << '%';
719  std::cout << log;
720  next_percent++;
721  next_enumeration = (max_enumerations * next_percent) / 100;
722  }
723  }
724 
725  if (log.is_verbose())
726  {
727  std::cout << "Complete enumeration of " << (minor_index + 1) << " minors done." << std::endl;
728  }
729 
731  for (size_t i = minor_index; i < nested_minors.size(); ++i)
732  {
733  size_t extension_height = nested_minors.get_extension_height(i);
734  size_t extension_width = nested_minors.get_extension_width(i);
735  if (detail::enumerate_extension(matroid, matrix, worker_matrix, row_mapping, column_mapping, minor_size, extension_height, extension_width,
736  result, extra_elements, enumeration, next_enumeration, max_enumerations, next_percent, log, cut))
737  {
738  return result;
739  }
740  minor_size.first += extension_height;
741  minor_size.second += extension_width;
742 
743  if (log.is_verbose())
744  {
745  std::cout << "Clever enumeration done for nested minor " << (i + 2) << "." << std::endl;
746  }
747  }
748 
749  if (log.is_progressive())
750  {
751  log.erase(full_cut);
752  log.line() << ", ENUMERATED " << enumeration << " PARTITIONS --> IRREGULAR";
753  std::cout << log << std::endl;
754  log.clear();
755  }
756 
757  if (log.is_verbose())
758  {
759  std::cout << "Matroid does not contain a (3|4)-separation and must be irregular." << std::endl;
760  }
761 
762  return separation();
763  }
764 
777 } /* namespace tu */
Definition: binary_linear_space.hpp:16
std::vector< bool > vector_type
Definition: binary_linear_space.hpp:19
bool insert_checked(const vector_type &vector)
Definition: binary_linear_space.hpp:96
int find(const vector_type &vector) const
Definition: binary_linear_space.hpp:133
Definition: logger.hpp:19
void clear()
Definition: logger.hpp:98
bool is_progressive() const
Definition: logger.hpp:67
std::stringstream & line()
Definition: logger.hpp:131
bool is_verbose() const
Definition: logger.hpp:58
size_t size() const
Definition: logger.hpp:108
void erase(size_t position)
Definition: logger.hpp:119
Definition: matrix_modified.hpp:14
size_type size1() const
Definition: matrix_modified.hpp:52
size_type size2() const
Definition: matrix_modified.hpp:61
Definition: matrix_permuted.hpp:17
const permutation_type & perm2() const
Definition: matrix_permuted.hpp:92
const permutation_type & perm1() const
Definition: matrix_permuted.hpp:74
Definition: matroid.hpp:22
size_t size1() const
Definition: matroid.hpp:77
size_t size2() const
Definition: matroid.hpp:86
name_type & name2(size_t index)
Definition: matroid.hpp:116
name_type & name1(size_t index)
Definition: matroid.hpp:96
@ ONE_ROW_ONE_COLUMN
Definition: nested_minor_sequence.hpp:28
@ ONE_ROW
Definition: nested_minor_sequence.hpp:26
@ TWO_ROWS_ONE_COLUMN
Definition: nested_minor_sequence.hpp:29
@ ONE_COLUMN
Definition: nested_minor_sequence.hpp:30
@ ONE_ROW_TWO_COLUMNS
Definition: nested_minor_sequence.hpp:27
Definition: permutations.hpp:44
size_type size() const
Definition: permutations.hpp:150
Definition: separation.hpp:18
std::pair< std::size_t, std::size_t > witness_type
Definition: separation.hpp:21
separation find_witnesses(MatroidType &matroid, MatrixType &matrix, size_pair_t split, matroid_element_set &extra_elements)
Definition: enumeration.hpp:281
void copy_partial_column(const MatrixType &matrix, VectorType &vector, size_t column, size_t first_row, size_t beyond_row)
Definition: partition.hpp:48
void find_row_witnesses(MatroidType &matroid, MatrixType &matrix, size_pair_t split, matroid_element_set &extra_elements)
Definition: enumeration.hpp:178
void find_column_witnesses(MatroidType &matroid, MatrixType &matrix, size_pair_t split, matroid_element_set &extra_elements)
Definition: enumeration.hpp:73
bool extend_to_3_4_separation(MatroidType &matroid, MatrixType &matrix, matrix_permuted< const integer_matrix > &worker_matrix, size_pair_t top_left_size, size_pair_t bottom_right_size, separation &separation, matroid_element_set &extra_elements)
Definition: enumeration.hpp:399
void pivot_top_right(MatroidType &matroid, MatrixType &matrix, size_pair_t &split, matroid_element_set &extra_elements)
Definition: enumeration.hpp:301
void copy_partial_row(const MatrixType &matrix, VectorType &vector, size_t row, size_t first_column, size_t beyond_column)
Definition: partition.hpp:28
void normalize_3_4_separation(MatroidType &matroid, MatrixType &matrix, size_pair_t &split, rank_distribution ranks, matroid_element_set &extra_elements)
Definition: enumeration.hpp:363
void pivot_bottom_left(MatroidType &matroid, MatrixType &matrix, size_pair_t &split, matroid_element_set &extra_elements)
Definition: enumeration.hpp:331
size_t find_first_7_element_minor(const NestedMinorSequence &nested_minors, size_pair_t &minor_size)
Definition: enumeration.hpp:469
bool enumerate_extension(MatroidType &matroid, MatrixType &matrix, matrix_permuted< const integer_matrix > &worker_matrix, std::vector< MappingValue > &row_mapping, std::vector< MappingValue > &column_mapping, size_pair_t minor_size, size_t ext_height, size_t ext_width, separation &separation, matroid_element_set &extra_elements, unsigned long long &enumeration, unsigned long long &next_enumeration, unsigned long long max_enumerations, unsigned int &next_percent, logger &log, size_t cut)
Definition: enumeration.hpp:516
size_pair_t apply_mapping(permutation &permutation, std::vector< MappingValue > &mapping)
Definition: enumeration.hpp:444
Definition: algorithm.hpp:14
permutation matrix_get_perm2(matrix_permuted< MatrixType > &matrix)
Definition: matrix_permuted.hpp:236
void sort(permutation &permutation, size_t first, size_t beyond, Less &less)
Definition: permutations.hpp:583
std::pair< size_t, size_t > size_pair_t
Definition: partition.hpp:12
bool bipartite_graph_bfs(const MatrixType &matrix, const bipartite_graph_dimensions &dimensions, const StartNodesContainerType &start_nodes, const EndNodesContainerType &end_nodes, bool reach_all, std::vector< bipartite_graph_bfs_node > &result)
Definition: bipartite_graph_bfs.hpp:182
rank_distribution
Definition: partition.hpp:59
@ RANK_TOO_HIGH
Definition: partition.hpp:60
@ RANK_BL_2_TR_0
Definition: partition.hpp:60
@ RANK_BL_0_TR_2
Definition: partition.hpp:60
permutation matrix_get_perm1(matrix_permuted< MatrixType > &matrix)
Definition: matrix_permuted.hpp:230
void matroid_permute1(matroid< NameType > &matroid, size_t index1, size_t index2)
Definition: matroid.hpp:162
void matrix_set_perm1(matrix_permuted< MatrixType > &matrix, const permutation &permutation)
Definition: matrix_permuted.hpp:254
void matroid_permute2(matroid< NameType > &matroid, size_t index1, size_t index2)
Definition: matroid.hpp:192
rank_distribution partition(matrix_permuted< const MatrixType > &matrix, size_t &top_left_height, size_t &top_left_width, size_t &bottom_right_height, size_t &bottom_right_width)
Definition: partition.hpp:76
boost::numeric::ublas::matrix< long long > integer_matrix
Definition: common.hpp:27
void matrix_set_perm2(matrix_permuted< MatrixType > &matrix, const permutation &permutation)
Definition: matrix_permuted.hpp:260
void matroid_set_perm1(matroid_permuted< MatroidType > &matroid, const permutation &permutation)
Definition: matroid_permuted.hpp:190
separation enumerate_separations(MatroidType &matroid, MatrixType &matrix, const NestedMinorSequence &nested_minors, matroid_element_set &extra_elements, logger &log)
Definition: enumeration.hpp:604
void matroid_binary_pivot(matroid< NameType > &matroid, size_t i, size_t j)
Definition: matroid.hpp:222
void matroid_set_perm2(matroid_permuted< MatroidType > &matroid, const permutation &permutation)
Definition: matroid_permuted.hpp:196
std::set< int > matroid_element_set
Definition: matroid_decomposition.hpp:19
Definition: bipartite_graph_bfs.hpp:39
bool is_row(index_type index) const
Definition: bipartite_graph_bfs.hpp:88
size_t index_to_column(index_type index) const
Definition: bipartite_graph_bfs.hpp:119
index_type column_to_index(size_t column) const
Definition: bipartite_graph_bfs.hpp:140
index_type row_to_index(size_t row) const
Definition: bipartite_graph_bfs.hpp:130
size_t index_to_row(index_type index) const
Definition: bipartite_graph_bfs.hpp:108
bool is_column(index_type index) const
Definition: bipartite_graph_bfs.hpp:98
Definition: enumeration.hpp:25
empty_bottom_left_modifier(size_pair_t split)
Definition: enumeration.hpp:34
value_type operator()(size_t i, size_t j, value_type value)
Definition: enumeration.hpp:49
int value_type
Definition: enumeration.hpp:26
Definition: comparators.hpp:108