P. 1
Simplex.cc

|Views: 3|Likes:
simplex method
simplex method

See more
See less

04/14/2013

pdf

text

original

# // Simplex method v2.01 (Feng Xie, xief@mcmaster.

ca) // // simplex (vector<vector<double>> A, vector<double> B, vector<double> C, // vector<double> X, double obj); // Input: A - constraint matrix in standard form (equality); // B - right hand side, should be non-negative; // C - objective vector. // Output: X - optimal solution; obj - optimal value; // Returns: -1 - unbounded; 0 - infeasible; 1 - feasible & bounded. // Note: it solves a maximization problem. #include #include #include #include <iostream> <vector> <set> <cmath>

using namespace std; #define EPS 1E-9 #define DEBUG 0 // Check if column c of A is an indentity column. // Returns: -1 if not; non-zero row id otherwise. inline int identity_col (const vector <vector <double> > & A, int c) { int count = 0, row; for (int r=0; r<A.size(); r++) if (A[r][c] > EPS) { count++; row = r; } return (count == 1) ? row : -1; } // Convert a standard form of LP into canonical form: // 1) The entries in the objective vector corresponding to basic variables are // 0's. // 2) The submatrix corresponding to basic variables is an identity matrix. void canonicalize ( vector <vector <double> > & A, vector <double> & B, vector <double> & C, vector <int> & BasicVarR, // basic variable of each row double & obj // objective value ) { int m = A.size(), n = C.size(); for (int r=0; r<m; r++) { int bc = BasicVarR[r]; // col. that the basic variable is in if ( fabs(A[r][bc] - 1.0) > EPS) { double p = A[r][bc]; for (int c=0; c<n; c++) A[r][c] /= p; B[r] /= p; } if (fabs(C[bc]) > EPS) { double p = C[bc]; for (int c=0; c<n; c++) C[c] -= A[r][c] * p; obj -= B[r] * p; } } }

} if (DEBUG) { for (int c=0. c++) cout << A[r][c] << "\t". ev<n. r++) { if ( r != lvr && fabs (A[r][ev]) > EPS ) { double p2 = A[r][ev]. obj -= p2 * B[lvr]. for (int c=0.// Pivoting iterations. int lvr = -1. vector <double> & B. r<m. for (int c=0. // optimum reached. c++) cout << C[c] << "\t". // unbounded int lv = BasicVarR[lvr]. do pivoting. while (1) { // Find the entering variable (use the first one encountered).size(). false otherwise.size(). cout << obj << endl. vector <double> & C. if (ev == n) break. B[lvr] /= p. id'ed by row double minRatio. // id of the entering variable for (ev=0. vector <int> & BasicVarR. // leaving variable // Leaving & entering variables identified. for (int r=0. ev++) if (C[ev] < -EPS) break. c<n. c<n. c<n. } cout << endl. } } if ( fabs (C[ev]) > EPS ) { double p2 = C[ev]. // Returns true if the problem is unbounded. cout << B[r] << endl. c++) A[lvr][c] /= p. minRatio = B[r] / A[r][ev]. double p = A[lvr][ev]. c<n. // basic variable of each row double & obj // objective value ) { int m = A. for (int c=0. // leaving variable. bool pivoting ( vector <vector <double> > & A. n = C. c++) C[c] -= p2 * A[lvr][c]. BasicVarR[lvr] = ev. c<n. int ev = 0. r++) { if (A[r][ev] > EPS) { if ( lvr < 0 || B[r]/A[r][ev] < minRatio ) { lvr = r. } } } if (lvr < 0) return true. B[r] -= p2 * B[lvr]. // Find the leaving variable using ratio test. for (int r=0. for (int r=0. r++) { for (int c=0. r<m. c++) A[r][c] -= p2 * A[lvr][c]. r<m. } } .

j<k.resize (n). (The new B is stored in X. // b vector <double> & X // x ) { int n = A. . } } // Forward substitution. // 2) Remove redundant constraints detected by linear dependency. X[k] /= U[k][k].begin(). for (int j=0. } // Backward substitution. for (int i=0.) for (int k=n-1. for (int k=0. // LU decomposition (Doolittle's method) is used.size() != n) X. j++) { // compute the (k+1)'s row of U double t = A[k+1][j]. i<n. k++) { for (int i=k+1. i<k+1. if (X. (B) is non-negative. j<n. void LU_solver ( vector <vector <double> > & A. j++) X[k] -= ( X[j] * L[k][j] ).return false. // LU decomposition (Dolittle's method). i++) { // compute the k'th column of L double t = A[i][k]. vector <vector <double> > L ( n. k<n. i++) L[i][i] = 1.0.end(). j++) t -= ( L[i][j] * U[j][k] ). k<n-1. k>=0. j<n. j<k. i<n. U[k+1][j] = t.s. // diagonals of L are 1's // The first row of U is the same as the first row of A. for (int j=0. vector<double> (n) ). for (int i=0. k++) { X[k] = B[k]. vector <vector <double> > U ( n. for (int k=0. } for (int j=k+1. L[i][k] = t / U[k][k]. } // Solver for Ax = b.begin() ). where A is a nonsingular square matrix. copy ( A[0]. i++) t -= ( L[k+1][i] * U[i][j] ). // matrix A vector <double> & B. k--) { for (int j=k+1. } } // Preprocessing: // 1) Make sure that the r. j++) X[k] -= ( X[j] * U[k][j] ). A[0]. vector<double> (n) ). U[0].size().h.

else { // both are nonzero if ( fabs(ratio) < EPS ) ratio = A[i][c] / A[j][c]. // # of constraints int n = A[0].size (). // right hand side vector <double> & X // unknowns ) { int m = A. // Remove the redundant constraints. } } } if (c == n) { if ( fabs(B[i]) < EPS && fabs(B[j]) < EPS || fabs(B[j]) > EPS && fabs (B[i]/B[j] . true).ratio) > EPS ) break. and check // if it is consistent. j++) if (!IsRedundant[j]) { int c.size (). else return -1.end(). else { if ( fabs (A[i][c]/A[j][c] . false). . for (int r=0. c++) { if ( fabs(A[i][c]) < EPS && fabs(A[j][c]) < EPS ) // both are 0 continue. // -2 : if the system is determined or over-determined and has unique // non-negative solution. c++) if (fabs(A[r][c]) > EPS) { allZero = false. which is stored in X.0.begin(). r++) { bool allZero = true. int preprocess ( vector <vector <double> > & A. double ratio = 0. for (c=0.ratio) < EPS ) IsRedundant[j] = true. // inconsistency detected } } } int numRedundancies = count (IsRedundant. } } for (int i=0. r<m. break. else IsRedundant[r] = true. // # of variables vector <bool> IsRedundant (m. j<m. c<n. c<n. else if ( fabs(A[i][c]) < EPS && fabs(A[j][c]) > EPS || // one is 0 fabs(A[i][c]) > EPS && fabs(A[j][c]) < EPS ) break. // Returns: // -1 : if the system is inconsistent. // >=0 : otherwise indicate the # of redundancies removed.// 3) Solve the system if it is determined or over-determined. for (int c=0. // flags for redundant constraint // Remove all-zero rows. } if (allZero) { if (fabs(B[r]) > EPS) return -1. IsRedundant. i<m. i++) if (!IsRedundant[i]) { for (int j=i+1. // constraint matrix vector <double> & B.

bool nonNegative = true.begin()). A[r]. for (int r=0. 0 . } return numRedundancies. // Returns: -1 .erase (B.feasible & bounded. if (m >= // A0. c++) if (X[c] < 0) { nonNegative = false. } // Simplex method (primal). for (int r=n. X0 : for LU solver.0. break. i++) { A. } if (!nonNegative) return -1. B. } } return (consistent ? -2 : -1). A0[r]. vector vector n) { // determined or overdetermined system B0. r<m.if (numRedundancies > 0) { int ir = 0. <double> B0 (n).begin()).begin().end()-1).begin(). r++) { double lhs = 0. c<n. for (int c=0. r++) { copy (A[r]. c++) lhs += A[r][c] * X[c]. A[i]. 1 . r<n. } } for (int i=0.unbounded. i<numRedundancies. } ir++. i++) { if (!IsRedundant[i]) { if (ir < i) { // overiding copy (A[i]. B0. if ( fabs (lhs .end(). // constraint matrix .end(). // 1 position to the right of the new A for (int i=0. X). bool consistent = true. i<m. int simplex ( const vector <vector <double> > & A. } LU_solver (A0. <vector <double> > A0 (n. // Check if the solutions are non-negative.end()-1).B[r]) > EPS ) { // constraint c not satisfied consistent = false.erase (A. B[ir] = B[i]. break. // Check if X satisfies the other constraints. vector<double> (n)).infeasible. } } m -= numRedundancies. for (int c=0. c<n. B0[r] = B[r]. A[ir].

end(). // inconsistent system // solved // need to run Simplex // size changes after redundancy removal vector <bool> IsBasic (n. A0[r]. X.end(). X). if (X. B0. if (r >= 0 && BasicVarR[r] < 0) { IsBasic[c] = true. . if (!m || m != B.begin(). // A0. vector vector vector B2. C2 : for Phase II <vector <double> > A2 ( m. vector <double> & X. B0. m = A0.size() != n) X. int numBasicVar = 0. // basic variable of each row // Find the initial basic variables. BasicVarR[r] = c. for (int r=0.begin().begin() ). copy ( B0. const vector <double> & C. r<m. int n = A[0]. for (int r=0. r<m. c<n. // bit flag for basic variables vector <int> BasicVarR (m. B0. vector<double>(n) ).size() || n != C. int ret_val = preprocess (A0.begin() ).begin() ).begin() ). vector <double> B0 (m).resize(n). A0[r]. B.size().begin().size(). false).size()) { cout << "Wrong inputs!\n". fill (X. // // // // right hand side objective vector unknowns objective value // # of inequalities // # of variables // Sanity check. -1). } } // A2. r++) copy (A[r]. A[r]. B2. int numRedundancies.end(). r++) copy ( A0[r].begin(). 0).begin(). <double> B2 (m). else numRedundancies = ret_val. exit(1). numBasicVar++. for (int c=0. else if (ret_val == -2) return 1. A2[r]. if (ret_val == -1) return -1. <double> C2 (n). B0 : for preprocessing vector <vector <double> > A0 ( m.end().size (). copy ( B. } // Adjust size of X if necessary. c++) { int r = identity_col (A.end(). vector<double>(n) ).const vector <double> & B. double & obj ) { int m = A. c).

r++) X[BasicVarR[r]] = B2[r].begin() ). // new objective vector for phase I for (int r=0. // r.end(). C1 : for Phase I. B2.push_back (1). r<m. B1.s. obj).begin(). <double> B1 (m). BasicVarR. } } // Phase II.h. r++) { for (int c=0.resize (n1. int n1 = n.s is found.push_back (1). r++) copy ( A0[r]. } C1.h. B1.f. n1++. i++) { if (BasicVarR[i] < 0) { for (int r=0.end(). C2. is the basic solution . canonicalize (A2. return ( unbounded ? -1 : 1 ). // obj. go into Phase I. if (!feasible) return 0. for (int r=0. C2. BasicVarR. copy ( B0. vector<double>(n) ). B0. // pivoting if (unbounded) { cout << "Unbounded Phase I!" << endl. // Adjust sizes of objective vector canonicalize (A1. B2[r] = B1[r]. obj). A0[r]. C1.s. else A1[r].f. // convert to canonical form bool unbounded = pivoting (A1. // Initial b. A1[r]. BasicVarR. B2. // r.for (int c=0. obj). c<n. r<m. c<n. vector should be negated if (numBasicVar < m) { // No initial b. r<m. is the same for (int i=0. BasicVarR. } } C1. <double> C1 (n. BasicVarR[i] = n1. C1. r<m.s. for (int r=0. i<m. 0). // Phase I need extra dummy variables // A1. <vector <double> > A1 (m.begin() ). c++) C2[c] = -C[c]. obj = 0. bool unbounded = pivoting (A2. r++) { if (r == i) A1[r]. } bool feasible = (fabs(obj) < EPS) ? true : false. obj).begin(). c++) A2[r][c] = A1[r][c].push_back (0). 1). B1. prepare for Phase II. found. vector vector vector B1. exit (1).

for (int i=0. for (int i=0. i<m. obj) << endl. } } . vector <vector <double> > A (m. for (int i=0. cout << "Input the " << m << " by " << n << " coefficients of the LHS of equality constraints:\n". i++) cin >> B[i]. double obj. cout << "\nOptimal objective value = " << obj << endl. cout << "Input the number of variables: ". cout << "Input the number of constraints: ". vector <double> B (m). i<n. cin >> m. cin >> n. C(n). B. cout << endl. n. i++) for (int j=0. cout << "Input the " << n << " coefficients of the objective function:\n". while (1) { cout << "Warning: The current version can only handle LP in standard form!!\ n". C. cout << "\nOptimal solution: ". vector<double>(n)). for (int i=0. i++) cout << X[i] << "\t". cout << "Input the " << m << " constants of the RHS of equality constraints:\n". j++) cin >> A[i][j]. i++) cin >> C[i]. i<m. i<n. cout << simplex (A.} main() { int m. j<n. vector <double> X. X.

scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->