Skip to content

Commit

Permalink
Created Highs::passLinearObjectives Highs::addLinearObjective Highs::…
Browse files Browse the repository at this point in the history
…clearLinearObjectives, and unit test in TestMultipleObjective.cpp
  • Loading branch information
jajhall committed Nov 20, 2024
1 parent 615663c commit e063490
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 112 deletions.
2 changes: 2 additions & 0 deletions check/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ if ((NOT FAST_BUILD OR ALL_TESTS) AND NOT (BUILD_EXTRA_UNIT_ONLY))
TestBasis.cpp
TestBasisSolves.cpp
TestCrossover.cpp
TestHighsCDouble.cpp
TestHighsHash.cpp
TestHighsIntegers.cpp
TestHighsParallel.cpp
Expand All @@ -66,6 +67,7 @@ if ((NOT FAST_BUILD OR ALL_TESTS) AND NOT (BUILD_EXTRA_UNIT_ONLY))
TestLpModification.cpp
TestLpOrientation.cpp
TestModelProperties.cpp
TestMultiObjective.cpp
TestPdlp.cpp
TestPresolve.cpp
TestQpSolver.cpp
Expand Down
108 changes: 2 additions & 106 deletions check/TestHighsIntegers.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "HCheckConfig.h"
#include "catch.hpp"
#include "util/HighsCDouble.h"
// #include "util/HighsCDouble.h"
#include "util/HighsIntegers.h"
#include "util/HighsRandom.h"
// #include "util/HighsRandom.h"

const bool dev_run = false;

Expand Down Expand Up @@ -40,107 +40,3 @@ TEST_CASE("HighsIntegers", "[util]") {

if (dev_run) printf("integral scalar is %g\n", integralscalar);
}

void testCeil(HighsCDouble x) {
double ceil_x;
double double_x;
ceil_x = double(ceil(x));
double_x = double(x);
REQUIRE(ceil_x >= double_x);
REQUIRE(ceil(x) >= x);
}

void testFloor(HighsCDouble x) {
double floor_x;
double double_x;
floor_x = double(floor(x));
double_x = double(x);
REQUIRE(floor_x <= double_x);
REQUIRE(floor(x) <= x);
}
TEST_CASE("HighsCDouble-ceil", "[util]") {
HighsCDouble x;
x = -1e-34;
testCeil(x);
x = -1e-32;
testCeil(x);
x = -1e-30;
testCeil(x);
x = -1e-23;
testCeil(x);
x = -1e-12;
testCeil(x);
x = -1e-1;
testCeil(x);
x = -0.99;
testCeil(x);

x = 0.99;
testCeil(x);
x = 1e-1;
testCeil(x);
x = 1e-12;
testCeil(x);
// This and rest failed in #2041
x = 1e-23;
testCeil(x);
x = 1e-30;
testCeil(x);
x = 1e-32;
testCeil(x);
x = 1e-34;
testCeil(x);

HighsRandom rand;
for (HighsInt k = 0; k < 1000; k++) {
double man = rand.fraction();
HighsInt power = 2 - rand.integer(5);
double exp = std::pow(10, power);
x = man * exp;
testCeil(x);
}
}

