int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set, int a_cost) { glp_vertex *v; glp_arc *a; int i, j, ret, ind[1+2]; double cost, val[1+2]; if (!(form == GLP_ASN_MIN || form == GLP_ASN_MAX || form == GLP_ASN_MMP)) xerror("glp_asnprob_lp: form = %d; invalid parameter\n", form); if (!(names == GLP_ON || names == GLP_OFF)) xerror("glp_asnprob_lp: names = %d; invalid parameter\n", names); if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) xerror("glp_asnprob_lp: v_set = %d; invalid offset\n", v_set); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_asnprob_lp: a_cost = %d; invalid offset\n", a_cost); ret = glp_check_asnprob(G, v_set); if (ret != 0) goto done; glp_erase_prob(P); if (names) glp_set_prob_name(P, G->name); glp_set_obj_dir(P, form == GLP_ASN_MIN ? GLP_MIN : GLP_MAX); if (G->nv > 0) glp_add_rows(P, G->nv); for (i = 1; i <= G->nv; i++) { v = G->v[i]; if (names) glp_set_row_name(P, i, v->name); glp_set_row_bnds(P, i, form == GLP_ASN_MMP ? GLP_UP : GLP_FX, 1.0, 1.0); } if (G->na > 0) glp_add_cols(P, G->na); for (i = 1, j = 0; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { j++; if (names) { char name[50+1]; sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); xassert(strlen(name) < sizeof(name)); glp_set_col_name(P, j, name); } ind[1] = a->tail->i, val[1] = +1.0; ind[2] = a->head->i, val[2] = +1.0; glp_set_mat_col(P, j, 2, ind, val); glp_set_col_bnds(P, j, GLP_DB, 0.0, 1.0); if (a_cost >= 0) memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); else cost = 1.0; glp_set_obj_coef(P, j, cost); } } xassert(j == G->na); done: return ret; }
void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names) { glp_tree *tree = dest->tree; glp_bfcp bfcp; int i, j, len, *ind; double *val; if (tree != NULL && tree->reason != 0) xerror("glp_copy_prob: operation not allowed\n"); if (dest == prob) xerror("glp_copy_prob: copying problem object to itself not al" "lowed\n"); if (!(names == GLP_ON || names == GLP_OFF)) xerror("glp_copy_prob: names = %d; invalid parameter\n", names); glp_erase_prob(dest); if (names && prob->name != NULL) glp_set_prob_name(dest, prob->name); if (names && prob->obj != NULL) glp_set_obj_name(dest, prob->obj); dest->dir = prob->dir; dest->c0 = prob->c0; if (prob->m > 0) glp_add_rows(dest, prob->m); if (prob->n > 0) glp_add_cols(dest, prob->n); glp_get_bfcp(prob, &bfcp); glp_set_bfcp(dest, &bfcp); dest->pbs_stat = prob->pbs_stat; dest->dbs_stat = prob->dbs_stat; dest->obj_val = prob->obj_val; dest->some = prob->some; dest->ipt_stat = prob->ipt_stat; dest->ipt_obj = prob->ipt_obj; dest->mip_stat = prob->mip_stat; dest->mip_obj = prob->mip_obj; for (i = 1; i <= prob->m; i++) { GLPROW *to = dest->row[i]; GLPROW *from = prob->row[i]; if (names && from->name != NULL) glp_set_row_name(dest, i, from->name); to->type = from->type; to->lb = from->lb; to->ub = from->ub; to->rii = from->rii; to->stat = from->stat; to->prim = from->prim; to->dual = from->dual; to->pval = from->pval; to->dval = from->dval; to->mipx = from->mipx; } ind = xcalloc(1+prob->m, sizeof(int)); val = xcalloc(1+prob->m, sizeof(double)); for (j = 1; j <= prob->n; j++) { GLPCOL *to = dest->col[j]; GLPCOL *from = prob->col[j]; if (names && from->name != NULL) glp_set_col_name(dest, j, from->name); to->kind = from->kind; to->type = from->type; to->lb = from->lb; to->ub = from->ub; to->coef = from->coef; len = glp_get_mat_col(prob, j, ind, val); glp_set_mat_col(dest, j, len, ind, val); to->sjj = from->sjj; to->stat = from->stat; to->prim = from->prim; to->dual = from->dual; to->pval = from->pval; to->dval = from->dval; to->mipx = from->mipx; } xfree(ind); xfree(val); return; }
void glp_del_cols(glp_prob *lp, int ncs, const int num[]) { glp_tree *tree = lp->tree; GLPCOL *col; int j, k, n_new; if (tree != NULL && tree->reason != 0) xerror("glp_del_cols: operation not allowed\n"); /* mark columns to be deleted */ if (!(1 <= ncs && ncs <= lp->n)) xerror("glp_del_cols: ncs = %d; invalid number of columns\n", ncs); for (k = 1; k <= ncs; k++) { /* take the number of column to be deleted */ j = num[k]; /* obtain pointer to j-th column */ if (!(1 <= j && j <= lp->n)) xerror("glp_del_cols: num[%d] = %d; column number out of ra" "nge", k, j); col = lp->col[j]; /* check that the column is not marked yet */ if (col->j == 0) xerror("glp_del_cols: num[%d] = %d; duplicate column number" "s not allowed\n", k, j); /* erase symbolic name assigned to the column */ glp_set_col_name(lp, j, NULL); xassert(col->node == NULL); /* erase corresponding column of the constraint matrix */ glp_set_mat_col(lp, j, 0, NULL, NULL); xassert(col->ptr == NULL); /* mark the column to be deleted */ col->j = 0; /* if it is basic, invalidate the basis factorization */ if (col->stat == GLP_BS) lp->valid = 0; } /* delete all marked columns from the column list */ n_new = 0; for (j = 1; j <= lp->n; j++) { /* obtain pointer to j-th column */ col = lp->col[j]; /* check if the column is marked */ if (col->j == 0) { /* it is marked; delete it */ dmp_free_atom(lp->pool, col, sizeof(GLPCOL)); } else { /* it is not marked; keep it */ col->j = ++n_new; lp->col[col->j] = col; } } /* set new number of columns */ lp->n = n_new; /* if the basis header is still valid, adjust it */ if (lp->valid) { int m = lp->m; int *head = lp->head; for (j = 1; j <= n_new; j++) { k = lp->col[j]->bind; if (k != 0) { xassert(1 <= k && k <= m); head[k] = m + j; } } } return; }
/* add the next column. col = index of the column (1<=col<=cols) n = number of entries in row_idx[],row_val[] (1<=i<=n) type = GLP_FR: free; GLP_LO: >=0 */ static void add_column(int col,int n,int type) { sort_rowidx(n); glp_set_col_bnds(P,col,type,0.0,0.0); glp_set_mat_col(P,col,n,row_idx,row_val); }
void glp_maxflow_lp(glp_prob *lp, glp_graph *G, int names, int s, int t, int a_cap) { glp_vertex *v; glp_arc *a; int i, j, type, ind[1+2]; double cap, val[1+2]; if (!(names == GLP_ON || names == GLP_OFF)) xerror("glp_maxflow_lp: names = %d; invalid parameter\n", names); if (!(1 <= s && s <= G->nv)) xerror("glp_maxflow_lp: s = %d; source node number out of rang" "e\n", s); if (!(1 <= t && t <= G->nv)) xerror("glp_maxflow_lp: t = %d: sink node number out of range " "\n", t); if (s == t) xerror("glp_maxflow_lp: s = t = %d; source and sink nodes must" " be distinct\n", s); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_maxflow_lp: a_cap = %d; invalid offset\n", a_cap); glp_erase_prob(lp); if (names) glp_set_prob_name(lp, G->name); glp_set_obj_dir(lp, GLP_MAX); glp_add_rows(lp, G->nv); for (i = 1; i <= G->nv; i++) { v = G->v[i]; if (names) glp_set_row_name(lp, i, v->name); if (i == s) type = GLP_LO; else if (i == t) type = GLP_UP; else type = GLP_FX; glp_set_row_bnds(lp, i, type, 0.0, 0.0); } if (G->na > 0) glp_add_cols(lp, G->na); for (i = 1, j = 0; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { j++; if (names) { char name[50+1]; sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); xassert(strlen(name) < sizeof(name)); glp_set_col_name(lp, j, name); } if (a->tail->i != a->head->i) { ind[1] = a->tail->i, val[1] = +1.0; ind[2] = a->head->i, val[2] = -1.0; glp_set_mat_col(lp, j, 2, ind, val); } if (a_cap >= 0) memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); else cap = 1.0; if (cap == DBL_MAX) type = GLP_LO; else if (cap != 0.0) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(lp, j, type, 0.0, cap); if (a->tail->i == s) glp_set_obj_coef(lp, j, +1.0); else if (a->head->i == s) glp_set_obj_coef(lp, j, -1.0); } } xassert(j == G->na); return; }
void glp_mincost_lp(glp_prob *lp, glp_graph *G, int names, int v_rhs, int a_low, int a_cap, int a_cost) { glp_vertex *v; glp_arc *a; int i, j, type, ind[1+2]; double rhs, low, cap, cost, val[1+2]; if (!(names == GLP_ON || names == GLP_OFF)) xerror("glp_mincost_lp: names = %d; invalid parameter\n", names); if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) xerror("glp_mincost_lp: v_rhs = %d; invalid offset\n", v_rhs); if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) xerror("glp_mincost_lp: a_low = %d; invalid offset\n", a_low); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_mincost_lp: a_cap = %d; invalid offset\n", a_cap); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_mincost_lp: a_cost = %d; invalid offset\n", a_cost) ; glp_erase_prob(lp); if (names) glp_set_prob_name(lp, G->name); if (G->nv > 0) glp_add_rows(lp, G->nv); for (i = 1; i <= G->nv; i++) { v = G->v[i]; if (names) glp_set_row_name(lp, i, v->name); if (v_rhs >= 0) memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); else rhs = 0.0; glp_set_row_bnds(lp, i, GLP_FX, rhs, rhs); } if (G->na > 0) glp_add_cols(lp, G->na); for (i = 1, j = 0; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { j++; if (names) { char name[50+1]; sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); xassert(strlen(name) < sizeof(name)); glp_set_col_name(lp, j, name); } if (a->tail->i != a->head->i) { ind[1] = a->tail->i, val[1] = +1.0; ind[2] = a->head->i, val[2] = -1.0; glp_set_mat_col(lp, j, 2, ind, val); } if (a_low >= 0) memcpy(&low, (char *)a->data + a_low, sizeof(double)); else low = 0.0; if (a_cap >= 0) memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); else cap = 1.0; if (cap == DBL_MAX) type = GLP_LO; else if (low != cap) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(lp, j, type, low, cap); if (a_cost >= 0) memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); else cost = 0.0; glp_set_obj_coef(lp, j, cost); } } xassert(j == G->na); return; }
void npp_build_prob(NPP *npp, glp_prob *prob) { /* build resultant (preprocessed) problem */ NPPROW *row; NPPCOL *col; NPPAIJ *aij; int i, j, type, len, *ind; double dir, *val; glp_erase_prob(prob); glp_set_prob_name(prob, npp->name); glp_set_obj_name(prob, npp->obj); glp_set_obj_dir(prob, npp->orig_dir); if (npp->orig_dir == GLP_MIN) dir = +1.0; else if (npp->orig_dir == GLP_MAX) dir = -1.0; else xassert(npp != npp); glp_set_obj_coef(prob, 0, dir * npp->c0); /* build rows */ for (row = npp->r_head; row != NULL; row = row->next) { row->temp = i = glp_add_rows(prob, 1); glp_set_row_name(prob, i, row->name); if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) type = GLP_FR; else if (row->ub == +DBL_MAX) type = GLP_LO; else if (row->lb == -DBL_MAX) type = GLP_UP; else if (row->lb != row->ub) type = GLP_DB; else type = GLP_FX; glp_set_row_bnds(prob, i, type, row->lb, row->ub); } /* build columns and the constraint matrix */ ind = xcalloc(1+prob->m, sizeof(int)); val = xcalloc(1+prob->m, sizeof(double)); for (col = npp->c_head; col != NULL; col = col->next) { j = glp_add_cols(prob, 1); glp_set_col_name(prob, j, col->name); #if 0 glp_set_col_kind(prob, j, col->kind); #else glp_set_col_kind(prob, j, col->is_int ? GLP_IV : GLP_CV); #endif if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) type = GLP_FR; else if (col->ub == +DBL_MAX) type = GLP_LO; else if (col->lb == -DBL_MAX) type = GLP_UP; else if (col->lb != col->ub) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(prob, j, type, col->lb, col->ub); glp_set_obj_coef(prob, j, dir * col->coef); len = 0; for (aij = col->ptr; aij != NULL; aij = aij->c_next) { len++; ind[len] = aij->row->temp; val[len] = aij->val; } glp_set_mat_col(prob, j, len, ind, val); } xfree(ind); xfree(val); /* resultant problem has been built */ npp->m = prob->m; npp->n = prob->n; npp->nnz = prob->nnz; npp->row_ref = xcalloc(1+npp->m, sizeof(int)); npp->col_ref = xcalloc(1+npp->n, sizeof(int)); for (row = npp->r_head, i = 0; row != NULL; row = row->next) npp->row_ref[++i] = row->i; for (col = npp->c_head, j = 0; col != NULL; col = col->next) npp->col_ref[++j] = col->j; /* transformed problem segment is no longer needed */ dmp_delete_pool(npp->pool), npp->pool = NULL; npp->name = npp->obj = NULL; npp->c0 = 0.0; npp->r_head = npp->r_tail = NULL; npp->c_head = npp->c_tail = NULL; return; }
void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], const double val[]) { /* set (replace) column of the constraint matrix */ glp_set_mat_col(lp, j, len, ind, val); return; }