1
+ #include < bits/stdc++.h>
2
+ #include < vector>
3
+ #include < iomanip>
4
+ #include < limits>
5
+
6
+ using namespace std ;
7
+
8
+ class Simplex {
9
+ private:
10
+ int n, m, artificialCount;
11
+ vector<vector<double >> A;
12
+ vector<double > c;
13
+ vector<double > b;
14
+ vector<double > CB;
15
+ vector<int > B;
16
+ vector<double > delta;
17
+ const double M = 1e2 ; // Large penalty value
18
+ int extravar = 0 ;
19
+ set<int > arti_ind;
20
+
21
+ public:
22
+ Simplex (int variables, int constraints) : n(variables), m(constraints),
23
+ A (constraints, vector<double >(variables + constraints+constraints)),
24
+ c(variables + constraints + constraints), // c includes slack and artificial variables
25
+ b(constraints),
26
+ CB(constraints),
27
+ B(constraints),
28
+ delta(variables + constraints + constraints),
29
+ artificialCount(0 ) {}
30
+
31
+ void readInput () {
32
+ cout << " Enter the coefficients of the objective function: " ;
33
+ for (int i = 0 ; i < n; i++) {
34
+ cin >> c[i];
35
+ }
36
+
37
+ cout << " Enter the coefficients of the constraints:" << endl;
38
+ for (int i = 0 ; i < m; i++) {
39
+ for (int j = 0 ; j < n; j++) {
40
+ cin >> A[i][j];
41
+ }
42
+ }
43
+
44
+ vector<string> sign (m);
45
+ cout << " Enter >=/<=/=: " << endl;
46
+ for (int i = 0 ;i<m;i++) cin>>sign[i];
47
+
48
+ cout << " Enter the right-hand side of the constraints: " ;
49
+ for (int i = 0 ; i < m; i++) {
50
+ cin >> b[i];
51
+ if (b[i] < 0 ) {
52
+ b[i]*=-1 ;
53
+ for (int j = 0 ;j<n;j++){
54
+ A[i][j]*=-1 ;
55
+ }
56
+ if (sign[i]==" >=" ) sign[i] = " <=" ;
57
+ else if (sign[i]==" <=" ) sign[i] = " >=" ;
58
+ }
59
+ }
60
+
61
+ // Set up slack and artificial variables
62
+
63
+ for (int i = 0 ; i < m; i++) {
64
+ string constraintType = sign[i];
65
+
66
+ if (constraintType == " <=" ) {
67
+ // Slack variable
68
+ A[i][n + extravar] = 1.0 ; // Slack variable coefficient
69
+ c[n + extravar] = 0.0 ; // Slack variable in the objective function
70
+ B[i] = n + extravar; // Slack variables start as basic variables
71
+ CB[i] = 0.0 ; // Coefficient of slack variable in the objective
72
+ extravar++;
73
+ }
74
+ else if (constraintType == " =" ) {
75
+ // Artificial variable
76
+ A[i][n + extravar] = 1.0 ; // Artificial variable coefficient
77
+ c[n + extravar] = -M; // Penalty M in objective function
78
+ B[i] = n + extravar; // Artificial variable starts as basic
79
+ CB[i] = -M; // Artificial variable in the basis
80
+ artificialCount++;
81
+ arti_ind.insert (n+extravar);
82
+ extravar++;
83
+ }
84
+ else if (constraintType == " >=" ) {
85
+ // Surplus variable
86
+ A[i][n + extravar] = -1.0 ; // Surplus variable coefficient
87
+ c[n + extravar] = 0.0 ; // Surplus variable in objective function
88
+ extravar++;
89
+ // Artificial variable
90
+ A[i][n +extravar] = 1.0 ; // Artificial variable coefficient
91
+ c[n + extravar] = -M; // Penalty M in objective function
92
+ B[i] = n + extravar; // Artificial variable starts as basic
93
+ CB[i] = -M; // Artificial variable in the basis
94
+ artificialCount++;
95
+ arti_ind.insert (n+extravar);
96
+ extravar++;
97
+ }
98
+ }
99
+ }
100
+
101
+ void computeDelta () {
102
+ for (int j = 0 ; j < n +extravar; j++) {
103
+ double sum = 0.0 ;
104
+ for (int i = 0 ; i < m; i++) {
105
+ sum += CB[i] * A[i][j];
106
+ }
107
+ delta[j] = sum - c[j];
108
+ }
109
+ }
110
+
111
+ int findEnteringVariable () {
112
+ int entering = -1 ;
113
+ for (int j = 0 ; j < n + extravar; j++) {
114
+ if (delta[j] < 0 ) {
115
+ if (entering == -1 || delta[j] < delta[entering]) {
116
+ entering = j;
117
+ }
118
+ }
119
+ }
120
+ return entering;
121
+ }
122
+
123
+ int findLeavingVariable (int entering) {
124
+ int leaving = -1 ;
125
+ double minRatio = numeric_limits<double >::infinity (); // Use infinity for comparison
126
+ for (int i = 0 ; i < m; i++) {
127
+ if (A[i][entering] > 0 ) { // Check if pivot element is positive
128
+ double ratio = b[i] / A[i][entering];
129
+ if (ratio < minRatio || (ratio == minRatio && B[i] < B[leaving])) { // Handle degeneracy
130
+ minRatio = ratio;
131
+ leaving = i;
132
+ }
133
+ }
134
+ }
135
+ if (minRatio == numeric_limits<double >::infinity ()) {
136
+ cout << " Unbounded solution: no positive entries in the column of the entering variable." << endl;
137
+ return -1 ;
138
+ }
139
+ return leaving;
140
+ }
141
+
142
+ void pivot (int entering, int leaving) {
143
+ double pivotElement = A[leaving][entering];
144
+
145
+ // Normalize pivot row
146
+ for (int j = 0 ; j < n +extravar; j++) {
147
+ A[leaving][j] /= pivotElement;
148
+ }
149
+ b[leaving] /= pivotElement;
150
+
151
+ // Update other rows
152
+ for (int i = 0 ; i < m; i++) {
153
+ if (i != leaving) {
154
+ double factor = A[i][entering];
155
+ for (int j = 0 ; j < n +extravar; j++) {
156
+ A[i][j] -= factor * A[leaving][j];
157
+ }
158
+ b[i] -= factor * b[leaving];
159
+ }
160
+ }
161
+
162
+ // Update basis
163
+ B[leaving] = entering;
164
+ CB[leaving] = c[entering];
165
+ }
166
+
167
+ void printTable () {
168
+ cout << endl << " Simplex Table:" << endl;
169
+ cout << ' ' << " XB" << ' ' << " CB" ;
170
+ for (int j = 0 ; j < n + extravar; j++) {
171
+ cout << ' ' << " X" << j + 1 ;
172
+ }
173
+ cout << ' ' << " b" << endl;
174
+
175
+ for (int i = 0 ; i < m; i++) {
176
+
177
+ cout << ' ' << " X" << B[i] + 1 << ' ' ;
178
+ if (CB[i]==-100 ) cout<<" -M" ;
179
+ else cout<<CB[i];
180
+ for (int j = 0 ; j < n + extravar; j++) {
181
+ cout << ' ' << A[i][j];
182
+ }
183
+ cout << ' ' << b[i] << endl;
184
+ }
185
+
186
+ cout << " Δj: " ;
187
+ for (int j = 0 ; j < n +extravar; j++) {
188
+ cout << ' ' << delta[j];
189
+ }
190
+ cout << endl;
191
+ }
192
+
193
+ void solve () {
194
+ while (true ) {
195
+ computeDelta ();
196
+ printTable ();
197
+
198
+ int entering = findEnteringVariable ();
199
+ if (entering == -1 ) {
200
+ cout << " Optimal solution found." << endl;
201
+ break ;
202
+ }
203
+
204
+ int leaving = findLeavingVariable (entering);
205
+ if (leaving == -1 ) {
206
+ cout << " Problem is unbounded." << endl;
207
+ return ;
208
+ }
209
+
210
+ // Check for degenerate solution
211
+ if (b[leaving] == 0 ) {
212
+ cout << " Degenerate solution detected." << endl;
213
+ }
214
+
215
+ pivot (entering, leaving);
216
+ }
217
+
218
+ // Print final solution
219
+ cout << " Final Solution:" << endl;
220
+ for (int i = 0 ; i < m; i++) {
221
+ if (B[i]<n)
222
+ cout << " X" << B[i] + 1 << " = " << b[i] << endl;
223
+ }
224
+ double optimalValue = 0 ;
225
+ for (int i = 0 ; i < m; i++) {
226
+ optimalValue += CB[i] * b[i];
227
+ }
228
+ cout << " Optimal value of the objective function: " << optimalValue << endl;
229
+
230
+ // Check for infeasibility
231
+ for (int i = 0 ; i < m; i++) {
232
+
233
+ if (arti_ind.find (B[i])!=arti_ind.end () && b[i] != 0 ) {
234
+ cout << " Infeasible solution: artificial variable X" << B[i] + 1 << " is still in the basis." << endl;
235
+ return ;
236
+ }
237
+ }
238
+ }
239
+ };
240
+
241
+ int main () {
242
+ int variables, constraints;
243
+ cout << " Enter the number of variables and constraints: " ;
244
+ cin >> variables >> constraints;
245
+
246
+ Simplex simplex (variables, constraints);
247
+ simplex.readInput ();
248
+ simplex.solve ();
249
+
250
+ return 0 ;
251
+ }
0 commit comments