TEST_CASE("HighsCDouble-floor", "[util]") {
HighsCDouble x;

x = 1e-34;
testFloor(x);
x = 1e-32;
testFloor(x);
x = 1e-30;
testFloor(x);
x = 1e-23;
testFloor(x);
x = 1e-12;
testFloor(x);
x = 1e-1;
testFloor(x);
x = 0.99;
testFloor(x);

x = -0.99;
testFloor(x);
x = -1e-1;
testFloor(x);
x = -1e-12;
testFloor(x);
// This and rest failed in #2041
x = -1e-23;
testFloor(x);
x = -1e-30;
testFloor(x);
x = -1e-32;
testFloor(x);
x = -1e-34;
testFloor(x);

HighsRandom rand;
for (HighsInt k = 0; k < 1000; k++) {
double man = rand.fraction();
HighsInt power = 2 - rand.integer(5);
double exp = std::pow(10, power);
x = man * exp;
testFloor(x);
}
}
24 changes: 19 additions & 5 deletions src/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ class Highs {
HighsStatus passHessian(const HighsInt dim, const HighsInt num_nz,
const HighsInt format, const HighsInt* start,
const HighsInt* index, const double* value);
/**
* @brief Pass multiple linear objectives for the incumbent model
*/
HighsStatus passLinearObjectives(
const HighsInt num_linear_objective,
const HighsLinearObjective* linear_objective);

/**
* @brief Add a linear objective for the incumbent model
*/
HighsStatus addLinearObjective(const HighsLinearObjective& linear_objective);

/**
* @brief Clear the multiple linear objective data
*/
HighsStatus clearLinearObjectives();

/**
* @brief Pass a column name to the incumbent model
*/
Expand Down Expand Up @@ -187,11 +204,6 @@ class Highs {
*/
HighsStatus run();

/**
* @brief Solve the incumbent model according to the specified options
*/
HighsStatus solve();

/**
* @brief Postsolve the incumbent model using a solution
*/
Expand Down Expand Up @@ -1430,6 +1442,8 @@ class Highs {

bool written_log_header = false;

HighsStatus solve();

void exactResizeModel() {
this->model_.lp_.exactResize();
this->model_.hessian_.exactResize();
Expand Down
59 changes: 58 additions & 1 deletion src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,39 @@ HighsStatus Highs::passHessian(const HighsInt dim, const HighsInt num_nz,
return passHessian(hessian);
}

HighsStatus Highs::passLinearObjectives(
const HighsInt num_linear_objective,
const HighsLinearObjective* linear_objective) {
if (num_linear_objective < 0) return HighsStatus::kOk;
this->multi_linear_objective_.clear();
for (HighsInt iObj = 0; iObj < num_linear_objective; iObj++)
if (this->addLinearObjective(linear_objective[iObj]) != HighsStatus::kOk)
return HighsStatus::kError;
;
return HighsStatus::kOk;
}

HighsStatus Highs::addLinearObjective(
const HighsLinearObjective& linear_objective) {
HighsInt linear_objective_coefficients_size =
linear_objective.coefficients.size();
if (linear_objective_coefficients_size != this->model_.lp_.num_col_) {
highsLogUser(options_.log_options, HighsLogType::kError,
"Coefficient vector for linear objective has size %d != %d = "
"lp.num_col_\n",
int(linear_objective_coefficients_size),
int(this->model_.lp_.num_col_));
return HighsStatus::kError;
}
this->multi_linear_objective_.push_back(linear_objective);
return HighsStatus::kOk;
}

HighsStatus Highs::clearLinearObjectives() {
this->multi_linear_objective_.clear();
return HighsStatus::kOk;
}

HighsStatus Highs::passColName(const HighsInt col, const std::string& name) {
const HighsInt num_col = this->model_.lp_.num_col_;
if (col < 0 || col >= num_col) {
Expand Down Expand Up @@ -877,7 +910,31 @@ HighsStatus Highs::presolve() {
return returnFromHighs(return_status);
}

HighsStatus Highs::run() { return this->solve(); }
HighsStatus Highs::run() {
HighsInt num_multi_linear_objective = this->multi_linear_objective_.size();
printf("Has %d multiple linear objectives\n",
int(num_multi_linear_objective));
if (!this->multi_linear_objective_.size()) return this->solve();
HighsLp& lp = this->model_.lp_;
HighsLinearObjective& multi_linear_objective =
this->multi_linear_objective_[0];
if (multi_linear_objective.coefficients.size() !=
static_cast<size_t>(lp.num_col_)) {
highsLogUser(options_.log_options, HighsLogType::kError,
"Multiple linear objective coefficient vector %d has size "
"incompatible with model\n",
int(0));
return HighsStatus::kError;
}
this->clearSolver();
// Objective is multiplied by the weight and minimized
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
lp.col_cost_[iCol] = multi_linear_objective.weight *
multi_linear_objective.coefficients[iCol];
lp.offset_ = multi_linear_objective.weight * multi_linear_objective.offset;
lp.sense_ = ObjSense::kMinimize;
return this->solve();
}

// Checks the options calls presolve and postsolve if needed. Solvers are called
// with callSolveLp(..)
Expand Down

0 comments on commit e063490

Please sign in to comment.