diff --git a/.gitignore b/.gitignore index 259148f..9cddbf8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Prerequisites *.d - +CMakeLists.txt +.idea # Compiled Object files *.slo *.lo diff --git a/main.cpp b/main.cpp index 5a2267d..4d52763 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,18 @@ #include +#include "tools/matrix.h" + int main() { - std::cout << "Hello World!\n"; + int n, m; + ColumnVector C(n); + Matrix A(n, m); + ColumnVector b(n); + double eps; + double eps_default; + + std::cin >> C; + std::cin >> A; + std::cin >> b; + std::cin >> eps; return 0; } diff --git a/simplex.cpp b/simplex.cpp index 70be5cc..c9a4b93 100644 --- a/simplex.cpp +++ b/simplex.cpp @@ -1 +1,85 @@ -// implementation of simplex task \ No newline at end of file +#include +#include +#include "tools/matrix.h" + +enum solver_state { + unbounded, + bounded +}; + +struct Result { + solver_state state; + ColumnVector *solution; + double objective_fucntion_value; +}; + +Result Simplex(ColumnVector C, Matrix A, ColumnVector b, double eps = 0.01, bool maximize) { + Result result; + std::vector basicVars(A.getColumns() - A.getRows()); + basicVars[0] = -1; + + for (int i = 1; i < basicVars.size(); i++) { + basicVars[i] = static_cast(basicVars.size()) + i; + } + + int kc = 0; + double temp = A[0][0]; + for (int j = 0; j< A.getColumns(); j++) { + if (A[0][j] < temp) { + temp = A[0][j]; + kc = j; + } + } + + if (A[0][kc] >= 0) { + result.state = unbounded; + result.solution = new ColumnVector(C.getRows()); + for (int i = 0; i < C.getRows(); i++) { + result.solution->operator[](i) = 0; + } + for (int i = 1; i < basicVars.size(); i++) { + if (basicVars[i] <= C.getRows()) { + (*result.solution)[basicVars[i]] = b.getRows() - 1; + } + } + result.objective_fucntion_value = b[0]; + } +} + +/* +Function_name(C, A, b, eps = eps_default) + +Input: +- C: A vector of coefficients of the objective function +- A: A matrix of coefficients of the constraint functions +- b: A vector of right-hand side values +- eps: Approximation accuracy (optional, default = eps_default) + +Steps: +1. Print the optimization problem: + - max (or min) z = C[0] * x1 + C[1] * x2 + ... + C[n] * xn + - subject to the constraints: + - A[0] * x <= b[0] + - A[1] * x <= b[1] + - ... + - A[m] * x <= b[m] + +2. Initialize: + - Form the initial tableau by introducing slack variables to convert inequalities into equalities. + +3. Iteratively apply the Simplex method: + - Step 1: Identify the entering variable (most negative coefficient in the objective row). + - Step 2: Identify the leaving variable (smallest positive ratio of RHS to pivot column). + - Step 3: Perform pivot operations to update the tableau. + +4. Check for optimality or unboundedness: + - If all coefficients in the objective function row are non-negative, the solution is optimal. + - If no leaving variable exists, the problem is unbounded. + +5. Return: + - solver_state: {solved, unbounded} + - x*: Optimal vector of decision variables (if solved) + - z: Maximum (or minimum) value of the objective function (if solved) + +End Function +*/ diff --git a/tools/matrix.cpp b/tools/matrix.cpp index e9f3200..2269226 100644 --- a/tools/matrix.cpp +++ b/tools/matrix.cpp @@ -1,213 +1,213 @@ #include "matrix.h" ColumnVector::ColumnVector(int n) { - rows = n; - columns = 1; - columnVector.resize(n); + rows = n; + columns = 1; + columnVector.resize(n); } ColumnVector::ColumnVector(const ColumnVector& other) { - rows = other.rows; - columns = other.columns; - columnVector = other.columnVector; + rows = other.rows; + columns = other.columns; + columnVector = other.columnVector; } int ColumnVector::getRows() const { - return rows; + return rows; } int ColumnVector::getColumns() const { - return columns; + return columns; } double& ColumnVector::operator[](int row) { - return columnVector[row]; + return columnVector[row]; } ColumnVector& ColumnVector::operator=(const ColumnVector& other) { - rows = other.rows; - columns = other.columns; - columnVector = other.columnVector; - return *this; + rows = other.rows; + columns = other.columns; + columnVector = other.columnVector; + return *this; } ColumnVector ColumnVector::operator+(ColumnVector& other) { - if (rows != other.rows) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } - ColumnVector result(rows); - for (int i = 0; i < rows; ++i) { - result[i] = columnVector[i] + other[i]; - } + if (rows != other.rows) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } + ColumnVector result(rows); + for (int i = 0; i < rows; ++i) { + result[i] = columnVector[i] + other[i]; + } - return result; + return result; } ColumnVector ColumnVector::operator-(ColumnVector& other) { - if (rows != other.rows) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } - ColumnVector result(rows); - for (int i = 0; i < rows; ++i) { - result[i] = columnVector[i] - other[i]; - } + if (rows != other.rows) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } + ColumnVector result(rows); + for (int i = 0; i < rows; ++i) { + result[i] = columnVector[i] - other[i]; + } - return result; + return result; } std::istream& operator>>(std::istream& cin, ColumnVector& vectorObj) { - for (int i = 0; i < vectorObj.rows; ++i) { - cin >> vectorObj[i]; - } - return cin; + for (int i = 0; i < vectorObj.rows; ++i) { + cin >> vectorObj[i]; + } + return cin; } std::ostream& operator<<(std::ostream& cout, ColumnVector& vectorObj) { - for (int i = 0; i < vectorObj.rows; ++i) { - if (i == vectorObj.rows - 1) { - cout << vectorObj[i] << std::endl; - } - else { - cout << vectorObj[i] << ' '; - } - } - return cout; + for (int i = 0; i < vectorObj.rows; ++i) { + if (i == vectorObj.rows - 1) { + cout << vectorObj[i] << std::endl; + } + else { + cout << vectorObj[i] << ' '; + } + } + return cout; } Matrix::Matrix(int n, int m) { - rows = n; - columns = m; - matrix.resize(n); - for (auto& row : matrix) { - row = ColumnVector(m); - } + rows = n; + columns = m; + matrix.resize(n); + for (auto& row : matrix) { + row = ColumnVector(m); + } } Matrix::Matrix(const Matrix& other) { - rows = other.rows; - columns = other.columns; - matrix = other.matrix; + rows = other.rows; + columns = other.columns; + matrix = other.matrix; } int Matrix::getRows() const { - return rows; + return rows; } int Matrix::getColumns() const { - return columns; + return columns; } ColumnVector& Matrix::operator[](int row) { - return matrix[row]; + return matrix[row]; } Matrix& Matrix::operator=(const Matrix& other) { - rows = other.rows; - columns = other.columns; - matrix = other.matrix; - return *this; + rows = other.rows; + columns = other.columns; + matrix = other.matrix; + return *this; } Matrix Matrix::operator+(Matrix& other) const { - if (rows != other.rows || columns != other.columns) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } - Matrix result(rows, columns); - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < columns; ++j) { - auto x = matrix[i]; - auto y = other[i]; - result[i][j] = x[j] + y[j]; - } - } - - return result; + if (rows != other.rows || columns != other.columns) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } + Matrix result(rows, columns); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < columns; ++j) { + auto x = matrix[i]; + auto y = other[i]; + result[i][j] = x[j] + y[j]; + } + } + + return result; } Matrix Matrix::operator-(Matrix& other) const { - if (rows != other.rows || columns != other.columns) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } - Matrix result(rows, columns); - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < columns; ++j) { - auto x = matrix[i]; - auto y = other[i]; - result[i][j] = x[j] - y[j]; - } - } + if (rows != other.rows || columns != other.columns) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } + Matrix result(rows, columns); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < columns; ++j) { + auto x = matrix[i]; + auto y = other[i]; + result[i][j] = x[j] - y[j]; + } + } - return result; + return result; } Matrix Matrix::operator*(Matrix& other) const { - if (columns != other.rows) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } + if (columns != other.rows) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } - Matrix result(rows, other.columns); - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < other.columns; ++j) { - result[i][j] = 0; - for (int k = 0; k < columns; ++k) { - auto x = matrix[i]; - auto y = other[k]; - result[i][j] += x[k] * y[j]; - } - } - } + Matrix result(rows, other.columns); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < other.columns; ++j) { + result[i][j] = 0; + for (int k = 0; k < columns; ++k) { + auto x = matrix[i]; + auto y = other[k]; + result[i][j] += x[k] * y[j]; + } + } + } - return result; + return result; } ColumnVector Matrix::operator*(ColumnVector other) const { - if (columns != other.getRows()) { - throw std::runtime_error("Error: the dimensional problem occurred"); - } + if (columns != other.getRows()) { + throw std::runtime_error("Error: the dimensional problem occurred"); + } - ColumnVector result(rows); - for (int i = 0; i < rows; ++i) { - result[i] = 0; - for (int k = 0; k < columns; ++k) { - auto x = matrix[i]; - result[i] += x[k] * other[k]; - } - } + ColumnVector result(rows); + for (int i = 0; i < rows; ++i) { + result[i] = 0; + for (int k = 0; k < columns; ++k) { + auto x = matrix[i]; + result[i] += x[k] * other[k]; + } + } - return result; + return result; } Matrix Matrix::transpose() const { - Matrix result(columns, rows); - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < columns; ++j) { - auto x = matrix[i]; - result[j][i] = x[j]; - } - } + Matrix result(columns, rows); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < columns; ++j) { + auto x = matrix[i]; + result[j][i] = x[j]; + } + } - return result; + return result; } std::istream& operator>>(std::istream& cin, Matrix& matrixObj) { - for (int i = 0; i < matrixObj.rows; ++i) { - for (int j = 0; j < matrixObj.columns; ++j) { - cin >> matrixObj[i][j]; - } - } - return cin; + for (int i = 0; i < matrixObj.rows; ++i) { + for (int j = 0; j < matrixObj.columns; ++j) { + cin >> matrixObj[i][j]; + } + } + return cin; } std::ostream& operator<<(std::ostream& cout, Matrix& matrixObj) { - for (int i = 0; i < matrixObj.rows; ++i) { - for (int j = 0; j < matrixObj.columns; ++j) { - if (j == matrixObj.columns - 1) { - cout << matrixObj[i][j] << std::endl; - } - else { - cout << matrixObj[i][j] << ' '; - } - } - } - return cout; + for (int i = 0; i < matrixObj.rows; ++i) { + for (int j = 0; j < matrixObj.columns; ++j) { + if (j == matrixObj.columns - 1) { + cout << matrixObj[i][j] << std::endl; + } + else { + cout << matrixObj[i][j] << ' '; + } + } + } + return cout; }