//#include //#include #include #include #include "ampl/ampl_c.h" int main(int argc, char **argv) { // Create an AMPL instance AMPL *ampl; AMPL_CALL(AMPL_Create(&l)); /* // If the AMPL installation directory is not in the system search path: AMPL_ENVIRONMENT *env; AMPL_EnvironmentCreate(&env, "full path to the AMPL installation directory", ""); AMPL_CALL(AMPL_CreateWithEnv(&l, env)); */ if (argc > 1) AMPL_CALL(AMPL_SetOption(ampl, "solver", argv[1])); const char *modelDirectory = argc == 3 ? argv[2] : "../models"; char dir[256]; char mod[256]; char dat[256]; char run[256]; sprintf(dir, "%s%s", modelDirectory, "/tracking"); sprintf(mod, "%s%s", modelDirectory, "/tracking/tracking.mod"); sprintf(dat, "%s%s", modelDirectory, "/tracking/tracking.dat"); sprintf(run, "%s%s", modelDirectory, "/tracking/trackingbit.run"); // Load the AMPL model from file AMPL_CALL(AMPL_Read(ampl, mod)); // Read data AMPL_CALL(AMPL_ReadData(ampl, dat)); // Read table declarations AMPL_CALL(AMPL_Read(ampl, run)); // Set tables directory (parameter used in the script above) AMPL_CALL(AMPL_ParameterSetString(ampl, "data_dir", dir)); // Read tables AMPL_CALL(AMPL_ReadTable(ampl, "assets")); AMPL_CALL(AMPL_ReadTable(ampl, "indret")); AMPL_CALL(AMPL_ReadTable(ampl, "returns")); // Relax the integrality AMPL_CALL(AMPL_SetBoolOption(ampl, "relax_integrality", true)); // Solve the problem AMPL_CALL(AMPL_Solve(ampl, "", "")); double value; AMPL_CALL(AMPL_GetValueNumeric(ampl, "cst", &value)); printf("QP objective value %f\n", value); double lowcutoff = 0.04; double highcutoff = 0.1; // Get the variable representing the (relaxed) solution vector AMPL_DATAFRAME *holdvalues; AMPL_CALL(AMPL_EntityGetValues(ampl, "hold", NULL, 0, &holdvalues)); size_t nrows; AMPL_CALL(AMPL_DataFrameGetNumRows(holdvalues, &nrows)); double *toHold; toHold = (double*) malloc(nrows * sizeof(double)); // For each asset, if it was held by more than the highcutoff, // forces it in the model, if less than lowcutoff, forces it out size_t holdindex; AMPL_CALL(AMPL_DataFrameGetColumnIndex(holdvalues, "hold.val", &holdindex)); for (size_t i = 0; i < nrows; i++) { AMPL_VARIANT *value; AMPL_CALL(AMPL_DataFrameElement(holdvalues, i, holdindex, &value)); double holdvalue; AMPL_VariantGetNumericValue(value, &holdvalue); if (holdvalue < lowcutoff) toHold[i] = 0; else if (holdvalue > highcutoff) toHold[i] = 2; else toHold[i] = 1; } AMPL_DataFrameFree(&holdvalues); // uses those values for the parameter ifinuniverse, which controls // which // stock is included or not in the solution AMPL_CALL(AMPL_ParameterSetArgsDoubleValues(ampl, "ifinuniverse", nrows, toHold)); free(toHold); // Get back to the integer problem AMPL_CALL(AMPL_SetBoolOption(ampl, "relax_integrality", false)); // Solve the (integer) problem AMPL_CALL(AMPL_Solve(ampl, "", "")); AMPL_CALL(AMPL_GetValueNumeric(ampl, "cst", &value)); printf("QMIP objective value %f\n", value); // Free the AMPL instance //AMPL_EnvironmentFree(&env); AMPL_Free(&l); return 0; }