diff --git a/docs/src/guide/further.md b/docs/src/guide/further.md index 91a4dc75ca..ed111f6682 100644 --- a/docs/src/guide/further.md +++ b/docs/src/guide/further.md @@ -125,7 +125,6 @@ linear objective is represented by the following data, held in the Multi-objective optimization in HiGHS is defined by the following methods -- [passLinearObjectives](@ref Multi-objective-optimization] - Pass multiple linear objectives as their number `num_linear_objective` and pointer to a vector of `HighsLinearObjective` instances, overwriting any previous linear objectives - [addLinearObjective](@ref Multi-objective-optimization] - Add a single `HighsLinearObjective` instance to any already stored in HiGHS - [clearLinearObjectives](@ref Multi-objective-optimization] - Clears any linear objectives stored in HiGHS @@ -151,27 +150,13 @@ priority values must be distinct_. * Minimize/maximize with respect to the linear objective of highest priority value, according to whether its `weight` is positive/negative * Add a constraint to the model so that the value of the linear objective of highest priority satsifies a bound given by the values of `abs_tolerance` and/or `rel_tolerance`. + + If the objective was minimized to a value ``f^*\ge0``, then the constraint ensures that the this objective value is no greater than ``\min(f^*+abs\_tolerance,~f^*\times[1+rel\_tolerance]).`` - + If the objective was minimized to a value ``f^*>=0``, then the constraint ensures that the this objective value is no greater than -```math + + If the objective was minimized to a value ``f^*<0``, then the constraint ensures that the this objective value is no greater than ``\min(f^*+abs\_tolerance,~f^*\times[1-rel\_tolerance]).`` -\min(f^*+`abs_tolerance`,~f^*[1+`rel_tolerance`]). -``` + + If the objective was maximized to a value ``f^*\ge0``, then the constraint ensures that the this objective value is no less than ``\max(f^*-abs\_tolerance,~f^*\times[1-rel\_tolerance]).`` - + If the objective was minimized to a value ``f^*<0``, then the constraint ensures that the this objective value is no greater than -```math -\min(f^*+`abs_tolerance`,~f^*[1-`rel_tolerance`]). -``` - - + If the objective was maximized to a value ``f^*>=0``, then the constraint ensures that the this objective value is no less than -```math -\max(f^*-`abs_tolerance`,~f^*[1-`rel_tolerance`]). -``` - - + If the objective was maximized to a value ``f^*<0``, then the constraint ensures that the this objective value is no less than -```math -\max(f^*-`abs_tolerance`,~f^*[1+`rel_tolerance`]). -``` + + If the objective was maximized to a value ``f^*<0``, then the constraint ensures that the this objective value is no less than ``\max(f^*-abs\_tolerance,~f^*\times[1+rel\_tolerance]).`` * Minimize/maximize with respect to the linear objective of next highest priority, and then add a corresponding objective constraint to the model, repeating until optimization with respect to the linear objective of lowest priority has taken place. diff --git a/src/interfaces/highs_c_api.cpp b/src/interfaces/highs_c_api.cpp index 655c0fce30..3c464796e2 100644 --- a/src/interfaces/highs_c_api.cpp +++ b/src/interfaces/highs_c_api.cpp @@ -300,12 +300,22 @@ HighsInt Highs_passLinearObjectives(const void* highs, const HighsInt* priority) { HighsInt status = Highs_clearLinearObjectives(highs); if (status != kHighsStatusOk) return status; - HighsInt num_col = Highs_getNumCol(highs); + HighsLinearObjective linear_objective; for (HighsInt iObj = 0; iObj < num_linear_objective; iObj++) { - status = Highs_addLinearObjectiveWithIndex( - highs, weight[iObj], offset[iObj], &coefficients[iObj * num_col], - abs_tolerance[iObj], rel_tolerance[iObj], priority[iObj], iObj); + HighsInt num_col = Highs_getNumCol(highs); + linear_objective.weight = weight[iObj]; + linear_objective.offset = offset[iObj]; + for (HighsInt iCol = 0; iCol < num_col; iCol++) + linear_objective.coefficients.push_back( + coefficients[iObj * num_col + iCol]); + linear_objective.abs_tolerance = abs_tolerance[iObj]; + linear_objective.rel_tolerance = rel_tolerance[iObj]; + linear_objective.priority = priority[iObj]; + linear_objective.weight = weight[iObj]; + status = + HighsInt(((Highs*)highs)->addLinearObjective(linear_objective, iObj)); if (status != kHighsStatusOk) return status; + linear_objective.coefficients.clear(); } return kHighsStatusOk; } @@ -316,15 +326,6 @@ HighsInt Highs_addLinearObjective(const void* highs, const double weight, const double abs_tolerance, const double rel_tolerance, const HighsInt priority) { - return Highs_addLinearObjectiveWithIndex(highs, weight, offset, coefficients, - abs_tolerance, rel_tolerance, - priority, -1); -} - -HighsInt Highs_addLinearObjectiveWithIndex( - const void* highs, const double weight, const double offset, - const double* coefficients, const double abs_tolerance, - const double rel_tolerance, const HighsInt priority, const HighsInt iObj) { HighsLinearObjective linear_objective; HighsInt num_col = Highs_getNumCol(highs); linear_objective.weight = weight; diff --git a/src/interfaces/highs_c_api.h b/src/interfaces/highs_c_api.h index db8764fae6..0feb39bf35 100644 --- a/src/interfaces/highs_c_api.h +++ b/src/interfaces/highs_c_api.h @@ -557,6 +557,28 @@ HighsInt Highs_passHessian(void* highs, const HighsInt dim, const HighsInt* start, const HighsInt* index, const double* value); +/** + * Passes multiple linear objective data to HiGHS, clearing any such + * data already in HiGHS + * + * @param highs A pointer to the Highs instance. + * @param weight A pointer to the weights of the linear objective, with + * its positive/negative sign determining whether it is + * minimized or maximized during lexicographic optimization + * @param offset A pointer to the objective offsets + * @param coefficients A pointer to the objective coefficients + * @param abs_tolerance A pointer to the absolute tolerances used when + * constructing objective constraints during lexicographic + * optimization + * @param rel_tolerance A pointer to the relative tolerances used when + * constructing objective constraints during lexicographic + * optimization + * @param priority A pointer to the priorities of the objectives during + * lexicographic optimization + * + * @returns A `kHighsStatus` constant indicating whether the call succeeded. + */ + HighsInt Highs_passLinearObjectives(const void* highs, const HighsInt num_linear_objective, const double* weight, const double* offset, @@ -565,6 +587,26 @@ HighsInt Highs_passLinearObjectives(const void* highs, const double* rel_tolerance, const HighsInt* priority); +/** + * Adds linear objective data to HiGHS + * + * @param highs A pointer to the Highs instance. + * @param weight The weight of the linear objective, with its + * positive/negative sign determining whether it is + * minimized or maximized during lexicographic + * optimization + * @param offset The objective offset + * @param coefficients A pointer to the objective coefficients + * @param abs_tolerance The absolute tolerance used when constructing an + * objective constraint during lexicographic optimization + * @param rel_tolerance The relative tolerance used when constructing an + * objective constraint during lexicographic optimization + * @param priority The priority of this objective during lexicographic + * optimization + * + * @returns A `kHighsStatus` constant indicating whether the call succeeded. + */ + HighsInt Highs_addLinearObjective(const void* highs, const double weight, const double offset, const double* coefficients, @@ -572,10 +614,13 @@ HighsInt Highs_addLinearObjective(const void* highs, const double weight, const double rel_tolerance, const HighsInt priority); -HighsInt Highs_addLinearObjectiveWithIndex( - const void* highs, const double weight, const double offset, - const double* coefficients, const double abs_tolerance, - const double rel_tolerance, const HighsInt priority, const HighsInt iObj); +/** + * Clears any multiple linear objective data in HiGHS + * + * @param highs A pointer to the Highs instance. + * + * @returns A `kHighsStatus` constant indicating whether the call succeeded. + */ HighsInt Highs_clearLinearObjectives(const void* highs); /**