Skip to content

Commit 3121a8a

Browse files
committed
Added testFixedLp to TestCAPI.c
1 parent 86105fe commit 3121a8a

File tree

3 files changed

+152
-2
lines changed

3 files changed

+152
-2
lines changed

check/TestCAPI.c

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,6 @@ void testGetModel() {
18201820
assert(ck_sense == sense);
18211821

18221822
double* ck_col_cost = (double*)malloc(sizeof(double) * ck_num_col);
1823-
;
18241823
double* ck_col_lower = (double*)malloc(sizeof(double) * ck_num_col);
18251824
double* ck_col_upper = (double*)malloc(sizeof(double) * ck_num_col);
18261825
double* ck_row_lower = (double*)malloc(sizeof(double) * ck_num_row);
@@ -2242,6 +2241,115 @@ void testIis() {
22422241
Highs_destroy(highs);
22432242
}
22442243

2244+
void testFixedLp() {
2245+
// The use of Highs_getFixedLp is illustrated for the MIP
2246+
//
2247+
// Min f = -3x_0 - 2x_1 - x_2
2248+
// s.t. x_0 + x_1 + x_2 <= 7
2249+
// 4x_0 + 2x_1 + x_2 = 12
2250+
// x_0 >=0; x_1 >= 0; x_2 binary
2251+
2252+
const HighsInt num_col = 3;
2253+
const HighsInt num_row = 2;
2254+
const HighsInt num_nz = 6;
2255+
HighsInt a_format = kHighsMatrixFormatColwise;
2256+
HighsInt sense = kHighsObjSenseMinimize;
2257+
double offset = 0;
2258+
2259+
// Define the column costs, lower bounds and upper bounds
2260+
double col_cost[3] = {-3.0, -2.0, -1.0};
2261+
double col_lower[3] = {0.0, 0.0, 0.0};
2262+
double col_upper[3] = {1.0e30, 1.0e30, 1.0};
2263+
// Define the row lower bounds and upper bounds
2264+
double row_lower[2] = {-1.0e30, 12.0};
2265+
double row_upper[2] = {7.0, 12.0};
2266+
// Define the constraint matrix column-wise
2267+
HighsInt a_start[3] = {0, 2, 4};
2268+
HighsInt a_index[6] = {0, 1, 0, 1, 0, 1};
2269+
double a_value[6] = {1.0, 4.0, 1.0, 2.0, 1.0, 1.0};
2270+
HighsInt integrality[3] = {kHighsVarTypeContinuous, kHighsVarTypeContinuous,
2271+
kHighsVarTypeInteger};
2272+
2273+
void* highs = Highs_create();
2274+
Highs_setBoolOptionValue(highs, "output_flag", dev_run);
2275+
Highs_setStringOptionValue(highs, "presolve", "off");
2276+
HighsInt return_status =
2277+
Highs_passMip(highs, num_col, num_row, num_nz, a_format, sense, offset,
2278+
col_cost, col_lower, col_upper, row_lower, row_upper,
2279+
a_start, a_index, a_value, integrality);
2280+
assert(return_status == kHighsStatusOk);
2281+
return_status = Highs_run(highs);
2282+
double mip_objective_function_value;
2283+
return_status = Highs_getDoubleInfoValue(highs, "objective_function_value",
2284+
&mip_objective_function_value);
2285+
assert(return_status == kHighsStatusOk);
2286+
2287+
double* col_value = (double*)malloc(sizeof(double) * num_col);
2288+
return_status = Highs_getSolution(highs, col_value, NULL, NULL, NULL);
2289+
assert(return_status == kHighsStatusOk);
2290+
2291+
HighsInt fixed_lp_num_col;
2292+
HighsInt fixed_lp_num_row;
2293+
HighsInt fixed_lp_num_nz;
2294+
HighsInt fixed_lp_sense;
2295+
double fixed_lp_offset;
2296+
Highs_getFixedLp(highs, kHighsMatrixFormatColwise, &fixed_lp_num_col, &fixed_lp_num_row,
2297+
&fixed_lp_num_nz, &fixed_lp_sense, &fixed_lp_offset, NULL, NULL, NULL, NULL, NULL,
2298+
NULL, NULL, NULL);
2299+
2300+
assert(fixed_lp_num_col == num_col);
2301+
assert(fixed_lp_num_row == num_row);
2302+
assert(fixed_lp_num_nz == num_nz);
2303+
assert(fixed_lp_sense == sense);
2304+
2305+
double* fixed_lp_col_cost = (double*)malloc(sizeof(double) * fixed_lp_num_col);
2306+
double* fixed_lp_col_lower = (double*)malloc(sizeof(double) * fixed_lp_num_col);
2307+
double* fixed_lp_col_upper = (double*)malloc(sizeof(double) * fixed_lp_num_col);
2308+
double* fixed_lp_row_lower = (double*)malloc(sizeof(double) * fixed_lp_num_row);
2309+
double* fixed_lp_row_upper = (double*)malloc(sizeof(double) * fixed_lp_num_row);
2310+
HighsInt* fixed_lp_a_start = (HighsInt*)malloc(sizeof(HighsInt) * fixed_lp_num_col);
2311+
HighsInt* fixed_lp_a_index = (HighsInt*)malloc(sizeof(HighsInt) * fixed_lp_num_nz);
2312+
double* fixed_lp_a_value = (double*)malloc(sizeof(double) * num_nz);
2313+
2314+
// Get the arrays
2315+
Highs_getFixedLp(highs, kHighsMatrixFormatColwise, &fixed_lp_num_col, &fixed_lp_num_row,
2316+
&fixed_lp_num_nz, &fixed_lp_sense, &fixed_lp_offset, fixed_lp_col_cost, fixed_lp_col_lower,
2317+
fixed_lp_col_upper, fixed_lp_row_lower, fixed_lp_row_upper, fixed_lp_a_start, fixed_lp_a_index,
2318+
fixed_lp_a_value);
2319+
2320+
return_status = Highs_passLp(highs,
2321+
fixed_lp_num_col, fixed_lp_num_row, fixed_lp_num_nz,
2322+
kHighsMatrixFormatColwise,
2323+
fixed_lp_sense, fixed_lp_offset,
2324+
fixed_lp_col_cost, fixed_lp_col_lower, fixed_lp_col_upper,
2325+
fixed_lp_row_lower, fixed_lp_row_upper,
2326+
fixed_lp_a_start, fixed_lp_a_index, fixed_lp_a_value);
2327+
assert(return_status == kHighsStatusOk);
2328+
2329+
return_status = Highs_setSolution(highs, col_value, NULL, NULL, NULL);
2330+
assert(return_status == kHighsStatusOk);
2331+
2332+
return_status = Highs_run(highs);
2333+
double objective_function_value;
2334+
return_status = Highs_getDoubleInfoValue(highs, "objective_function_value",
2335+
&objective_function_value);
2336+
assert(return_status == kHighsStatusOk);
2337+
assert(objective_function_value == mip_objective_function_value);
2338+
2339+
2340+
free(col_value);
2341+
free(fixed_lp_col_cost);
2342+
free(fixed_lp_col_lower);
2343+
free(fixed_lp_col_upper);
2344+
free(fixed_lp_row_lower);
2345+
free(fixed_lp_row_upper);
2346+
free(fixed_lp_a_start);
2347+
free(fixed_lp_a_index);
2348+
free(fixed_lp_a_value);
2349+
2350+
Highs_destroy(highs);
2351+
}
2352+
22452353
int main() {
22462354
minimalApiIllegalLp();
22472355
testCallback();
@@ -2265,7 +2373,8 @@ int main() {
22652373
testQpIndefiniteFailure();
22662374
testDualRayTwice();
22672375
testDeleteRowResolveWithBasis();
2268-
testIis();
2376+
testIis();
2377+
testFixedLp();
22692378
return 0;
22702379
}
22712380
// testSetSolution();

highs/interfaces/highs_c_api.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,23 @@ HighsInt Highs_getLp(const void* highs, const HighsInt a_format,
12961296
a_start, a_index, a_value, integrality);
12971297
}
12981298

1299+
HighsInt Highs_getFixedLp(const void* highs, const HighsInt a_format,
1300+
HighsInt* num_col, HighsInt* num_row,
1301+
HighsInt* num_nz, HighsInt* sense, double* offset,
1302+
double* col_cost, double* col_lower,
1303+
double* col_upper, double* row_lower,
1304+
double* row_upper, HighsInt* a_start,
1305+
HighsInt* a_index, double* a_value) {
1306+
HighsLp lp;
1307+
HighsInt status = HighsInt(((Highs*)highs)->getFixedLp(lp));
1308+
if (status == kHighsStatusError) return status;
1309+
HighsInt* integrality = nullptr;
1310+
Highs_getHighsLpData(lp, a_format, num_col, num_row, num_nz, sense, offset,
1311+
col_cost, col_lower, col_upper, row_lower, row_upper,
1312+
a_start, a_index, a_value, integrality);
1313+
return status;
1314+
}
1315+
12991316
HighsInt Highs_getPresolvedLp(const void* highs, const HighsInt a_format,
13001317
HighsInt* num_col, HighsInt* num_row,
13011318
HighsInt* num_nz, HighsInt* sense, double* offset,

highs/interfaces/highs_c_api.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,6 +2261,30 @@ HighsInt Highs_getIisLp(const void* highs, const HighsInt a_format,
22612261
double* row_upper, HighsInt* a_start, HighsInt* a_index,
22622262
double* a_value, HighsInt* integrality);
22632263

2264+
/**
2265+
* Get the LP corresponding to a MIP with non-continuous variables
2266+
* fixed at a MIP solution
2267+
*
2268+
* The input arguments have the same meaning (in a different order) to those
2269+
* used in `Highs_passModel`.
2270+
*
2271+
* Note that all arrays must be pre-allocated to the correct size before calling
2272+
* `Highs_getModel`. Use the following query methods to check the appropriate
2273+
* size:
2274+
* - `Highs_getNumCol`
2275+
* - `Highs_getNumRow`
2276+
* - `Highs_getNumNz`
2277+
*
2278+
* @returns A `kHighsStatus` constant indicating whether the call succeeded.
2279+
*/
2280+
HighsInt Highs_getFixedLp(const void* highs, const HighsInt a_format,
2281+
HighsInt* num_col, HighsInt* num_row,
2282+
HighsInt* num_nz, HighsInt* sense, double* offset,
2283+
double* col_cost, double* col_lower,
2284+
double* col_upper, double* row_lower,
2285+
double* row_upper, HighsInt* a_start,
2286+
HighsInt* a_index, double* a_value);
2287+
22642288
/**
22652289
* Set a primal (and possibly dual) solution as a starting point, then run
22662290
* crossover to compute a basic feasible solution.

0 commit comments

Comments
 (0)