#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "interfaces/highs_c_api.h"
void minimal_api() {
const HighsInt num_col = 2;
const HighsInt num_row = 3;
const HighsInt num_nz = 5;
HighsInt sense = kHighsObjSenseMinimize;
const double offset = 3;
const double col_cost[2] = {1.0, 1.0};
const double col_lower[2] = {0.0, 1.0};
const double col_upper[2] = {4.0, 1.0e30};
const double row_lower[3] = {-1.0e30, 5.0, 6.0};
const double row_upper[3] = {7.0, 15.0, 1.0e30};
const HighsInt a_format = kHighsMatrixFormatColwise;
const HighsInt a_start[2] = {0, 2};
const HighsInt a_index[5] = {1, 2, 0, 1, 2};
const double a_value[5] = {1.0, 3.0, 1.0, 2.0, 2.0};
double objective_value;
double* col_value = (double*)malloc(sizeof(double) * num_col);
double* col_dual = (double*)malloc(sizeof(double) * num_col);
double* row_value = (double*)malloc(sizeof(double) * num_row);
double* row_dual = (double*)malloc(sizeof(double) * num_row);
HighsInt* col_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_col);
HighsInt* row_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_row);
HighsInt model_status;
HighsInt run_status;
run_status =
Highs_lpCall(num_col, num_row, num_nz, a_format, sense, offset, col_cost,
col_lower, col_upper, row_lower, row_upper, a_start, a_index,
a_value, col_value, col_dual, row_value, row_dual,
col_basis_status, row_basis_status, &model_status);
assert(run_status == kHighsStatusOk);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
objective_value = offset;
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "\n",
i, col_value[i], col_dual[i], col_basis_status[i]);
objective_value += col_value[i] * col_cost[i];
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "\n",
i, row_value[i], row_dual[i], row_basis_status[i]);
}
printf("Optimal objective value = %g\n", objective_value);
sense = kHighsObjSenseMaximize;
run_status =
Highs_lpCall(num_col, num_row, num_nz, a_format, sense, offset, col_cost,
col_lower, col_upper, row_lower, row_upper, a_start, a_index,
a_value, col_value, col_dual, row_value, row_dual,
col_basis_status, row_basis_status, &model_status);
assert(run_status == kHighsStatusOk);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
objective_value = offset;
for (HighsInt i = 0; i < num_col; i++)
objective_value += col_value[i] * col_cost[i];
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "\n",
i, col_value[i], col_dual[i], col_basis_status[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "\n",
i, row_value[i], row_dual[i], row_basis_status[i]);
}
printf("Optimal objective value = %g\n", objective_value);
HighsInt integrality[2] = {1, 1};
run_status = Highs_mipCall(num_col, num_row, num_nz, a_format, sense, offset,
col_cost, col_lower, col_upper, row_lower,
row_upper, a_start, a_index, a_value, integrality,
col_value, row_value, &model_status);
assert(run_status == kHighsStatusOk);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
objective_value = offset;
for (HighsInt i = 0; i < num_col; i++)
objective_value += col_value[i] * col_cost[i];
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT " = %lf\n", i, col_value[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT " = %lf\n", i, row_value[i]);
}
printf("Optimal objective value = %g\n", objective_value);
free(col_value);
free(col_dual);
free(row_value);
free(row_dual);
free(col_basis_status);
free(row_basis_status);
}
void minimal_api_qp() {
const HighsInt num_col = 3;
const HighsInt num_row = 1;
const HighsInt num_nz = 3;
HighsInt sense = kHighsObjSenseMinimize;
const double offset = 0;
const double col_cost[3] = {0.0, -1.0, 0.0};
const double col_lower[3] = {0.0, 0.0, 0.0};
const double col_upper[3] = {1.0e30, 1.0e30, 1.0e30};
const double row_lower[1] = {1};
const double row_upper[1] = {1.0e30};
const HighsInt a_format = kHighsMatrixFormatRowwise;
const HighsInt a_start[2] = {0, 3};
const HighsInt a_index[3] = {0, 1, 2};
const double a_value[3] = {1.0, 1.0, 1.0};
const HighsInt q_format = kHighsHessianFormatTriangular;
const HighsInt q_num_nz = 4;
const HighsInt q_start[3] = {0, 2, 3};
const HighsInt q_index[4] = {0, 2, 1, 2};
const double q_value[4] = {2.0, -1.0, 0.2, 2.0};
double objective_value;
double* col_value = (double*)malloc(sizeof(double) * num_col);
double* col_dual = (double*)malloc(sizeof(double) * num_col);
double* row_value = (double*)malloc(sizeof(double) * num_row);
double* row_dual = (double*)malloc(sizeof(double) * num_row);
HighsInt* col_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_col);
HighsInt* row_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_row);
HighsInt model_status;
HighsInt run_status;
run_status = Highs_qpCall(
num_col, num_row, num_nz, q_num_nz, a_format, q_format, sense, offset,
col_cost, col_lower, col_upper, row_lower, row_upper, a_start, a_index,
a_value, q_start, q_index, q_value, col_value, col_dual, row_value,
row_dual, col_basis_status, row_basis_status, &model_status);
assert(run_status == kHighsStatusOk);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
objective_value = offset;
for (HighsInt i = 0; i < num_col; i++)
objective_value += col_value[i] * col_cost[i];
for (HighsInt i = 0; i < num_col; i++) {
HighsInt from_el = q_start[i];
HighsInt to_el;
if (i + 1 < num_col) {
to_el = q_start[i + 1];
} else {
to_el = q_num_nz;
}
for (HighsInt el = from_el; el < to_el; el++) {
HighsInt j = q_index[el];
objective_value += 0.5 * col_value[i] * col_value[j] * q_value[el];
}
}
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT " = %lf; dual = %lf\n", i, col_value[i],
col_dual[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT " = %lf; dual = %lf\n", i, row_value[i],
row_dual[i]);
}
printf("Optimal objective value = %g\n", objective_value);
free(col_value);
free(col_dual);
free(row_value);
free(row_dual);
free(col_basis_status);
free(row_basis_status);
}
void minimal_api_mps() {
const char* filename = "../HiGHS/check/instances/avgas.mps";
void* highs = Highs_create();
int run_status;
run_status = Highs_readModel(highs, filename);
assert(run_status == kHighsStatusOk);
run_status = Highs_run(highs);
int model_status = Highs_getModelStatus(highs);
assert(run_status == kHighsStatusOk);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %d; Model status = %d\n", run_status, model_status);
double objective_function_value;
Highs_getDoubleInfoValue(highs, "objective_function_value",
&objective_function_value);
printf("Optimal objective value = %g\n", objective_function_value);
assert(fabs(objective_function_value + 7.75) < 1e-5);
}
void full_api() {
printf("\nHiGHS version %s\n", Highs_version());
printf(" Major version %" HIGHSINT_FORMAT "\n", Highs_versionMajor());
printf(" Minor version %" HIGHSINT_FORMAT "\n", Highs_versionMinor());
printf(" Patch version %" HIGHSINT_FORMAT "\n", Highs_versionPatch());
printf(" Githash %s\n", Highs_githash());
const HighsInt num_col = 2;
const HighsInt num_row = 3;
const HighsInt num_nz = 5;
HighsInt sense = kHighsObjSenseMinimize;
const double offset = 3;
const double col_cost[2] = {1.0, 1.0};
const double col_lower[2] = {0.0, 1.0};
const double col_upper[2] = {4.0, 1.0e30};
const double row_lower[3] = {-1.0e30, 5.0, 6.0};
const double row_upper[3] = {7.0, 15.0, 1.0e30};
const HighsInt a_format = kHighsMatrixFormatColwise;
const HighsInt a_start[2] = {0, 2};
const HighsInt a_index[5] = {1, 2, 0, 1, 2};
const double a_value[5] = {1.0, 3.0, 1.0, 2.0, 2.0};
HighsInt run_status;
HighsInt model_status;
double objective_function_value;
HighsInt simplex_iteration_count;
int64_t mip_node_count;
HighsInt primal_solution_status;
HighsInt dual_solution_status;
HighsInt basis_validity;
void* highs = Highs_create();
run_status = Highs_passLp(highs, num_col, num_row, num_nz, a_format, sense,
offset, col_cost, col_lower, col_upper, row_lower,
row_upper, a_start, a_index, a_value);
assert(run_status == kHighsStatusOk);
run_status = Highs_run(highs);
assert(run_status == kHighsStatusOk);
model_status = Highs_getModelStatus(highs);
assert(model_status == kHighsModelStatusOptimal);
printf("Run status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
Highs_getDoubleInfoValue(highs, "objective_function_value",
&objective_function_value);
Highs_getIntInfoValue(highs, "simplex_iteration_count",
&simplex_iteration_count);
Highs_getIntInfoValue(highs, "primal_solution_status",
&primal_solution_status);
Highs_getIntInfoValue(highs, "dual_solution_status", &dual_solution_status);
Highs_getIntInfoValue(highs, "basis_validity", &basis_validity);
assert(primal_solution_status == kHighsSolutionStatusFeasible);
assert(dual_solution_status == kHighsSolutionStatusFeasible);
assert(basis_validity == kHighsBasisValidityValid);
double* col_value = (double*)malloc(sizeof(double) * num_col);
double* col_dual = (double*)malloc(sizeof(double) * num_col);
double* row_value = (double*)malloc(sizeof(double) * num_row);
double* row_dual = (double*)malloc(sizeof(double) * num_row);
HighsInt* col_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_col);
HighsInt* row_basis_status = (HighsInt*)malloc(sizeof(HighsInt) * num_row);
Highs_getSolution(highs, col_value, col_dual, row_value, row_dual);
Highs_getBasis(highs, col_basis_status, row_basis_status);
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, col_value[i], col_dual[i], col_basis_status[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, row_value[i], row_dual[i], row_basis_status[i]);
}
printf("Objective value = %g; Iteration count = %" HIGHSINT_FORMAT "\n",
objective_function_value, simplex_iteration_count);
HighsInt check_sense;
run_status = Highs_getObjectiveSense(highs, &check_sense);
assert(run_status == 0);
printf("LP problem has objective sense = %" HIGHSINT_FORMAT "\n",
check_sense);
assert(check_sense == sense);
Highs_changeObjectiveSense(highs, kHighsObjSenseMaximize);
run_status = Highs_run(highs);
assert(run_status == kHighsStatusOk);
model_status = Highs_getModelStatus(highs);
assert(model_status == kHighsModelStatusOptimal);
printf("Run status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
Highs_getDoubleInfoValue(highs, "objective_function_value",
&objective_function_value);
Highs_getIntInfoValue(highs, "simplex_iteration_count",
&simplex_iteration_count);
Highs_getIntInfoValue(highs, "primal_solution_status",
&primal_solution_status);
Highs_getIntInfoValue(highs, "dual_solution_status", &dual_solution_status);
Highs_getIntInfoValue(highs, "basis_validity", &basis_validity);
assert(primal_solution_status == kHighsSolutionStatusFeasible);
assert(dual_solution_status == kHighsSolutionStatusFeasible);
assert(basis_validity == kHighsBasisValidityValid);
Highs_getSolution(highs, col_value, col_dual, row_value, row_dual);
Highs_getBasis(highs, col_basis_status, row_basis_status);
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, col_value[i], col_dual[i], col_basis_status[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, row_value[i], row_dual[i], row_basis_status[i]);
}
printf("Objective value = %g; Iteration count = %" HIGHSINT_FORMAT "\n",
objective_function_value, simplex_iteration_count);
Highs_clearModel(highs);
const HighsInt check_num_col = Highs_getNumCol(highs);
const HighsInt check_num_row = Highs_getNumRow(highs);
const HighsInt check_num_nz = Highs_getNumNz(highs);
assert(check_num_col == 0);
assert(check_num_row == 0);
assert(check_num_nz == 0);
printf("\nCleared model has %" HIGHSINT_FORMAT " columns, %" HIGHSINT_FORMAT
" rows and %" HIGHSINT_FORMAT " nonzeros\n",
check_num_col, check_num_row, check_num_nz);
const HighsInt ar_start[3] = {0, 1, 3};
const HighsInt ar_index[5] = {1, 0, 1, 0, 1};
const double ar_value[5] = {1.0, 1.0, 2.0, 3.0, 2.0};
run_status = Highs_addCols(highs, num_col, col_cost, col_lower, col_upper, 0,
NULL, NULL, NULL);
assert(run_status == 0);
run_status = Highs_addRows(highs, num_row, row_lower, row_upper, num_nz,
ar_start, ar_index, ar_value);
assert(run_status == 0);
Highs_changeObjectiveSense(highs, kHighsObjSenseMaximize);
Highs_changeObjectiveOffset(highs, offset);
run_status = Highs_getObjectiveSense(highs, &check_sense);
assert(run_status == 0);
printf("LP problem has objective sense = %" HIGHSINT_FORMAT "\n",
check_sense);
assert(check_sense == kHighsObjSenseMaximize);
HighsInt option_type;
const char* option_string = "primal_feasibility_tolerance";
run_status = Highs_getOptionType(highs, option_string, &option_type);
printf("Option %s is of type %" HIGHSINT_FORMAT "\n", option_string,
option_type);
assert(run_status == kHighsStatusOk);
assert(option_type == 2);
double primal_feasibility_tolerance;
Highs_getDoubleOptionValue(highs, "primal_feasibility_tolerance",
&primal_feasibility_tolerance);
printf("primal_feasibility_tolerance = %g: setting it to 1e-6\n",
primal_feasibility_tolerance);
primal_feasibility_tolerance = 1e-6;
Highs_setDoubleOptionValue(highs, "primal_feasibility_tolerance",
primal_feasibility_tolerance);
Highs_setBoolOptionValue(highs, "output_flag", 0);
printf("Running quietly...\n");
run_status = Highs_run(highs);
printf("Running loudly...\n");
Highs_setBoolOptionValue(highs, "output_flag", 1);
assert(run_status == 0);
model_status = Highs_getModelStatus(highs);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
HighsInt info_type;
const char* info_string = "objective_function_value";
run_status = Highs_getInfoType(highs, info_string, &info_type);
printf("Info %s is of type %" HIGHSINT_FORMAT "\n", info_string, info_type);
assert(run_status == kHighsStatusOk);
assert(info_type == kHighsInfoTypeDouble);
Highs_getDoubleInfoValue(highs, "objective_function_value",
&objective_function_value);
Highs_getIntInfoValue(highs, "simplex_iteration_count",
&simplex_iteration_count);
Highs_getIntInfoValue(highs, "primal_solution_status",
&primal_solution_status);
Highs_getIntInfoValue(highs, "dual_solution_status", &dual_solution_status);
Highs_getIntInfoValue(highs, "basis_validity", &basis_validity);
assert(primal_solution_status == kHighsSolutionStatusFeasible);
assert(dual_solution_status == kHighsSolutionStatusFeasible);
assert(basis_validity == kHighsBasisValidityValid);
Highs_getSolution(highs, col_value, col_dual, row_value, row_dual);
Highs_getBasis(highs, col_basis_status, row_basis_status);
for (HighsInt i = 0; i < num_col; i++) {
printf("Col%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, col_value[i], col_dual[i], col_basis_status[i]);
}
for (HighsInt i = 0; i < num_row; i++) {
printf("Row%" HIGHSINT_FORMAT
" = %lf; dual = %lf; status = %" HIGHSINT_FORMAT "; \n",
i, row_value[i], row_dual[i], row_basis_status[i]);
}
printf("Objective value = %g; Iteration count = %" HIGHSINT_FORMAT "\n",
objective_function_value, simplex_iteration_count);
HighsInt integrality[2] = {1, 1};
Highs_changeColsIntegralityByRange(highs, 0, 1, integrality);
Highs_setBoolOptionValue(highs, "output_flag", 0);
run_status = Highs_run(highs);
Highs_setBoolOptionValue(highs, "output_flag", 1);
assert(run_status == kHighsStatusOk);
model_status = Highs_getModelStatus(highs);
assert(model_status == kHighsModelStatusOptimal);
printf("\nRun status = %" HIGHSINT_FORMAT "; Model status = %" HIGHSINT_FORMAT
"\n",
run_status, model_status);
Highs_getDoubleInfoValue(highs, "objective_function_value",
&objective_function_value);
Highs_getIntInfoValue(highs, "simplex_iteration_count",
&simplex_iteration_count);
Highs_getInt64InfoValue(highs, "mip_node_count", &mip_node_count);
Highs_getIntInfoValue(highs, "primal_solution_status",
&primal_solution_status);
Highs_getIntInfoValue(highs, "dual_solution_status", &dual_solution_status);
Highs_getIntInfoValue(highs, "basis_validity", &basis_validity);
assert(primal_solution_status == kHighsSolutionStatusFeasible);
assert(dual_solution_status == kHighsSolutionStatusNone);
assert(basis_validity == kHighsBasisValidityInvalid);
assert(mip_node_count == 1);
Highs_getSolution(highs, col_value, col_dual, row_value, row_dual);
for (HighsInt i = 0; i < num_col; i++)
printf("Col%" HIGHSINT_FORMAT " = %lf\n", i, col_value[i]);
for (HighsInt i = 0; i < num_row; i++)
printf("Row%" HIGHSINT_FORMAT " = %lf\n", i, row_value[i]);
printf("Objective value = %g; Iteration count = %" HIGHSINT_FORMAT "\n",
objective_function_value, simplex_iteration_count);
free(col_value);
free(col_dual);
free(row_value);
free(row_dual);
free(col_basis_status);
free(row_basis_status);
Highs_destroy(highs);
}
int main() {
minimal_api();
minimal_api_qp();
minimal_api_mps();
full_api();
return 0;
}