OR-Tools  9.6
symmetry_util.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_SAT_SYMMETRY_UTIL_H_
15 #define OR_TOOLS_SAT_SYMMETRY_UTIL_H_
16 
17 #include <memory>
18 #include <vector>
19 
21 
22 namespace operations_research {
23 namespace sat {
24 
25 // Given the generator for a permutation group of [0, n-1], tries to identify
26 // a grouping of the variables in an p x q matrix such that any permutations
27 // of the columns of this matrix is in the given group.
28 //
29 // The name comes from: "Packing and Partitioning Orbitopes", Volker Kaibel,
30 // Marc E. Pfetsch, https://arxiv.org/abs/math/0603678 . Here we just detect it,
31 // independently of the constraints on the variables in this matrix. We can also
32 // detect non-Boolean orbitope.
33 //
34 // In order to detect orbitope, this basic algorithm requires that the
35 // generators of the orbitope must only contain one or more 2-cyle (i.e
36 // transpositions). Thus they must be involutions. The list of transpositions in
37 // the SparsePermutation must also be listed in a canonical order.
38 //
39 // TODO(user): Detect more than one orbitope? Note that once detected, the
40 // structure can be exploited efficiently, but for now, a more "generic"
41 // algorithm based on stabilizator should achieve the same preprocessing power,
42 // so I don't know how hard we need to invest in orbitope detection.
43 //
44 // TODO(user): The heuristic is quite limited for now, but this works on
45 // graph20-20-1rand.mps.gz. I suspect the generators provided by the detection
46 // code follow our preconditions.
47 std::vector<std::vector<int>> BasicOrbitopeExtraction(
48  const std::vector<std::unique_ptr<SparsePermutation>>& generators);
49 
50 // Returns a vector of size n such that
51 // - orbits[i] == -1 iff i is never touched by the generators (singleton orbit).
52 // - orbits[i] = orbit_index, where orbits are numbered from 0 to num_orbits - 1
53 //
54 // TODO(user): We could reuse the internal memory if needed.
55 std::vector<int> GetOrbits(
56  int n, const std::vector<std::unique_ptr<SparsePermutation>>& generators);
57 
58 // Returns the orbits under the given orbitope action.
59 // Same results format as in GetOrbits(). Note that here, the orbit index
60 // is simply the row index of an element in the orbitope matrix.
61 std::vector<int> GetOrbitopeOrbits(
62  int n, const std::vector<std::vector<int>>& orbitope);
63 
64 // Given the generators for a permutation group of [0, n-1], update it to
65 // a set of generators of the group stabilizing the given element.
66 //
67 // Note that one can add symmetry breaking constraints by repeatedly doing:
68 // 1/ Call GetOrbits() using the current set of generators.
69 // 2/ Choose an element x0 in a large orbit (x0, .. xi ..) , and add x0 >= xi
70 // for all i.
71 // 3/ Update the set of generators to the one stabilizing x0.
72 //
73 // This is more or less what is described in "Symmetry Breaking Inequalities
74 // from the Schreier-Sims Table", Domenico Salvagnin,
75 // https://link.springer.com/chapter/10.1007/978-3-319-93031-2_37
76 //
77 // TODO(user): Implement!
79  int to_stabilize,
80  std::vector<std::unique_ptr<SparsePermutation>>* generators) {}
81 
82 } // namespace sat
83 } // namespace operations_research
84 
85 #endif // OR_TOOLS_SAT_SYMMETRY_UTIL_H_
std::vector< int > GetOrbitopeOrbits(int n, const std::vector< std::vector< int >> &orbitope)
void TransformToGeneratorOfStabilizer(int to_stabilize, std::vector< std::unique_ptr< SparsePermutation >> *generators)
Definition: symmetry_util.h:78
std::vector< std::vector< int > > BasicOrbitopeExtraction(const std::vector< std::unique_ptr< SparsePermutation >> &generators)
std::vector< int > GetOrbits(int n, const std::vector< std::unique_ptr< SparsePermutation >> &generators)
Collection of objects used to extend the Constraint Solver library.