diff --git a/lib/core/consts.hpp b/lib/core/consts.hpp index 956dadf..318fc16 100644 --- a/lib/core/consts.hpp +++ b/lib/core/consts.hpp @@ -5,10 +5,10 @@ namespace core { -enum class PresolveRulesIds { - freeRowId = 0, - singletonVariableId, - rowSingletonId, +enum class PresolveRulesIds { + freeRowId = 0, + singletonVariableId, + rowSingletonId, parallelRowId, emptyColId, fixedColId, @@ -26,6 +26,11 @@ struct FormattedPrimalProblem { std::vector basic_variables; }; +struct FormattedDualProblem { + std::vector> problem_matrix; + std::vector basic_variables; +}; + struct FormattedLogicalProblem { std::vector> problem_matrix; std::vector lower_bounds; diff --git a/lib/solvers/CMakeLists.txt b/lib/solvers/CMakeLists.txt index 9af5dc2..350efdb 100644 --- a/lib/solvers/CMakeLists.txt +++ b/lib/solvers/CMakeLists.txt @@ -1,4 +1,4 @@ -add_subdirectory(dual_simplex) +add_subdirectory(dual_bland) add_subdirectory(primal_simplex) add_subdirectory(logical_solver) add_subdirectory(revised_primal_solver) diff --git a/lib/solvers/dual_simplex/CMakeLists.txt b/lib/solvers/dual_bland/CMakeLists.txt similarity index 90% rename from lib/solvers/dual_simplex/CMakeLists.txt rename to lib/solvers/dual_bland/CMakeLists.txt index 4fb7491..de75d17 100644 --- a/lib/solvers/dual_simplex/CMakeLists.txt +++ b/lib/solvers/dual_bland/CMakeLists.txt @@ -1,4 +1,4 @@ -set(target "dual_simplex") +set(target "dual_bland") file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp") file(GLOB code "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") add_library(${target} STATIC ${headers} ${code}) diff --git a/lib/solvers/dual_simplex/main.cpp b/lib/solvers/dual_bland/main.cpp similarity index 100% rename from lib/solvers/dual_simplex/main.cpp rename to lib/solvers/dual_bland/main.cpp diff --git a/lib/solvers/dual_simplex/main.hpp b/lib/solvers/dual_bland/main.hpp similarity index 100% rename from lib/solvers/dual_simplex/main.hpp rename to lib/solvers/dual_bland/main.hpp diff --git a/lib/utils/dual_reformatter.cpp b/lib/utils/dual_reformatter.cpp new file mode 100644 index 0000000..181675b --- /dev/null +++ b/lib/utils/dual_reformatter.cpp @@ -0,0 +1,128 @@ +#include "dual_reformatter.hpp" + +namespace utils { + +DualRefomatter::DualRefomatter() {} + +core::FormattedDualProblem +DualRefomatter::reformatProblem(const core::InputRows input_rows) { + const std::vector bounds = getBounds(input_rows); + const std::vector> table = getTable(input_rows); + const core::FormattedDualProblem full_table = getFullTable(table, bounds); + return full_table; +} + +std::vector DualRefomatter::getBounds(const core::InputRows input_rows) { + + std::vector bounds; + + // add inequality rows to bounds + for (std::size_t i = 0; i < input_rows.inequality_rows.size(); ++i) { + bounds.push_back(-1.0F * input_rows.inequality_rows.at(i).at(0)); + } + + // add potitive and negative of equality rows to bounds, creating equality by + // constraint + for (std::size_t i = 0; i < input_rows.equality_rows.size(); ++i) { + bounds.push_back(-1.0F * input_rows.equality_rows.at(i).at(0)); + } + + for (std::size_t i = 0; i < input_rows.equality_rows.size(); ++i) { + bounds.push_back(input_rows.equality_rows.at(i).at(0)); + } + + return bounds; +} + +std::vector> +DualRefomatter::getTable(const core::InputRows input_rows) { + + std::vector> table; + + // make temporary row vector container + std::vector row_vector; + + // add inequality rows to table + for (std::size_t i = 0; i < input_rows.inequality_rows.size(); ++i) { + row_vector.clear(); + for (std::size_t j = 1; j < input_rows.inequality_rows.at(0).size(); ++j) { + row_vector.push_back(input_rows.inequality_rows.at(i).at(j)); + } + for (std::size_t j = 1; j < input_rows.inequality_rows.at(0).size(); ++j) { + row_vector.push_back(-1.0F * input_rows.inequality_rows.at(i).at(j)); + } + table.push_back(row_vector); + } + + // add equality rows to table + for (std::size_t i = 0; i < input_rows.equality_rows.size(); ++i) { + row_vector.clear(); + for (std::size_t j = 1; j < input_rows.equality_rows.at(0).size(); ++j) { + row_vector.push_back(input_rows.equality_rows.at(i).at(j)); + } + for (std::size_t j = 1; j < input_rows.equality_rows.at(0).size(); ++j) { + row_vector.push_back(-1.0F * input_rows.equality_rows.at(i).at(j)); + } + table.push_back(row_vector); + } + + // add negative of equality rows to table + for (std::size_t i = 0; i < input_rows.equality_rows.size(); ++i) { + row_vector.clear(); + for (std::size_t j = 1; j < input_rows.equality_rows.at(0).size(); ++j) { + row_vector.push_back(-1.0F * input_rows.equality_rows.at(i).at(j)); + } + for (std::size_t j = 1; j < input_rows.equality_rows.at(0).size(); ++j) { + row_vector.push_back(input_rows.equality_rows.at(i).at(j)); + } + table.push_back(row_vector); + } + return table; +} + +core::FormattedDualProblem +DualRefomatter::getFullTable(const std::vector> input_table, + const std::vector bounds) { + + // container for full table + std::vector> full_table; + + // temporary row vector for use in making table + std::vector row_vector; + const int row_length = input_table.size() + input_table.at(0).size() + 1; + + // add objective row + row_vector.push_back(1.0F); + for (std::size_t i = 0; i < row_length; ++i) { + row_vector.push_back(0.0F); + } + full_table.push_back(row_vector); + row_vector.clear(); + + int index_1_position = 0; + for (std::size_t i = 0; i < input_table.size(); ++i) { + row_vector.clear(); + row_vector.push_back(0); + for (std::size_t j = 0; j < input_table.at(0).size(); ++j) { + row_vector.push_back(input_table.at(i).at(j)); + } + for (std::size_t j = 0; j < input_table.size(); ++j) { + if (j == index_1_position) { + row_vector.push_back(1); + } else { + row_vector.push_back(0); + } + } + row_vector.push_back(bounds.at(i)); + full_table.push_back(row_vector); + } + + core::FormattedDualProblem formatted_problem; + formatted_problem.problem_matrix = full_table; + // TODO: figure out basic variables here + // formatted_problem.basic_variables; + + return formatted_problem; +} + +} // namespace utils \ No newline at end of file diff --git a/lib/utils/dual_reformatter.hpp b/lib/utils/dual_reformatter.hpp new file mode 100644 index 0000000..864db13 --- /dev/null +++ b/lib/utils/dual_reformatter.hpp @@ -0,0 +1,22 @@ +#include "../core/consts.hpp" +#include +#include + +namespace utils { + +class DualRefomatter { +public: + DualRefomatter(); + + core::FormattedDualProblem reformatProblem(const core::InputRows input_rows); + +private: + std::vector getBounds(const core::InputRows input_rows); + + std::vector> getTable(const core::InputRows input_rows); + + core::FormattedDualProblem + getFullTable(const std::vector> input_table, + const std::vector bounds); +}; +} // namespace utils \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 09750b3..aa790b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,7 @@ target_include_directories(${target} ) target_link_libraries(${target} - dual_simplex + dual_bland primal_simplex utils logical_solver