Skip to content

Commit 68c4397

Browse files
committed
Merge branch 'latest' into pr-2461
2 parents 1949dc0 + 2fb5d47 commit 68c4397

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+11641
-1073
lines changed

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,10 @@ if(ZLIB AND NOT TARGET ZLIB::ZLIB)
500500
find_package(ZLIB 1.2.3)
501501
endif()
502502

503-
include(CPack)
503+
if(CPack_CMake_INCLUDED EQUAL 0)
504+
include(CPack)
505+
endif()
506+
504507
set(CPACK_PACKAGE_VERSION_MAJOR "${HIGHS_VERSION_MAJOR}")
505508
set(CPACK_PACKAGE_VERSION_MINOR "${HIGHS_VERSION_MINOR}")
506509
set(CPACK_PACKAGE_VERSION_PATCH "${HIGHS_VERSION_PATCH}")

FEATURES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Forcing column reduction now checks the bound on the column dual rather than whe
66

77
Now handling correctly the case where an infeasible MIP has a feasible relaxation, so no ray is computed fixing [#2415](https://github.com/ERGO-Code/HiGHS/issues/2415)
88

9-
Fixed minor bug exposed by [#2441](https://github.com/ERGO-Code/HiGHS/issues/2441) in Highs::setSolution() for a sparse user solution when the moidel is empty, and only clearing the dual data before solving with modified objective in Highs::multiobjectiveSolve() so that user-supplied solution is not cleared.
9+
Fixed minor bug exposed by [#2441](https://github.com/ERGO-Code/HiGHS/issues/2441) in `Highs::setSolution()` for a sparse user solution when the moidel is empty, and only clearing the dual data before solving with modified objective in `Highs::multiobjectiveSolve()` so that user-supplied solution is not cleared.
1010

11+
The irreducible infeasibility system (IIS) facility now detects infeasibility due to bounds on constraint activity values (implied by variable bounds) being incompatible with constraint bounds. A `kIisStrategyLight mode` for the `iis_strategy` option has been introduced so that only infeasibility due to incompatible variable/constraint bounds and constraint activity values is checked for. The LP corresponding to any known IIS is now formed and held as a data member of the `HighsIis` class. It can be obtained as a const reference using `Highs::getIisLp()`, and written to a file using `Highs::writeIisModel(const std::string& filename = "")`
12+
13+
Prompted by [#2463](https://github.com/ERGO-Code/HiGHS/issues/2463), the HiGHS solution and basis files now match data to any column and row names in the model, only assuming that the data are aligned with column and row indices if there are no names in the model. This requires a new version (v2) of the HiGHS basis file. Basis files from v1 are still read, but deprecated. Now, when writing out a model, basis or solution, column and row names are added to the model - previously they were created temporarily and inconsistentyly on the fly. If the model has existing names, then distinctive names are created to replace any blank names, but names with spaces or duplicate names yield an error status return.
1114

check/TestBasis.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,16 @@ TEST_CASE("Basis-file", "[highs_basis_file]") {
5656
f << "HiGHS v1" << std::endl;
5757
f << "None" << std::endl;
5858
f.close();
59-
return_status = highs.readBasis(invalid_basis_file);
60-
REQUIRE(return_status == HighsStatus::kOk);
59+
// HiGHS v1 basis file is deprecated, but read, so warning is
60+
// returned
61+
REQUIRE(highs.readBasis(invalid_basis_file) == HighsStatus::kWarning);
62+
63+
// Write and read a file for an invalid basis
64+
f.open(invalid_basis_file, std::ios::out);
65+
f << "HiGHS_basis_file v2" << std::endl;
66+
f << "None" << std::endl;
67+
f.close();
68+
REQUIRE(highs.readBasis(invalid_basis_file) == HighsStatus::kOk);
6169

6270
// Write and read a file for incompatible number of columns
6371
f.open(invalid_basis_file, std::ios::out);

check/TestCAPI.c

Lines changed: 148 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,6 @@ void fullApi() {
617617

618618
// Define all column names to be different
619619
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
620-
const char suffix = iCol + '0';
621620
char name[5]; // 3 chars prefix, 1 char iCol, 1 char 0-terminator
622621
sprintf(name, "%s%" HIGHSINT_FORMAT "", col_prefix, iCol);
623622
const char* name_p = name;
@@ -650,7 +649,6 @@ void fullApi() {
650649

651650
// Define all row names to be different
652651
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
653-
const char suffix = iRow + '0';
654652
char name[5]; // 3 chars prefix, 1 char iCol, 1 char 0-terminator
655653
sprintf(name, "%s%" HIGHSINT_FORMAT "", row_prefix, iRow);
656654
const char* name_p = name;
@@ -1991,7 +1989,7 @@ void testDualRayTwice() {
19911989
void* highs = Highs_create();
19921990
Highs_setBoolOptionValue(highs, "output_flag", dev_run);
19931991
int ret;
1994-
double INF = Highs_getInfinity(highs);
1992+
double inf = Highs_getInfinity(highs);
19951993
ret = Highs_changeObjectiveOffset(highs, 0.0);
19961994
assert(ret == 0);
19971995
ret = Highs_setStringOptionValue(highs, "presolve", "off");
@@ -2000,9 +1998,9 @@ void testDualRayTwice() {
20001998
assert(ret == 0);
20011999
ret = Highs_addCol(highs, 0.0, 0.0, 0.0, 0, NULL, NULL);
20022000
assert(ret == 0);
2003-
ret = Highs_addCol(highs, -1.0, 0.0, INF, 0, NULL, NULL);
2001+
ret = Highs_addCol(highs, -1.0, 0.0, inf, 0, NULL, NULL);
20042002
assert(ret == 0);
2005-
ret = Highs_addCol(highs, -1.0, 0.0, INF, 0, NULL, NULL);
2003+
ret = Highs_addCol(highs, -1.0, 0.0, inf, 0, NULL, NULL);
20062004
assert(ret == 0);
20072005
HighsInt index[2] = {2, 3};
20082006
double value[2] = {1.0, -1.0};
@@ -2012,19 +2010,19 @@ void testDualRayTwice() {
20122010
index[1] = 3;
20132011
value[0] = 1.0;
20142012
value[1] = 1.0;
2015-
ret = Highs_addRow(highs, 1.0, INF, 2, index, value);
2013+
ret = Highs_addRow(highs, 1.0, inf, 2, index, value);
20162014
assert(ret == 0);
20172015
index[0] = 0;
20182016
index[1] = 2;
20192017
value[0] = -2.0;
20202018
value[1] = 1.0;
2021-
ret = Highs_addRow(highs, -INF, 0.0, 2, index, value);
2019+
ret = Highs_addRow(highs, -inf, 0.0, 2, index, value);
20222020
assert(ret == 0);
20232021
index[0] = 1;
20242022
index[1] = 3;
20252023
value[0] = -3.0;
20262024
value[1] = 1.0;
2027-
ret = Highs_addRow(highs, -INF, 0.0, 2, index, value);
2025+
ret = Highs_addRow(highs, -inf, 0.0, 2, index, value);
20282026
assert(ret == 0);
20292027
ret = Highs_run(highs);
20302028
assert(ret == 0);
@@ -2105,16 +2103,16 @@ void testDeleteRowResolveWithBasis() {
21052103
void* highs = Highs_create();
21062104
Highs_setBoolOptionValue(highs, "output_flag", dev_run);
21072105
HighsInt ret;
2108-
double INF = Highs_getInfinity(highs);
2106+
double inf = Highs_getInfinity(highs);
21092107
ret = Highs_addCol(highs, 0.0, 2.0, 2.0, 0, NULL, NULL);
2110-
ret = Highs_addCol(highs, 0.0, -INF, INF, 0, NULL, NULL);
2111-
ret = Highs_addCol(highs, 0.0, -INF, INF, 0, NULL, NULL);
2108+
ret = Highs_addCol(highs, 0.0, -inf, inf, 0, NULL, NULL);
2109+
ret = Highs_addCol(highs, 0.0, -inf, inf, 0, NULL, NULL);
21122110
HighsInt index_1[2] = {0, 2};
21132111
double value_1[2] = {2.0, -1.0};
21142112
ret = Highs_addRow(highs, 0.0, 0.0, 2, index_1, value_1);
21152113
HighsInt index_2[1] = {1};
21162114
double value_2[1] = {6.0};
2117-
ret = Highs_addRow(highs, 10.0, INF, 1, index_2, value_2);
2115+
ret = Highs_addRow(highs, 10.0, inf, 1, index_2, value_2);
21182116
Highs_run(highs);
21192117
double col_value[3] = {0.0, 0.0, 0.0};
21202118
Highs_getSolution(highs, col_value, NULL, NULL, NULL);
@@ -2129,30 +2127,145 @@ void testDeleteRowResolveWithBasis() {
21292127
Highs_destroy(highs);
21302128
}
21312129

2130+
void testIis() {
2131+
void* highs = Highs_create();
2132+
Highs_setBoolOptionValue(highs, "output_flag", dev_run);
2133+
HighsInt ret;
2134+
double inf = Highs_getInfinity(highs);
2135+
// For the constraints
2136+
//
2137+
// x + y - z = 2
2138+
//
2139+
// x + y + z <= 5
2140+
//
2141+
// x + 2y + z <= 1
2142+
//
2143+
// with variables in [0, 1], constraints 0 and 2 form an IIS with
2144+
//
2145+
// x free (so should be removed?); 0 <= y; 0 <= z
2146+
//
2147+
// x + y - z >= 2; x + 2y + z <= 1
2148+
//
2149+
ret = Highs_addCol(highs, 0.0, 0.0, 1.0, 0, NULL, NULL);
2150+
assert(ret == 0);
2151+
ret = Highs_addCol(highs, 0.0, 0.0, 1.0, 0, NULL, NULL);
2152+
assert(ret == 0);
2153+
ret = Highs_addCol(highs, 0.0, 0.0, 1.0, 0, NULL, NULL);
2154+
assert(ret == 0);
2155+
HighsInt index[3] = {0, 1, 2};
2156+
double value_1[3] = {1, 1, -1};
2157+
double value_2[3] = {1, 1, 1};
2158+
double value_3[3] = {1, 2, 1};
2159+
ret = Highs_addRow(highs, 2.0, 2.0, 3, index, value_1);
2160+
assert(ret == 0);
2161+
ret = Highs_addRow(highs, -inf, 5.0, 3, index, value_2);
2162+
assert(ret == 0);
2163+
ret = Highs_addRow(highs, -inf, 1.0, 3, index, value_3);
2164+
assert(ret == 0);
2165+
2166+
HighsInt num_col;
2167+
HighsInt num_row;
2168+
HighsInt num_nz;
2169+
HighsInt sense;
2170+
double offset;
2171+
ret = Highs_getLp(highs, kHighsMatrixFormatRowwise,
2172+
&num_col, &num_row, &num_nz,
2173+
&sense, &offset,
2174+
NULL, NULL, NULL,
2175+
NULL, NULL,
2176+
NULL, NULL, NULL,
2177+
NULL);
2178+
2179+
for (int k = 0 ; k < 2; k++) {
2180+
HighsInt iis_num_col;
2181+
HighsInt iis_num_row;
2182+
ret = Highs_getIis(highs,
2183+
&iis_num_col, &iis_num_row,
2184+
NULL, NULL,
2185+
NULL, NULL,
2186+
NULL, NULL);
2187+
assert(ret == 0);
2188+
2189+
if (k == 0) {
2190+
// No IIS from kHighsIisStrategyLight
2191+
assert(iis_num_col == 0);
2192+
assert(iis_num_row == 0);
2193+
Highs_setIntOptionValue(highs, "iis_strategy",
2194+
kHighsIisStrategyFromLpRowPriority);
2195+
} else {
2196+
assert(iis_num_col == 3);
2197+
assert(iis_num_row == 2);
2198+
HighsInt* col_index = (HighsInt*)malloc(sizeof(HighsInt) * iis_num_col);
2199+
HighsInt* row_index = (HighsInt*)malloc(sizeof(HighsInt) * iis_num_row);
2200+
HighsInt* col_bound = (HighsInt*)malloc(sizeof(HighsInt) * iis_num_col);
2201+
HighsInt* row_bound = (HighsInt*)malloc(sizeof(HighsInt) * iis_num_row);
2202+
HighsInt* col_status = (HighsInt*)malloc(sizeof(HighsInt) * num_col);
2203+
HighsInt* row_status = (HighsInt*)malloc(sizeof(HighsInt) * num_row);
2204+
ret = Highs_getIis(highs,
2205+
&iis_num_col, &iis_num_row,
2206+
col_index, row_index,
2207+
col_bound, row_bound,
2208+
col_status, row_status);
2209+
assert(ret == 0);
2210+
2211+
assert(col_index[0] == 0);
2212+
assert(col_index[1] == 1);
2213+
assert(col_index[2] == 2);
2214+
2215+
assert(row_index[0] == 0);
2216+
assert(row_index[1] == 2);
2217+
2218+
assert(col_bound[0] == kHighsIisBoundFree);
2219+
assert(col_bound[1] == kHighsIisBoundLower);
2220+
assert(col_bound[2] == kHighsIisBoundLower);
2221+
2222+
assert(row_bound[0] == kHighsIisBoundLower);
2223+
assert(row_bound[1] == kHighsIisBoundUpper);
2224+
2225+
assert(col_status[0] == kHighsIisStatusInConflict);
2226+
assert(col_status[1] == kHighsIisStatusInConflict);
2227+
assert(col_status[2] == kHighsIisStatusInConflict);
2228+
2229+
assert(row_status[0] == kHighsIisStatusInConflict);
2230+
assert(row_status[1] == kHighsIisStatusNotInConflict);
2231+
assert(row_status[2] == kHighsIisStatusInConflict);
2232+
2233+
free(col_index);
2234+
free(row_index);
2235+
free(col_bound);
2236+
free(row_bound);
2237+
free(col_status);
2238+
free(row_status);
2239+
}
2240+
}
2241+
2242+
Highs_destroy(highs);
2243+
}
2244+
21322245
int main() {
2133-
minimalApiIllegalLp();
2134-
testCallback();
2135-
versionApi();
2136-
fullApi();
2137-
minimalApiLp();
2138-
minimalApiMip();
2139-
minimalApiQp();
2140-
fullApiOptions();
2141-
fullApiLp();
2142-
fullApiMip();
2143-
fullApiQp();
2144-
passPresolveGetLp();
2145-
options();
2146-
testGetColsByRange();
2147-
testPassHessian();
2148-
testRanging();
2149-
testFeasibilityRelaxation();
2150-
testGetModel();
2151-
testMultiObjective();
2152-
testQpIndefiniteFailure();
2153-
testDualRayTwice();
2154-
2155-
testDeleteRowResolveWithBasis();
2246+
minimalApiIllegalLp();
2247+
testCallback();
2248+
versionApi();
2249+
fullApi();
2250+
minimalApiLp();
2251+
minimalApiMip();
2252+
minimalApiQp();
2253+
fullApiOptions();
2254+
fullApiLp();
2255+
fullApiMip();
2256+
fullApiQp();
2257+
passPresolveGetLp();
2258+
options();
2259+
testGetColsByRange();
2260+
testPassHessian();
2261+
testRanging();
2262+
testFeasibilityRelaxation();
2263+
testGetModel();
2264+
testMultiObjective();
2265+
testQpIndefiniteFailure();
2266+
testDualRayTwice();
2267+
testDeleteRowResolveWithBasis();
2268+
testIis();
21562269
return 0;
21572270
}
21582271
// testSetSolution();

0 commit comments

Comments
 (0)