📄 lpkit.c
字号:
MALLOC(scalechange, lp->sum + 1);
/* initialise min and max values */
for(i = 0; i <= lp->rows; i++) {
row_max[i] = 0;
row_min[i] = lp->infinite;
}
/* calculate min and max absolute values of rows */
for(j = 1; j <= lp->columns; j++)
for(i = lp->col_end[j - 1]; i < lp->col_end[j]; i++) {
row_nr = lp->mat[i].row_nr;
absval = my_abs(lp->mat[i].value);
if(absval != 0) {
row_max[row_nr] = my_max(row_max[row_nr], absval);
row_min[row_nr] = my_min(row_min[row_nr], absval);
}
}
/* calculate scale factors for rows */
for(i = 0; i <= lp->rows; i++) {
scalechange[i] = minmax_to_scale(row_min[i], row_max[i]);
lp->scale[i] *= scalechange[i];
}
/* now actually scale the matrix */
for(j = 1; j <= lp->columns; j++)
for(i = lp->col_end[j - 1]; i < lp->col_end[j]; i++)
lp->mat[i].value *= scalechange[lp->mat[i].row_nr];
/* and scale the rhs and the row bounds (RANGES in MPS!!) */
for(i = 0; i <= lp->rows; i++) {
lp->orig_rh[i] *= scalechange[i];
if((lp->orig_upbo[i] < lp->infinite) && (lp->orig_upbo[i] != 0))
lp->orig_upbo[i] *= scalechange[i];
if(lp->orig_lowbo[i] != 0)
lp->orig_lowbo[i] *= scalechange[i];
}
free(row_max);
free(row_min);
/* calculate column scales */
for(j = 1; j <= lp->columns; j++) {
if(lp->must_be_int[lp->rows + j]) { /* do not scale integer columns */
scalechange[lp->rows + j] = 1;
}
else {
col_max = 0;
col_min = lp->infinite;
for(i = lp->col_end[j - 1]; i < lp->col_end[j]; i++) {
if(lp->mat[i].value != 0) {
col_max = my_max(col_max, my_abs(lp->mat[i].value));
col_min = my_min(col_min, my_abs(lp->mat[i].value));
}
}
scalechange[lp->rows + j] = minmax_to_scale(col_min, col_max);
lp->scale[lp->rows + j] *= scalechange[lp->rows + j];
}
}
/* scale mat */
for(j = 1; j <= lp->columns; j++)
for(i = lp->col_end[j - 1]; i < lp->col_end[j]; i++)
lp->mat[i].value *= scalechange[lp->rows + j];
/* scale bounds as well */
for(i = lp->rows + 1; i <= lp->sum; i++) { /* was < *//* changed by PN */
if(lp->orig_lowbo[i] != 0)
lp->orig_lowbo[i] /= scalechange[i];
if(lp->orig_upbo[i] != lp->infinite)
lp->orig_upbo[i] /= scalechange[i];
}
lp->columns_scaled = TRUE;
free(scalechange);
lp->scaling_used = TRUE;
lp->eta_valid = FALSE;
}
void reset_basis(lprec *lp)
{
lp->basis_valid = FALSE;
}
void print_solution(lprec *lp)
{
int i;
FILE *stream;
stream = stdout;
fprintf(stream, "Value of objective function: %g\n",
(double)lp->best_solution[0]);
/* print normal variables */
for(i = 1; i <= lp->columns; i++)
if(lp->names_used)
fprintf(stream, "%-20s %g\n", lp->col_name[i],
(double)lp->best_solution[lp->rows + i]);
else
fprintf(stream, "Var [%d] %g\n", i,
(double)lp->best_solution[lp->rows + i]);
/* print achieved constraint values */
if(lp->verbose) {
fprintf(stream, "\nActual values of the constraints:\n");
for(i = 1; i <= lp->rows; i++)
if(lp->names_used)
fprintf(stream, "%-20s %g\n", lp->row_name[i],
(double)lp->best_solution[i]);
else
fprintf(stream, "Row [%d] %g\n", i,
(double)lp->best_solution[i]);
}
if((lp->verbose || lp->print_duals)) {
if(lp->max_level != 1)
fprintf(stream,
"These are the duals from the node that gave the optimal solution.\n");
else
fprintf(stream, "\nDual values:\n");
for(i = 1; i <= lp->rows; i++)
if(lp->names_used)
fprintf(stream, "%-20s %g\n", lp->row_name[i],
(double)lp->duals[i]);
else
fprintf(stream, "Row [%d] %g\n", i, (double)lp->duals[i]);
}
fflush(stream);
} /* Printsolution */
void write_LP(lprec *lp, FILE *output)
{
int i, j;
REAL *row;
MALLOC(row, lp->columns+1);
if(lp->maximise)
fprintf(output, "max:");
else
fprintf(output, "min:");
get_row(lp, 0, row);
for(i = 1; i <= lp->columns; i++)
if(row[i] != 0) {
if(row[i] == -1)
fprintf(output, " -");
else if(row[i] == 1)
fprintf(output, " +");
else
fprintf(output, " %+g ", (double)row[i]);
if(lp->names_used)
fprintf(output, "%s", lp->col_name[i]);
else
fprintf(output, "x%d", i);
}
fprintf(output, ";\n");
for(j = 1; j <= lp->rows; j++) {
if(lp->names_used)
fprintf(output, "%s:", lp->row_name[j]);
get_row(lp, j, row);
for(i = 1; i <= lp->columns; i++)
if(row[i] != 0) {
if(row[i] == -1)
fprintf(output, " -");
else if(row[i] == 1)
fprintf(output, " +");
else
fprintf(output, " %+g ", (double)row[i]);
if(lp->names_used)
fprintf(output, "%s", lp->col_name[i]);
else
fprintf(output, "x%d", i);
}
if(lp->orig_upbo[j] == 0)
fprintf(output, " =");
else if(lp->ch_sign[j])
fprintf(output, " >");
else
fprintf(output, " <");
if(lp->ch_sign[j])
fprintf(output, " %16g;\n", (double)-lp->orig_rh[j]);
else
fprintf(output, " %16g;\n", (double)lp->orig_rh[j]);
}
for(i = lp->rows + 1; i <= lp->sum; i++) {
if(lp->orig_lowbo[i] != 0) {
if(lp->names_used)
fprintf(output, "%s > %16g;\n", lp->col_name[i - lp->rows],
(double)lp->orig_lowbo[i]);
else
fprintf(output, "x%d > %16g;\n", i - lp->rows,
(double)lp->orig_lowbo[i]);
}
if(lp->orig_upbo[i] != lp->infinite) {
if(lp->names_used)
fprintf(output, "%s < %16g;\n", lp->col_name[i - lp->rows],
(double)lp->orig_upbo[i]);
else
fprintf(output, "x%d < %16g;\n", i - lp->rows,
(double)lp->orig_upbo[i]);
}
}
i = 1;
while(!lp->must_be_int[lp->rows + i] && i <= lp->columns)
i++;
if(i <= lp->columns) {
if(lp->names_used)
fprintf(output, "\nint %s", lp->col_name[i]);
else
fprintf(output, "\nint x%d", i);
i++;
for(; i <= lp->columns; i++)
if(lp->must_be_int[lp->rows + i]) {
if(lp->names_used)
fprintf(output, ",%s", lp->col_name[i]);
else
fprintf(output, ", x%d", i);
}
fprintf(output, ";\n");
}
free(row);
}
void write_MPS(lprec *lp, FILE *output)
{
int i, j, marker, putheader;
REAL *column, a;
MALLOC(column, lp->rows + 1);
marker = 0;
fprintf(output, "NAME %s\n", lp->lp_name);
fprintf(output, "ROWS\n");
for(i = 0; i <= lp->rows; i++) {
if(i == 0)
fprintf(output, " N ");
else
if(lp->orig_upbo[i] != 0) {
if(lp->ch_sign[i])
fprintf(output, " G ");
else
fprintf(output, " L ");
}
else
fprintf(output, " E ");
if(lp->names_used)
fprintf(output, "%s\n", lp->row_name[i]);
else
fprintf(output, "r_%d\n", i);
}
fprintf(output, "COLUMNS\n");
for(i = 1; i <= lp->columns; i++) {
if((lp->must_be_int[i + lp->rows]) && (marker % 2) == 0) {
fprintf(output,
" MARK%04d 'MARKER' 'INTORG'\n",
marker);
marker++;
}
if((!lp->must_be_int[i + lp->rows]) && (marker % 2) == 1) {
fprintf(output,
" MARK%04d 'MARKER' 'INTEND'\n",
marker);
marker++;
}
/* this gets slow for large LP problems. Implement a sparse version? */
get_column(lp, i, column);
j = 0;
if(lp->maximise) {
if(column[j] != 0) {
if(lp->names_used)
fprintf(output, " %-8s %-8s %12g\n", lp->col_name[i],
lp->row_name[j], (double)-column[j]);
else
fprintf(output, " var_%-4d r_%-6d %12g\n", i, j,
(double)-column[j]);
}
}
else {
if(column[j] != 0) {
if(lp->names_used)
fprintf(output, " %-8s %-8s %12g\n", lp->col_name[i],
lp->row_name[j], (double)column[j]);
else
fprintf(output, " var_%-4d r_%-6d %12g\n", i, j,
(double)column[j]);
}
}
for(j = 1; j <= lp->rows; j++)
if(column[j] != 0) {
if(lp->names_used)
fprintf(output, " %-8s %-8s %12g\n", lp->col_name[i],
lp->row_name[j], (double)column[j]);
else
fprintf(output, " var_%-4d r_%-6d %12g\n", i, j,
(double)column[j]);
}
}
if((marker % 2) == 1) {
fprintf(output, " MARK%04d 'MARKER' 'INTEND'\n",
marker);
/* marker++; */ /* marker not used after this */
}
fprintf(output, "RHS\n");
for(i = 1; i <= lp->rows; i++) {
a = lp->orig_rh[i];
if(lp->scaling_used)
a /= lp->scale[i];
if(lp->ch_sign[i]) {
if(lp->names_used)
fprintf(output, " RHS %-8s %12g\n", lp->row_name[i],
(double)-a);
else
fprintf(output, " RHS r_%-6d %12g\n", i, (double)-a);
}
else {
if(lp->names_used)
fprintf(output, " RHS %-8s %12g\n", lp->row_name[i],
(double)a);
else
fprintf(output, " RHS r_%-6d %12g\n", i, (double)a);
}
}
putheader = TRUE;
for(i = 1; i <= lp->rows; i++)
if((lp->orig_upbo[i] != lp->infinite) && (lp->orig_upbo[i] != 0.0)) {
if(putheader) {
fprintf(output, "RANGES\n");
putheader = FALSE;
}
a = lp->orig_upbo[i];
if(lp->scaling_used)
a /= lp->scale[i];
if(lp->names_used)
fprintf(output, " RGS %-8s %12g\n", lp->row_name[i],
(double)a);
else
fprintf(output, " RGS r_%-6d %12g\n", i,
(double)a);
}
else if((lp->orig_lowbo[i] != 0.0)) {
if(putheader) {
fprintf(output, "RANGES\n");
putheader = FALSE;
}
a = lp->orig_lowbo[i];
if(lp->scaling_used)
a /= lp->scale[i];
if(lp->names_used)
fprintf(output, " RGS %-8s %12g\n", lp->row_name[i],
(double)-a);
else
fprintf(output, " RGS r_%-6d %12g\n", i,
(double)-a);
}
fprintf(output, "BOUNDS\n");
if(lp->names_used)
for(i = lp->rows + 1; i <= lp->sum; i++) {
if((lp->orig_lowbo[i] != 0) && (lp->orig_upbo[i] < lp->infinite) &&
(lp->orig_lowbo[i] == lp->orig_upbo[i])) {
a = lp->orig_upbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
fprintf(output, " FX BND %-8s %12g\n",
lp->col_name[i - lp->rows], (double)a);
}
else {
if(lp->orig_upbo[i] < lp->infinite) {
a = lp->orig_upbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
fprintf(output, " UP BND %-8s %12g\n",
lp->col_name[i - lp->rows], (double)a);
}
if(lp->orig_lowbo[i] != 0) {
a = lp->orig_lowbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
/* bug? should a be used instead of lp->orig_lowbo[i] MB */
fprintf(output, " LO BND %-8s %12g\n",
lp->col_name[i - lp->rows], (double)lp->orig_lowbo[i]);
}
}
}
else
for(i = lp->rows + 1; i <= lp->sum; i++) {
if((lp->orig_lowbo[i] != 0) && (lp->orig_upbo[i] < lp->infinite) &&
(lp->orig_lowbo[i] == lp->orig_upbo[i])) {
a = lp->orig_upbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
fprintf(output, " FX BND %-8s %12g\n",
lp->col_name[i - lp->rows], (double)a);
}
else {
if(lp->orig_upbo[i] < lp->infinite) {
a = lp->orig_upbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
fprintf(output, " UP BND var_%-4d %12g\n",
i - lp->rows, (double)a);
}
if(lp->orig_lowbo[i] != 0) {
a = lp->orig_lowbo[i];
if(lp->scaling_used)
a *= lp->scale[i];
fprintf(output, " LO BND var_%-4d %12g\n", i - lp->rows,
(double)a);
}
}
}
fprintf(output, "ENDATA\n");
free(column);
}
void print_duals(lprec *lp)
{
int i;
for(i = 1; i <= lp->rows; i++)
if(lp->names_used)
fprintf(stdout, "%s [%d] %g\n", lp->row_name[i], i,
(double)lp->duals[i]);
else
fprintf(stdout, "Dual [%d] %g\n", i, (double)lp->duals[i]);
}
void print_scales(lprec *lp)
{
int i;
if(lp->scaling_used) {
for(i = 0; i <= lp->rows; i++)
fprintf(stdout, "Row[%d] scaled at %g\n", i,
(double)lp->scale[i]);
for(i = 1; i <= lp->columns; i++)
fprintf(stdout, "Column[%d] scaled at %g\n", i,
(double)lp->scale[lp->rows + i]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -