/* A specification for the ORD file format can be found in the * ILOG CPLEX 7.0 Reference Manual page 545. */ void lps_mstfile( const Lps* lp, FILE* fp, LpFormat format, const char* text) { const Var* var; int name_size; char* vtmp; assert(lp != NULL); assert(fp != NULL); assert(format == LP_FORM_LPF || format == LP_FORM_MPS); name_size = lps_getnamesize(lp, format); vtmp = malloc((size_t)name_size); assert(vtmp != NULL); if (text != NULL) fprintf(fp, "* %s\n", text); fprintf(fp, "NAME %8.8s\n", lp->name); for(var = lp->var_root; var != NULL; var = var->next) { if (var->vclass == VAR_CON) continue; if (var->size == 0) continue; lps_makename(vtmp, name_size, var->name, var->number); fprintf(fp, " %-*s %.10e", name_size - 1, vtmp, mpq_get_d(var->startval)); fputc('\n', fp); } fprintf(fp, "ENDATA\n"); free(vtmp); }
void lps_transtable(const Lps* lp, FILE* fp, LpFormat format, const char* head) { Var* var; Con* con; char* temp; int namelen; assert(lps_valid(lp)); assert(fp != NULL); assert(head != NULL); assert(format == LP_FORM_LPF || format == LP_FORM_MPS || format == LP_FORM_RLP || format == LP_FORM_PIP); namelen = lps_getnamesize(lp, format); temp = malloc((size_t)namelen); assert(temp != NULL); lps_number(lp); for(var = lp->var_root; var != NULL; var = var->next) { lps_makename(temp, namelen, var->name, var->number); if (var->type == VAR_FIXED) fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\t%.16e\n", head, var->number, namelen - 1, temp, var->name, mpq_get_d(var->lower)); else { if (var->size > 0 || !mpq_equal(var->cost, const_zero)) fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\n", head, var->number, namelen - 1, temp, var->name); } } for(con = lp->con_root; con != NULL; con = con->next) { lps_makename(temp, namelen, con->name, con->number); fprintf(fp, "%s\tc %7d\t%-*s\t\"%s\"\t%.16e\n", head, con->number, namelen - 1, temp, con->name, mpq_get_d(con->scale)); } free(temp); }
/* A specification for the LP file format can be found in the * ILOG CPLEX 7.0 Reference Manual page 527. * ILOG CPLEX 8.0 Reference Manual page 595. * The "Lazy Constraints" section seems to be undocumented. */ void lpf_write( const Lps* lp, FILE* fp, LpFormat format, const char* text) { const Var* var; Con* con; Con** contab; Bool have_integer = FALSE; Bool have_separate = FALSE; Bool have_checkonly = FALSE; int cnt; int i; int k; int name_size; char* name; assert(lp != NULL); assert(fp != NULL); /* Store constraint pointers and permute them * (add 1 in case lp->cons == 0) */ contab = calloc((size_t)lp->cons + 1, sizeof(*contab)); assert(contab != NULL); k = 0; for(con = lp->con_root; con != NULL; con = con->next) contab[k++] = con; assert(k == lp->cons); if (format == LP_FORM_RLP) permute(lp->cons, (void**)contab); name_size = lps_getnamesize(lp, LP_FORM_LPF); name = malloc((size_t)name_size); assert(name != NULL); if (text != NULL) fprintf(fp, "%s", text); fprintf(fp, "\\Problem name: %s\n", lp->name); fprintf(fp, "%s\n", (lp->direct == LP_MIN) ? "Minimize" : "Maximize"); fprintf(fp, " %s: ", lp->objname == NULL ? "Objective" : lp->objname); for(var = lp->var_root, cnt = 0; var != NULL; var = var->next) { /* If cost is zero, do not include in objective function */ if (mpq_equal(var->cost, const_zero)) continue; lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number); if (mpq_equal(var->cost, const_one)) fprintf(fp, " + %s", name); else if (mpq_equal(var->cost, const_minus_one)) fprintf(fp, " - %s", name); else { fprintf(fp, " "); write_val(fp, format, TRUE, var->cost); fprintf(fp, " %s", name); } if (++cnt % 6 == 0) fprintf(fp, "\n "); } /* ---------------------------------------------------------------------- */ /* First loop run for normal constraints, second one for * user cuts, thrid one for lazy constraints, if any. */ for(i = 0; i < 3; i++) { if (i == 0) fprintf(fp, "\nSubject to\n"); else if (i == 1) { if (!have_separate) continue; else fprintf(fp, "\nUser Cuts\n"); } else if (i == 2) { if (!have_checkonly) continue; else fprintf(fp, "\nLazy Constraints\n"); } for(k = 0; k < lp->cons; k++) { con = contab[k]; if (con->size == 0 && con->qme_first == NULL && con->term == NULL) continue; if (i == 0 && ((con->flags & (LP_FLAG_CON_SEPAR | LP_FLAG_CON_CHECK)) != 0)) { if ((con->flags & LP_FLAG_CON_SEPAR) == LP_FLAG_CON_SEPAR) have_separate = TRUE; if ((con->flags & LP_FLAG_CON_CHECK) == LP_FLAG_CON_CHECK) have_checkonly = TRUE; continue; } if (i == 1 && (con->flags & LP_FLAG_CON_SEPAR) != LP_FLAG_CON_SEPAR) continue; if (i == 2 && (con->flags & LP_FLAG_CON_CHECK) != LP_FLAG_CON_CHECK) continue; if (con->type == CON_RANGE) { if (format == LP_FORM_HUM) { lps_makename(name, name_size, con->name, -1); fprintf(fp, " %s:\n ", name); write_lhs(fp, format, con, CON_RANGE); write_row(fp, format, con, name, name_size); write_rhs(fp, format, con, CON_RANGE); } else { /* Split ranges, because LP format can't handle them. */ lps_makename(name, name_size, con->name, con->number); fprintf(fp, " %sR:\n ", name); write_row(fp, format, con, name, name_size); /* changes name */ write_rhs(fp, format, con, CON_RHS); lps_makename(name, name_size, con->name, con->number); fprintf(fp, " %sL:\n ", name); write_row(fp, format, con, name, name_size); /* changes name */ write_rhs(fp, format, con, CON_LHS); } } else { lps_makename(name, name_size, con->name, format == LP_FORM_HUM ? -1 : con->number); if (i == 0) fprintf(fp, " %s:\n ", name); else if (i == 1) fprintf(fp, " %sU:\n ", name); else if (i == 2) fprintf(fp, " %sZ:\n ", name); if (con->ind_var != NULL) { lps_makename(name, name_size, con->ind_var->name, format == LP_FORM_HUM ? -1 : con->ind_var->number); fprintf(fp, "%s = %d -> ", name, con->ind_dir ? 1 : 0); } write_row(fp, format, con, name, name_size); write_rhs(fp, format, con, con->type); } } } /* ---------------------------------------------------------------------- */ fprintf(fp, "Bounds\n"); for(var = lp->var_root; var != NULL; var = var->next) { /* A variable without any entries in the matrix * or the objective function can be ignored. * (also not part of an SOS or quadratic constraint) */ if (var->size == 0 && mpq_equal(var->cost, const_zero) && !var->is_used) continue; lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number); if (var->type == VAR_FIXED) { fprintf(fp, " %s = ", name); write_val(fp, format, FALSE, var->lower); fprintf(fp, "\n"); } else { /* Check if we have integer variables */ if (var->vclass == VAR_INT) have_integer = TRUE; fprintf(fp, " "); if (var->type == VAR_LOWER || var->type == VAR_BOXED) write_val(fp, format, FALSE, var->lower); else fprintf(fp, "-inf"); fprintf(fp, " <= %s <= ", name); if (var->type == VAR_UPPER || var->type == VAR_BOXED) { write_val(fp, format, FALSE, var->upper); fprintf(fp, "\n"); } else fprintf(fp, "+inf\n"); } } /* ---------------------------------------------------------------------- */ if (have_integer) { fprintf(fp, "General\n"); for(var = lp->var_root; var != NULL; var = var->next) { if (var->vclass != VAR_INT) continue; if (var->size == 0 && mpq_equal(var->cost, const_zero) && !var->is_used) continue; lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number); fprintf(fp, " %s\n", name); } } /* ---------------------------------------------------------------------- */ if (lps_has_sos(lp)) { const Sos* sos; const Sse* sse; fprintf(fp, "SOS\n"); for(sos = lp->sos_root; sos != NULL; sos = sos->next) { cnt = 0; fprintf(fp, " %s:S%d:: ", sos->name, sos->type == SOS_TYPE1 ? 1 : 2); for(sse = sos->first; sse != NULL; sse = sse->next) { lps_makename(name, name_size, sse->var->name, format == LP_FORM_HUM ? -1 : sse->var->number); fprintf(fp, " %s:", name); write_val(fp, format, FALSE, sse->weight); if (++cnt % 6 == 0) fputc('\n', fp); } if (cnt % 6 != 0) fputc('\n', fp); } } fprintf(fp, "End\n"); free(name); free(contab); }