1
1
#pragma once
2
+ #include < algorithm>
3
+ #include < chrono>
2
4
#include < cmath>
3
5
#include < numeric>
6
+ #include < random>
4
7
#include < vector>
5
8
6
9
// CUT begin
7
10
// Maximize cx s.t. Ax <= b, x >= 0
8
11
// Implementation idea: https://kopricky.github.io/code/Computation_Advanced/simplex.html
9
12
// Refer to https://hitonanode.github.io/cplib-cpp/combinatorial_opt/simplex.hpp
10
- template <typename Float = double , int DEPS = 30 > struct Simplex {
13
+ template <typename Float = double , int DEPS = 30 , bool Randomize = true > struct Simplex {
11
14
const Float EPS = Float(1.0 ) / (1LL << DEPS);
12
15
int N, M;
16
+ std::vector<int > shuffle_idx;
13
17
std::vector<int > idx;
14
18
std::vector<std::vector<Float>> mat;
15
19
int i_ch, j_ch;
@@ -35,7 +39,7 @@ template <typename Float = double, int DEPS = 30> struct Simplex {
35
39
inline Float abs_ (Float x) noexcept { return x > -x ? x : -x; }
36
40
void _solve () {
37
41
std::vector<int > jupd;
38
- for (j_ch = N;;) {
42
+ for (nb_iter = 0 , j_ch = N;; nb_iter++ ) {
39
43
if (i_ch < M) {
40
44
std::swap (idx[j_ch], idx[i_ch + N + 1 ]);
41
45
mat[i_ch][j_ch] = Float (1 ) / mat[i_ch][j_ch];
@@ -90,11 +94,38 @@ template <typename Float = double, int DEPS = 30> struct Simplex {
90
94
}
91
95
92
96
public:
93
- Simplex (const std::vector<std::vector<Float>> & A, const std::vector<Float> & b, const std::vector<Float> & c) {
97
+ Simplex (std::vector<std::vector<Float>> A, std::vector<Float> b, std::vector<Float> c) {
94
98
is_infty = infeasible = false ;
99
+
100
+ if (Randomize) {
101
+ std::mt19937 rng (std::chrono::steady_clock::now ().time_since_epoch ().count ());
102
+
103
+ std::vector<std::pair<std::vector<Float>, Float>> Abs;
104
+ for (unsigned i = 0 ; i < A.size (); i++) Abs.emplace_back (A[i], b[i]);
105
+ std::shuffle (Abs.begin (), Abs.end (), rng);
106
+ A.clear (), b.clear ();
107
+ for (auto &&Ab : Abs) A.emplace_back (Ab.first ), b.emplace_back (Ab.second );
108
+
109
+ shuffle_idx.resize (c.size ());
110
+ std::iota (shuffle_idx.begin (), shuffle_idx.end (), 0 );
111
+ std::shuffle (shuffle_idx.begin (), shuffle_idx.end (), rng);
112
+ auto Atmp = A;
113
+ auto ctmp = c;
114
+ for (unsigned i = 0 ; i < A.size (); i++) {
115
+ for (unsigned j = 0 ; j < A[i].size (); j++) A[i][j] = Atmp[i][shuffle_idx[j]];
116
+ }
117
+ for (unsigned j = 0 ; j < c.size (); j++) c[j] = ctmp[shuffle_idx[j]];
118
+ }
119
+
95
120
_initialize (A, b, c);
96
121
_solve ();
122
+
123
+ if (Randomize) {
124
+ auto xtmp = x;
125
+ for (unsigned j = 0 ; j < c.size (); j++) x[shuffle_idx[j]] = xtmp[j];
126
+ }
97
127
}
128
+ unsigned nb_iter;
98
129
bool is_infty;
99
130
bool infeasible;
100
131
std::vector<Float> x;
0 commit comments