Skip to content

Commit 0b03858

Browse files
authored
Replace Simplex with KACTL-based lp_solver (#84)
1 parent e07d025 commit 0b03858

2 files changed

Lines changed: 98 additions & 46 deletions

File tree

Lines changed: 98 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,104 @@
11
/*
2-
*Description:* Optimizes linear function, based of linear restrictions, in $O(n^2)$
3-
*Status:* Not tested
2+
*Author:* KACTL Based
3+
*Description:* Solves a general linear maximization problem:
4+
maximize $c^T x$ subject to $A x <= b$, $x >= 0$.
5+
Returns $-infinity$ if infeasible, $infinity$ if unbounded,
6+
or the maximum value of $c^T x$ otherwise.
7+
The input vector is set to an optimal $x$ (or in the unbounded
8+
case, an arbitrary solution fulfilling the constraints).
9+
Numerical stability is not guaranteed. For better performance,
10+
define variables such that $x = 0$ is viable.
11+
*Time:* $O(n m dot "pivots")$ per pivot. $O(2^n)$ worst case,
12+
fast in practice.
13+
*Usage:*
14+
`lp_solver<double> lp(A, b, c);`
15+
`vector<double> x;`
16+
`double val = lp.solve(x);`
17+
*Status:* Tested
418
*/
5-
template<class T> struct Simplex {
6-
T ans;
7-
vector<vector<T>> a;
8-
vector<T> b,c,d;
9-
void pivot(int ii, int jj){
10-
d[ii] = c[jj];
11-
T s1 = a[ii][jj];
12-
for (int i = 0; i < a[0].size(); i++)
13-
a[ii][i] /= s1;
14-
b[ii] /= s1;
15-
for (int i = 0; i < d.size(); i++){
16-
if (i == ii || a[i][jj] == 0) continue;
17-
T s2 = a[i][jj];
18-
for (int j = 0; j < a[0].size(); j++)
19-
a[i][j] -= s2*a[ii][j];
20-
b[i] -= s2*b[ii];
21-
}
19+
template<class T>
20+
struct lp_solver {
21+
T eps = 1e-8, inf = 1e18;
22+
int m, n;
23+
vector<int> N, B;
24+
vector<vector<T>> D;
25+
26+
lp_solver(vector<vector<T>> A, vector<T> b, vector<T> c)
27+
: m(b.size()), n(c.size()),
28+
N(n + 1), B(m), D(m + 2, vector<T>(n + 2)) {
29+
for (int i = 0; i < m; i++)
30+
for (int j = 0; j < n; j++)
31+
D[i][j] = A[i][j];
32+
for (int i = 0; i < m; i++)
33+
B[i] = n + i, D[i][n] = -1, D[i][n + 1] = b[i];
34+
iota(N.begin(), N.end() - 1, 0);
35+
for (int j = 0; j < n; j++)
36+
D[m][j] = -c[j];
37+
N[n] = -1;
38+
D[m + 1][n] = 1;
39+
}
40+
41+
void pivot(int r, int s) {
42+
T *a = D[r].data(), inv = 1 / a[s];
43+
for (int i = 0; i < m + 2; i++) {
44+
if (i == r || abs(D[i][s]) <= eps) continue;
45+
T *b = D[i].data(), inv2 = b[s] * inv;
46+
for (int j = 0; j < n + 2; j++)
47+
b[j] -= a[j] * inv2;
48+
b[s] = a[s] * inv2;
2249
}
23-
bool next_point(){
24-
int idx = -1; T mx;
25-
for (int i = 0; i < (int)a[0].size(); i++){
26-
T z = 0;
27-
for (int j = 0; j < (int)d.size(); j++)
28-
z += a[j][i]*d[j];
29-
if (idx == -1 || mx < c[i]-z)
30-
mx = c[i]-z, idx = i;
31-
}
32-
if (mx > 0){
33-
int idx2 = -1; T mn;
34-
for (int i = 0; i < (int)b.size(); i++){
35-
if (a[i][idx] == 0 || b[i]/a[i][idx] <= 0) continue;
36-
if (idx2 == -1 || mn > b[i]/a[i][idx])
37-
mn = b[i]/a[i][idx], idx2 = i;
38-
}
39-
if (idx2 == -1) return 0; // unbounded
40-
pivot(idx2,idx);
41-
return 1;
42-
}
43-
return 0;
50+
for (int j = 0; j < n + 2; j++)
51+
if (j != s) D[r][j] *= inv;
52+
for (int i = 0; i < m + 2; i++)
53+
if (i != r) D[i][s] *= -inv;
54+
D[r][s] = inv;
55+
swap(B[r], N[s]);
56+
}
57+
58+
int sel(int lo, int hi, vector<T> &row, int phase = 0) {
59+
int s = -1;
60+
for (int j = lo; j < hi; j++)
61+
if (N[j] != -phase)
62+
if (s == -1 || pair{row[j], N[j]} < pair{row[s], N[s]})
63+
s = j;
64+
return s;
65+
}
66+
67+
bool simplex(int phase) {
68+
int x = m + phase - 1;
69+
for (;;) {
70+
int s = sel(0, n + 1, D[x], phase);
71+
if (D[x][s] >= -eps) return true;
72+
int r = -1;
73+
for (int i = 0; i < m; i++) {
74+
if (D[i][s] <= eps) continue;
75+
if (r == -1 ||
76+
pair{D[i][n+1] / D[i][s], B[i]} <
77+
pair{D[r][n+1] / D[r][s], B[r]})
78+
r = i;
79+
}
80+
if (r == -1) return false;
81+
pivot(r, s);
4482
}
45-
Simplex(vector<vector<T>> & _a, vector<T> & _b, vector<T> & _c) : a(_a),b(_b),c(_c){
46-
d.resize(b.size(),0);
47-
while (next_point());
48-
ans = 0;
49-
for (int i = 0; i < b.size(); i++)
50-
ans += b[i]*d[i];
83+
}
84+
85+
T solve(vector<T> &x) {
86+
int r = 0;
87+
for (int i = 1; i < m; i++)
88+
if (D[i][n + 1] < D[r][n + 1]) r = i;
89+
if (D[r][n + 1] < -eps) {
90+
pivot(r, n);
91+
if (!simplex(2) || D[m + 1][n + 1] < -eps)
92+
return -inf;
93+
for (int i = 0; i < m; i++)
94+
if (B[i] == -1)
95+
pivot(i, sel(0, n + 1, D[i]));
5196
}
97+
bool ok = simplex(1);
98+
x.assign(n, 0);
99+
for (int i = 0; i < m; i++)
100+
if (B[i] < n)
101+
x[B[i]] = D[i][n + 1];
102+
return ok ? D[m][n + 1] : inf;
103+
}
52104
};

main-wf.pdf

323 KB
Binary file not shown.

0 commit comments

Comments
 (0)