📄 lpkit.c
字号:
void set_constr_type(lprec *lp, int row, short con_type){ int i; if(row > lp->rows || row < 1) error("Row out of Range"); if(con_type == EQ) { lp->orig_upbo[row] = 0; lp->basis_valid = FALSE; if(lp->ch_sign[row]) { for(i = 0; i < lp->non_zeros; i++) if(lp->mat[i].row_nr == row) lp->mat[i].value *= -1; lp->eta_valid = FALSE; lp->ch_sign[row] = FALSE; if(lp->orig_rh[row] != 0) lp->orig_rh[row] *= -1; } } else if(con_type == LE) { lp->orig_upbo[row] = lp->infinite; lp->basis_valid = FALSE; if(lp->ch_sign[row]) { for(i = 0; i < lp->non_zeros; i++) if(lp->mat[i].row_nr == row) lp->mat[i].value *= -1; lp->eta_valid = FALSE; lp->ch_sign[row] = FALSE; if(lp->orig_rh[row] != 0) lp->orig_rh[row] *= -1; } } else if(con_type == GE) { lp->orig_upbo[row] = lp->infinite; lp->basis_valid = FALSE; if(!lp->ch_sign[row]) { for(i = 0; i < lp->non_zeros; i++) if(lp->mat[i].row_nr == row) lp->mat[i].value *= -1; lp->eta_valid = FALSE; lp->ch_sign[row] = TRUE; if(lp->orig_rh[row] != 0) lp->orig_rh[row] *= -1; } } else error("Constraint type not (yet) implemented");}REAL mat_elm(lprec *lp, int row, int column){ REAL value; int elmnr; if(row < 0 || row > lp->rows) error("Row out of range in mat_elm"); if(column < 1 || column > lp->columns) error("Column out of range in mat_elm"); value = 0; elmnr = lp->col_end[column-1]; while(lp->mat[elmnr].row_nr != row && elmnr < lp->col_end[column]) elmnr++; if(elmnr != lp->col_end[column]) { value = lp->mat[elmnr].value; if(lp->ch_sign[row]) value = -value; if(lp->scaling_used) value /= lp->scale[row] * lp->scale[lp->rows + column]; } return(value);}void get_row(lprec *lp, int row_nr, REAL *row){ int i, j; if(row_nr <0 || row_nr > lp->rows) error("Row nr. out of range in get_row"); for(i = 1; i <= lp->columns; i++) { row[i] = 0; for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++) if(lp->mat[j].row_nr == row_nr) row[i] = lp->mat[j].value; if(lp->scaling_used) row[i] /= lp->scale[lp->rows + i] * lp->scale[row_nr]; } if(lp->ch_sign[row_nr]) for(i = 0; i <= lp->columns; i++) if(row[i] != 0) row[i] = -row[i];}void get_column(lprec *lp, int col_nr, REAL *column){ int i; if(col_nr < 1 || col_nr > lp->columns) error("Col. nr. out of range in get_column"); for(i = 0; i <= lp->rows; i++) column[i] = 0; for(i = lp->col_end[col_nr - 1]; i < lp->col_end[col_nr]; i++) column[lp->mat[i].row_nr] = lp->mat[i].value; for(i = 0; i <= lp->rows; i++) if(column[i] != 0) { if(lp->ch_sign[i]) column[i] *= -1; if(lp->scaling_used) column[i] /= (lp->scale[i] * lp->scale[lp->rows + col_nr]); }}void get_reduced_costs(lprec *lp, REAL *rc){ int varnr, i, j; REAL f; if(!lp->basis_valid) error("Not a valid basis in get_reduced_costs"); if(!lp->eta_valid) invert(lp); for(i = 1; i <= lp->sum; i++) rc[i] = 0; rc[0] = 1; btran(lp, rc); for(i = 1; i <= lp->columns; i++) { varnr = lp->rows + i; if(!lp->basis[varnr]) if(lp->upbo[varnr] > 0) { f = 0; for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++) f += rc[lp->mat[j].row_nr] * lp->mat[j].value; rc[varnr] = f; } } for(i = 1; i <= lp->sum; i++) my_round(rc[i], lp->epsd);} short is_feasible(lprec *lp, REAL *values){ int i, elmnr; REAL *this_rhs; REAL dist; if(lp->scaling_used) { for(i = lp->rows + 1; i <= lp->sum; i++) if( values[i - lp->rows] < lp->orig_lowbo[i] * lp->scale[i] || values[i - lp->rows] > lp->orig_upbo[i] * lp->scale[i]) return(FALSE); } else { for(i = lp->rows + 1; i <= lp->sum; i++) if( values[i - lp->rows] < lp->orig_lowbo[i] || values[i - lp->rows] > lp->orig_upbo[i]) return(FALSE); } CALLOC(this_rhs, lp->rows + 1); if (lp->columns_scaled) { for(i = 1; i <= lp->columns; i++) for(elmnr = lp->col_end[i - 1]; elmnr < lp->col_end[i]; elmnr++) this_rhs[lp->mat[elmnr].row_nr] += lp->mat[elmnr].value * values[i] / lp->scale[lp->rows + i]; } else { for(i = 1; i <= lp->columns; i++) for(elmnr = lp->col_end[i - 1]; elmnr < lp->col_end[i]; elmnr++) this_rhs[lp->mat[elmnr].row_nr] += lp->mat[elmnr].value * values[i]; } for(i = 1; i <= lp->rows; i++) { dist = lp->orig_rh[i] - this_rhs[i]; my_round(dist, 0.001); /* ugly constant, MB */ if((lp->orig_upbo[i] == 0 && dist != 0) || dist < 0) { free(this_rhs); return(FALSE); } } free(this_rhs); return(TRUE);}/* fixed by Enrico Faggiolo */short column_in_lp(lprec *lp, REAL *testcolumn){ int i, j; int nz, ident; REAL value; for(nz = 0, i = 0; i <= lp->rows; i++) if(my_abs(testcolumn[i]) > lp->epsel) nz++; if(lp->scaling_used) for(i = 1; i <= lp->columns; i++) { ident = nz; for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++) { value = lp->mat[j].value; if(lp->ch_sign[lp->mat[j].row_nr]) value = -value; value /= lp->scale[lp->rows + i]; value /= lp->scale[lp->mat[j].row_nr]; value -= testcolumn[lp->mat[j].row_nr]; if(my_abs(value) > lp->epsel) break; ident--; if(ident == 0) return(TRUE); } } else for(i = 1; i <= lp->columns; i++) { ident = nz; for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++) { value = lp->mat[j].value; if(lp->ch_sign[lp->mat[j].row_nr]) value = -value; value -= testcolumn[lp->mat[j].row_nr]; if(my_abs(value) > lp->epsel) break; ident--; if(ident == 0) return(TRUE); } } return(FALSE);}void print_lp(lprec *lp){ int i, j; REAL *fatmat; CALLOC(fatmat, (lp->rows + 1) * lp->columns); for(i = 1; i <= lp->columns; i++) for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++) fatmat[(i - 1) * (lp->rows + 1) + lp->mat[j].row_nr] = lp->mat[j].value; printf("problem name: %s\n", lp->lp_name); printf(" "); for(j = 1; j <= lp->columns; j++) if(lp->names_used) printf("%8s ", lp->col_name[j]); else printf("Var[%3d] ", j); if(lp->maximise) { printf("\nMaximise "); for(j = 0; j < lp->columns; j++) printf("%8g ", (double) -fatmat[j * (lp->rows + 1)]); } else { printf("\nMinimize "); for(j = 0; j < lp->columns; j++) printf("%8g ", (double) fatmat[j * (lp->rows + 1)]); } printf("\n"); for(i = 1; i <= lp->rows; i++) { if(lp->names_used) printf("%-9s ", lp->row_name[i]); else printf("Row[%3d] ", i); for(j = 0; j < lp->columns; j++) if(lp->ch_sign[i] && fatmat[j*(lp->rows + 1) + i] != 0) printf("%8g ", (double)-fatmat[j * (lp->rows+1) + i]); else printf("%8g ", (double)fatmat[j * (lp->rows + 1) + i]); if(lp->orig_upbo[i] != 0) { if(lp->ch_sign[i]) printf(">= "); else printf("<= "); } else printf(" = "); if(lp->ch_sign[i]) printf("%8g", (double)-lp->orig_rh[i]); else printf("%8g", (double)lp->orig_rh[i]); if(lp->orig_lowbo[i] != 0) { printf(" %s = %8g", (lp->ch_sign[i]) ? "lowbo" : "upbo", (double)lp->orig_lowbo[i]); } if((lp->orig_upbo[i] != lp->infinite) && (lp->orig_upbo[i] != 0.0)) { printf(" %s = %8g", (lp->ch_sign[i]) ? "upbo" : "lowbo", (double)lp->orig_upbo[i]); } printf("\n"); } printf("Type "); for(i = 1; i <= lp->columns; i++) if(lp->must_be_int[lp->rows + i] == TRUE) printf(" Int "); else printf(" Real "); printf("\nupbo "); for(i = 1; i <= lp->columns; i++) if(lp->orig_upbo[lp->rows + i] == lp->infinite) printf(" Infinite"); else printf("%8g ", (double)lp->orig_upbo[lp->rows + i]); printf("\nlowbo "); for(i = 1; i <= lp->columns; i++) printf("%8g ", (double)lp->orig_lowbo[lp->rows + i]); printf("\n"); for(i = 0; i < lp->nr_lagrange; i++) { printf("lag[%d] ", i); for(j = 1; j <= lp->columns; j++) printf("%8g ", (double)lp->lag_row[i][j]); if(lp->orig_upbo[i] == lp->infinite) { if(lp->lag_con_type[i] == GE) printf(">= "); else if(lp->lag_con_type[i] == LE) printf("<= "); else if(lp->lag_con_type[i] == EQ) printf(" = "); } printf("%8g\n", (double)lp->lag_rhs[i]); } free(fatmat);} void set_row_name(lprec *lp, int row, nstring new_name){ int i; hashelem *hp; if(!lp->names_used) { CALLOC(lp->row_name, lp->rows_alloc + 1); CALLOC(lp->col_name, lp->columns_alloc + 1); lp->names_used = TRUE; for(i = 0; i <= lp->rows; i++) sprintf(lp->row_name[i], "r_%d", i); for(i = 1; i <= lp->columns; i++) sprintf(lp->col_name[i], "var_%d", i); } strcpy(lp->row_name[row], new_name); hp = puthash(lp->row_name[row], lp->rowname_hashtab); hp->index = row;}void set_col_name(lprec *lp, int column, nstring new_name){ int i; hashelem *hp; if(!lp->names_used) { CALLOC(lp->row_name, lp->rows_alloc + 1); CALLOC(lp->col_name, lp->columns_alloc + 1); lp->names_used = TRUE; for(i = 0; i <= lp->rows; i++) sprintf(lp->row_name[i], "r_%d", i); for(i = 1; i <= lp->columns; i++) sprintf(lp->col_name[i], "var_%d", i); } strcpy(lp->col_name[column], new_name); hp = puthash(lp->col_name[column], lp->colname_hashtab); hp->index = column;}static REAL minmax_to_scale(REAL min, REAL max){ REAL scale; /* should do something sensible when min or max is 0, MB */ if((min == 0) || (max == 0)) return((REAL)1); /* scale = 1 / pow(10, (log10(min) + log10(max)) / 2); */ /* Jon van Reet noticed: can be simplified to: */ scale = 1 / sqrt(min * max); return(scale);}void unscale_columns(lprec *lp){ int i, j; /* unscale 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 /= lp->scale[lp->rows + j]; /* unscale 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] *= lp->scale[i]; if(lp->orig_upbo[i] != lp->infinite) lp->orig_upbo[i] *= lp->scale[i]; } for(i = lp->rows + 1; i<= lp->sum; i++) lp->scale[i] = 1; lp->columns_scaled = FALSE; lp->eta_valid = FALSE;}void unscale(lprec *lp){ int i, j; if(lp->scaling_used) { /* unscale 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 /= lp->scale[lp->rows + j]; /* unscale bounds */ for(i = lp->rows + 1; i <= lp->sum; i++) { /* was < */ /* changed by PN */ if(lp->orig_lowbo[i] != 0) lp->orig_lowbo[i] *= lp->scale[i]; if(lp->orig_upbo[i] != lp->infinite) lp->orig_upbo[i] *= lp->scale[i]; } /* unscale 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 /= lp->scale[lp->mat[i].row_nr]; /* unscale the rhs! */ for(i = 0; i <= lp->rows; i++) lp->orig_rh[i] /= lp->scale[i]; /* and don't forget to unscale the upper and lower bounds ... */ for(i = 0; i <= lp->rows; i++) { if(lp->orig_lowbo[i] != 0) lp->orig_lowbo[i] /= lp->scale[i]; if(lp->orig_upbo[i] != lp->infinite) lp->orig_upbo[i] /= lp->scale[i]; } free(lp->scale); lp->scaling_used = FALSE; lp->eta_valid = FALSE; }}void auto_scale(lprec *lp){ int i, j, row_nr; REAL *row_max, *row_min, *scalechange, absval; REAL col_max, col_min; if(!lp->scaling_used) { MALLOC(lp->scale, lp->sum_alloc + 1); for(i = 0; i <= lp->sum; i++) lp->scale[i] = 1; } MALLOC(row_max, lp->rows + 1); MALLOC(row_min, lp->rows + 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -