void NADA() { glp_prob *lp; lp = glp_create_prob(); glp_add_cols(lp, 3); glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 3.0); // 0 <= x1 glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 2.0); // 0 <= x2 glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); // 0 <= x3 glp_set_obj_dir(lp, GLP_MAX); //max glp_set_obj_coef(lp, 1, -3.0); // -3x1 glp_set_obj_coef(lp, 2, 4.0); // +4x2 glp_set_obj_coef(lp, 3, 11.0); // +11x3 // max -3x1 + 4x2 + 11 x3. int indCol[123]; double val[123]; glp_add_rows(lp, 1); indCol[1] = 1; val[1] = 10; // 10*x1 indCol[2] = 2; val[2] = 3; // 3*x2 glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 15.0);// <=15 glp_set_mat_row(lp, 1, 2, indCol, val);// 10 x1 + 3 x2 <= 15 glp_add_rows(lp, 1); indCol[1] = 3; val[1] = 9; // 9*x3 indCol[2] = 1; val[2] = 7; // 7*x1 glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 38.0);// <=38 glp_set_mat_row(lp, 2, 2, indCol, val);// 7x1+9x2<=38 glp_add_rows(lp, 1); indCol[1] = 3; val[1] = 15; // 15*x3 glp_set_row_bnds(lp, 3, GLP_LO, 0.0, 25.0);// >=25 glp_set_mat_row(lp, 3, 1, indCol, val);// 15x3 >=25 glp_set_col_kind(lp, 1, GLP_IV);// X1 EH INTEIRO glp_set_col_kind(lp, 2, GLP_IV);// X2 EH INTEIRO glp_set_col_kind(lp, 3, GLP_IV);// X3 EH INTEIRO glp_intopt(lp, NULL); // acha solucao com restricao de integralidade // glp_simplex(lp, NULL); // printf("Solucao Otima: %.3f\n", glp_get_obj_val(lp)); // printf("X1: %.3f\n", glp_get_col_prim(lp, 1)); // printf("X2: %.3f\n", glp_get_col_prim(lp, 2)); // printf("X3: %.3f\n", glp_get_col_prim(lp, 3)); printf("Solucao Otima: %.3f\n", glp_mip_obj_val(lp)); printf("X1: %.3f\n", glp_mip_col_val(lp, 1)); printf("X2: %.3f\n", glp_mip_col_val(lp, 2)); printf("X3: %.3f\n", glp_mip_col_val(lp, 3)); // for (int est = 1; est <= nEstradas; ++est) { // glp_set_col_bnds(lp, est, GLP_LO, 0.0, 0.0); // } }
glp_prob * montarModeloInicial() { glp_prob *lp; lp = glp_create_prob();//cria problema glp_add_cols(lp, nEstradas); // cria uma variavel por estrada for(int est = 1; est <= nEstradas; ++est) { // para cada estrada glp_set_col_bnds(lp, est, GLP_DB, 0.0, 1.0); // estrada entre 0 e 1 glp_set_col_kind(lp, est, GLP_BV); // estrada binaria } glp_set_obj_dir(lp, GLP_MIN); //MIN for(int est=1; est <= nEstradas; ++est) { // para cada estrada glp_set_obj_coef(lp, est, estradas[est].dist); // custo da estrada eh coeficiente da objetivo } for (int cid = 1; cid <= nCidades; ++cid) { //para cada cidade int indCol[123]; double val[123]; int nCoef = 0; for (int est = 1; est < nEstradas; ++est) { //para cada estrada Estrada estrada = estradas[est]; if (estrada.ori == cid || estrada.dest == cid) { //se cidade toca estrada est indCol[nCoef + 1] = est; // a est-esima estrada val[nCoef + 1] = 1.0; // com coeficiente 1 na linha nCoef++; //incremente numero de coeficiente } } glp_add_rows(lp, 1); glp_set_mat_row(lp, cid, nCoef, indCol, val); // adiciona coeficientes da linha glp_set_row_bnds(lp, cid, GLP_DB, 2.0, 2.0); // restringe linha = 2. } }
void NUMlinprog_addConstraintCoefficient (NUMlinprog me, double coefficient) { ++ my ivar; my ind [my ivar] = my ivar; my val [my ivar] = coefficient; if (my ivar == my numberOfVariables) { glp_set_mat_row (my linearProgram, my numberOfConstraints, my numberOfVariables, my ind, my val); } }
static void parse_constraints(struct csa *csa) { int i, len, type; double s; /* parse the keyword 'subject to' */ xassert(csa->token == T_SUBJECT_TO); scan_token(csa); loop: /* create new row (constraint) */ i = glp_add_rows(csa->P, 1); /* parse row name */ if (csa->token == T_NAME && csa->c == ':') { /* row name is followed by a colon */ if (glp_find_row(csa->P, csa->image) != 0) error(csa, "constraint '%s' multiply defined\n", csa->image); glp_set_row_name(csa->P, i, csa->image); scan_token(csa); xassert(csa->token == T_COLON); scan_token(csa); } else { /* row name is not specified; use default */ char name[50]; sprintf(name, "r.%d", csa->count); glp_set_row_name(csa->P, i, name); } /* parse linear form */ len = parse_linear_form(csa); glp_set_mat_row(csa->P, i, len, csa->ind, csa->val); /* parse constraint sense */ if (csa->token == T_LE) type = GLP_UP, scan_token(csa); else if (csa->token == T_GE) type = GLP_LO, scan_token(csa); else if (csa->token == T_EQ) type = GLP_FX, scan_token(csa); else error(csa, "missing constraint sense\n"); /* parse right-hand side */ if (csa->token == T_PLUS) s = +1.0, scan_token(csa); else if (csa->token == T_MINUS) s = -1.0, scan_token(csa); else s = +1.0; if (csa->token != T_NUMBER) error(csa, "missing right-hand side\n"); glp_set_row_bnds(csa->P, i, type, s * csa->value, s * csa->value); /* the rest of the current line must be empty */ if (!(csa->c == '\n' || csa->c == EOF)) error(csa, "invalid symbol(s) beyond right-hand side\n"); scan_token(csa); /* if the next token is a sign, numeric constant, or a symbolic name, here is another constraint */ if (csa->token == T_PLUS || csa->token == T_MINUS || csa->token == T_NUMBER || csa->token == T_NAME) goto loop; return; }
int GLPKAddConstraint(LinEquation* InEquation) { if (InEquation->QuadCoeff.size() > 0) { FErrorFile() << "GLPK solver cannot accept quadratic constraints." << endl; FlushErrorFile(); return FAIL; } if (GLPKModel == NULL) { FErrorFile() << "Could not add constraint because GLPK object does not exist." << endl; FlushErrorFile(); return FAIL; } int NumRows = glp_get_num_rows(GLPKModel); if (InEquation->Index >= NumRows) { glp_add_rows(GLPKModel, 1); } if (InEquation->EqualityType == EQUAL) { glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_FX, InEquation->RightHandSide, InEquation->RightHandSide); } else if (InEquation->EqualityType == GREATER) { glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_LO, InEquation->RightHandSide, InEquation->RightHandSide); } else if (InEquation->EqualityType == LESS) { glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_UP, InEquation->RightHandSide, InEquation->RightHandSide); } else { FErrorFile() << "Could not add constraint because the constraint type was not recognized." << endl; FlushErrorFile(); return FAIL; } int NumColumns = glp_get_num_cols(GLPKModel); int* Indecies = new int[int(InEquation->Variables.size())+1]; double* Coeff = new double[int(InEquation->Variables.size())+1]; for (int i=0; i < int(InEquation->Variables.size()); i++) { if (InEquation->Variables[i]->Index < NumColumns) { if (InEquation->Variables[i]->Exclude) { Coeff[i+1] = 0; } else { Coeff[i+1] = InEquation->Coefficient[i]; } Indecies[i+1] = InEquation->Variables[i]->Index+1; } else { FErrorFile() << "Variable index found in constraint is out of the range found in GLPK problem" << endl; FlushErrorFile(); return FAIL; } } glp_set_mat_row(GLPKModel, InEquation->Index+1, int(InEquation->Variables.size()), Indecies, Coeff); delete [] Indecies; delete [] Coeff; return SUCCESS; }
void glp_del_rows(glp_prob *lp, int nrs, const int num[]) { glp_tree *tree = lp->tree; GLPROW *row; int i, k, m_new; /* mark rows to be deleted */ if (!(1 <= nrs && nrs <= lp->m)) xerror("glp_del_rows: nrs = %d; invalid number of rows\n", nrs); for (k = 1; k <= nrs; k++) { /* take the number of row to be deleted */ i = num[k]; /* obtain pointer to i-th row */ if (!(1 <= i && i <= lp->m)) xerror("glp_del_rows: num[%d] = %d; row number out of range" "\n", k, i); row = lp->row[i]; if (tree != NULL && tree->reason != 0) { xassert(tree->curr != NULL); xassert(row->level == tree->curr->level); } /* check that the row is not marked yet */ if (row->i == 0) xerror("glp_del_rows: num[%d] = %d; duplicate row numbers n" "ot allowed\n", k, i); /* erase symbolic name assigned to the row */ glp_set_row_name(lp, i, NULL); xassert(row->node == NULL); /* erase corresponding row of the constraint matrix */ glp_set_mat_row(lp, i, 0, NULL, NULL); xassert(row->ptr == NULL); /* mark the row to be deleted */ row->i = 0; } /* delete all marked rows from the row list */ m_new = 0; for (i = 1; i <= lp->m; i++) { /* obtain pointer to i-th row */ row = lp->row[i]; /* check if the row is marked */ if (row->i == 0) { /* it is marked, delete it */ dmp_free_atom(lp->pool, row, sizeof(GLPROW)); } else { /* it is not marked; keep it */ row->i = ++m_new; lp->row[row->i] = row; } } /* set new number of rows */ lp->m = m_new; /* invalidate the basis factorization */ lp->valid = 0; return; }
/* Create from the base problem, an other problem which forces stocks to be 0. * The cronstruted solution stay feasible for the first problem. */ node* construction (glp_prob * prob) { node* res = (node *) malloc (sizeof(node)); glp_prob * constProb = glp_create_prob(); glp_copy_prob(constProb, prob, GLP_ON); int i = glp_add_rows(constProb, 1); int k = glp_add_rows(constProb, 1); int nbj = glp_get_num_cols(prob)/3 -1; int ind[nbj+2]; double val[nbj+2]; int indk[nbj+2]; double valk[nbj+2]; int j; ind[0] = 0; val[0] = 1; ind[1] = 1; val[1] = 1; indk[1] = 2 ; valk[1] = 1; for (j = 1; j <= nbj; ++j) { ind[j] = j * 3 +2; indk[j] = j *3 + 3; val[j] = 1; valk[j] = 1; } glp_set_mat_row(constProb, i, nbj, ind, val); glp_set_row_bnds(constProb, i, GLP_FX, 0, 0); glp_set_mat_row(constProb, k, nbj, indk, valk); glp_set_row_bnds(constProb, k, GLP_FX, nbj, nbj); create_node(res, constProb, NULL, 0, 0); return res; }
void glpk_wrapper::set_constraint(int index, Enode * const e) { DREAL_LOG_INFO << "glpk_wrapper::set_constraint " << e << " with " << e->getPolarity(); assert(is_linear(e)); changed = true; LAExpression la(e); auto vars = e->get_vars(); auto s = vars.size(); auto indices = new int[s + 1]; auto values = new double[s + 1]; int i = 1; for (auto it = la.begin(); it != la.end(); ++it) { auto v = it->first; double c = it->second; if (v != nullptr && c != 0.0) { DREAL_LOG_INFO << "glpk_wrapper::set_constraint " << c << " * " << v; indices[i] = get_index(v) + 1; values[i] = c; i += 1; } else { if (e->isEq()) { assert(!e->hasPolarity() || e->getPolarity() != l_False); DREAL_LOG_INFO << "glpk_wrapper::set_constraint == " << c; glp_set_row_bnds(lp, index, GLP_FX, -c, -c); } else { if (!e->hasPolarity() || e->getPolarity() != l_False) { DREAL_LOG_INFO << "glpk_wrapper::set_constraint <= " << (-c); glp_set_row_bnds(lp, index, GLP_UP, 0, -c); } else { DREAL_LOG_INFO << "glpk_wrapper::set_constraint >= " << (-c); glp_set_row_bnds(lp, index, GLP_LO, -c, 0); } } } } glp_set_mat_row(lp, index, i-1, indices, values); delete[] indices; delete[] values; // name the constraints (helps debugging) if (DREAL_LOG_INFO_IS_ON) { std::ostringstream stream; if (e->getPolarity() == l_False) { stream << "¬"; } stream << e; glp_set_row_name(lp, index, stream.str().c_str()); } }
void LinearProblem::RemoveRow(int row) { static int indices[MAX_VARS]; static double values[MAX_VARS]; int nonZeros = glp_get_mat_row(lp_, row, indices, values); glp_set_row_bnds(lp_, row, GLP_FR, 0.0, 0.0); // glpk ignores the 0's index of the array int ind[2]; double val[2]; for (int i = 1; i <= nonZeros; ++i) { ind[1] = indices[i]; val[1] = (isMax(colToVar_[indices[i]]) ? -1 : 1); int r = glp_add_rows(lp_, 1); glp_set_row_bnds(lp_, r, GLP_UP, 0.0, MINUS_INFTY); glp_set_mat_row(lp_, r, 1, ind, val); } }
/* Different cases : * - if the created node is root, then father is NULL, the problem version in the node is the one gave as parameter. * - else we copy the problem, and had the constraint "x_{y} = valy" */ void create_node(node* n, glp_prob* prob, node* father, int y, double valy) { n->father = father; n->leftSon = NULL; n->rightSon = NULL; n->check = 0; int i = 0; int ind[] = {0,y}; double val[] = {0,1}; if (n-> father == NULL) { n->prob = prob; } else { n->prob = glp_create_prob(); glp_copy_prob(n->prob, n->father->prob, GLP_ON); i = glp_add_rows(n->prob, 1); glp_set_mat_row(n->prob, i, 1, ind, val); glp_set_row_bnds(n->prob, i, GLP_FX, valy, valy); } glp_smcp parm; glp_init_smcp(&parm); parm.msg_lev = GLP_MSG_OFF; glp_iocp parmip; glp_init_iocp(&parmip); parmip.msg_lev = GLP_MSG_OFF; glp_write_lp(prob, NULL, "ULS.lp"); n->solveFlag = glp_simplex(n->prob, &parm); glp_intopt(n->prob, &parmip); n->z = glp_mip_obj_val(n->prob); n->x = (double *) malloc (glp_get_num_cols(n->prob) * sizeof(double)); for (i = 0; i < glp_get_num_cols(n->prob); ++i) n->x[i] = glp_mip_col_val(n->prob, i+1); }
/* Restriction xj - xi >= Sij */ void addSeparationConstraint(glp_prob * Prob, int plane1, int plane2) { int cardinal, constr[3], i = plane1, j = plane2; double cValues[3]; char buf[AUXSIZE]; cardinal = glp_add_rows(Prob, 1); sprintf(buf,"S%i,%i",i,j); glp_set_row_name(Prob, cardinal, buf); glp_set_row_bnds(Prob, cardinal, GLP_LO, planes[i].sep[j], 0); sprintf(buf,"x%i",j); constr[1] = glp_find_col(Prob, buf); sprintf(buf,"x%i",i); constr[2] = glp_find_col(Prob, buf); cValues[1] = 1; cValues[2] = -1; glp_set_mat_row(Prob, cardinal, 2, constr, cValues); }
int main(int argc, char *argv[]) { leEstradas(); glp_prob *lp = montarModeloInicial(); while(1){ glp_intopt(lp, NULL); // acha solucao com restricao de integralidade printf("Solucao Otima: %.3f\n", glp_mip_obj_val(lp)); printf("X1: %.3f\n", glp_mip_col_val(lp, 1)); printf("X2: %.3f\n", glp_mip_col_val(lp, 2)); printf("X3: %.3f\n", glp_mip_col_val(lp, 3)); int arestaEscolhida[1234]; for(int est = 1; est) { arestaEscolhida[est] = glp_mip_col_val(lp, est); } int verticesAlcancados[123]; for( ) ; // para contar se todos os vertices foram alcancados // se tiverem sido, de um break e mostre a resposta; encontraVerticesAlcancaveis(arestaEscolhida, verticesAlcancados); glp_add_row(lp, 1); int indCol[123]; double val[123]; int nCoef = 0; for (int e = 1; e <= nArestas; ++e) { Estrada estrada = estradas[e]; int nextremosAlcancados = verticesAlcancados[estrada.ori] + verticesAlcancados[estrada.dest]; if (nextremosAlcancados == 1) { indCol[nCoef + 1] = e; val[nCoef + 1] = 1.0; } } glp_set_mat_row(lp, glp_get_num_rows(lp), nCoef, indCol, val); glp_set_row_bnds(lp, glp_get_num_rows(lp), GLP_LO, 2.0, 2.0); system("PAUSE"); return EXIT_SUCCESS; }
vector<int> LinearProblem::ElasticFilter() const { LinearProblem tmp(*this); int realCols = glp_get_num_cols(tmp.lp_); for (int i = realCols; i > 0; --i) { // set old coefs to zero glp_set_obj_coef(tmp.lp_, i, 0); } int elasticCols = glp_get_num_rows(tmp.lp_); glp_add_cols(tmp.lp_, elasticCols); for (int i = 1; i <= elasticCols; ++i) { int indices[MAX_VARS]; double values[MAX_VARS]; int nonZeros = glp_get_mat_row(tmp.lp_, i, indices, values); indices[nonZeros + 1] = realCols + i; values[nonZeros + 1] = 1.0; glp_set_mat_row(tmp.lp_, i, nonZeros + 1, indices, values); glp_set_obj_coef(tmp.lp_, realCols + i, 1); glp_set_col_bnds(tmp.lp_, realCols + i, GLP_UP, 0.0, 0.0); } vector<int> suspects; glp_std_basis(tmp.lp_); int status = tmp.Solve(); while ((status != GLP_INFEAS) && (status != GLP_NOFEAS)) { for (int i = 1; i <= elasticCols; ++i) { if (glp_get_col_prim(tmp.lp_, realCols + i) < 0) { suspects.push_back(i); glp_set_col_bnds(tmp.lp_, realCols + i, GLP_FX, 0.0, 0.0); } } status = tmp.Solve(); } return suspects; }
/* Restriction bci = ai - bi + xi = Ti and z += ai*Ei + bi*Li */ void addBasicRestriction(glp_prob * Prob, int plane) { int cardinal, constr[4], i = plane, cardRow; double cValues[4]; char buf[AUXSIZE]; cardinal = glp_add_cols(Prob, 3); sprintf(buf,"a%i",i); glp_set_col_name(Prob, cardinal, buf); glp_set_col_bnds(Prob, cardinal, GLP_LO, 0, 0); glp_set_obj_coef(Prob, cardinal, planes[i].costE); sprintf(buf,"b%i",i); glp_set_col_name(Prob, cardinal+1, buf); glp_set_col_bnds(Prob, cardinal+1, GLP_LO, 0, 0); glp_set_obj_coef(Prob, cardinal+1, planes[i].costL); sprintf(buf,"x%i",i); glp_set_col_name(Prob, cardinal+2, buf); if( planes[i].earliest == planes[i].latest ) glp_set_col_bnds(Prob, cardinal+2, GLP_FX, planes[i].earliest, 0); else glp_set_col_bnds(Prob, cardinal+2, GLP_DB, planes[i].earliest, planes[i].latest); cardRow = glp_add_rows(Prob, 1); sprintf(buf,"bc%i",i); glp_set_row_name(Prob, cardRow, buf); glp_set_row_bnds(Prob, cardRow, GLP_FX, planes[i].ideal, 0); constr[3] = 1 + (constr[2] = 1 + (constr[1] = cardinal)); cValues[3] = cValues[1] = 1; cValues[2] = -1; glp_set_mat_row(Prob, cardRow, 3, constr, cValues); }
int main() { // Variáveis auxiliares int i, j, constraintNumber, *constraintIndices; double *constraintCoefficients; // Aloca os vetores utilizados para criar as restrições do problema // *********************************************************************************************** // ATENÇÃO ===> É importante dizer que estes vetores serão utilizados da posição 1 em diante // Ou seja, no GLPK você aloca uma posição a mais e descarta a posição 0 dos vetores. // *********************************************************************************************** constraintIndices = (int*)malloc((n+1)*sizeof(int)); constraintCoefficients = (double*)malloc((n+1)*sizeof(double)); // Cria um modelo com nenhuma variável e nenhuma restrição glp_prob *model = glp_create_prob(); // Define o sentido da otimização que, para este problema, é minimização glp_set_obj_dir(model, GLP_MIN); // Cria as variáveis (colunas) no modelo // Para este problema são necessárias n*n variáveis // Estas n*n variáveis são definidas pelo GLPK através dos indices que vão de 1 até n*n (x1, x2, ..., x(n*n)) // Portanto, neste momento é importante determinar qual variável no GLPK (índice) representará qual variável x[i,j] // Para tanto, fazemos o mapeamento das variáveis x[i,j] utilizando a fórmula (i-1)*n + j // Isto é, a variável x[i,j] será representada pela variável de índice (i-1)*n + j no modelo do GLPK // Note que é imprescindível que cada índice (variável do GLPK) seja associado a no máximo uma variável x[i,j] // Caso contrário, uma variável do GLPK pode representar duas variáveis x[i,j] diferentes que assumem valores distintos nas soluções ótimas // Neste caso, o modelo estará incorreto glp_add_cols(model, n*n); // Ajuste dos tipos, limitantes e coeficientes da função objetivo das variáveis do modelo for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) { // Define o tipo da variável como sendo binária (em outros modelos poderia ser contínua (GLP_CV) ou inteira (GLP_IV)) glp_set_col_kind(model, (i-1)*n + j, GLP_BV); // Define o limitante inferior (0) e superior (1) da variável // Consultem no manual as outras forma para definir apenas o limitante inferior ou superior glp_set_col_bnds(model, (i-1)*n + j, GLP_DB, 0.0, 1.0); // Define o coeficiente da variável na função objetivo glp_set_obj_coef(model, (i-1)*n + j, c[i-1][j-1]); } // Cria no modelo 2n restrições (linhas) nulas (com os coeficientes e limitantes zerados) // Ou seja, neste momento é criada uma matriz de zeros que correspondem aos coeficientes das restrições do modelo // O próximo passo será modificar esta matriz de tal forma que ela represente as restrições do problema descrito glp_add_rows(model, 2*n); // Esta variável define qual das restrições (qual linha da matriz de coeficientes) estamos modificando // ************************************************************************************************************ // ATENÇÃO: perceba que as restrições (linhas), assim como as variáveis (colunas), são indexadas a partir de 1. // ************************************************************************************************************ constraintNumber = 1; // Preenchimento das restrições limitando a soma das linhas: // sum{j in 1..n} w[i,j]*x[i,j] <= u[i] para i in 1..n for (i = 1; i <= n; i++) { // Define o limite superior (RHS) da restrição glp_set_row_bnds(model, constraintNumber, GLP_UP, 0.0, u[i-1]); for (j = 1; j <= n; j++) { // Ajusta o índice da variável que será informado à rotina do GLPK constraintIndices[j] = (i-1)*n + j; // Ajusta o coeficiente da variável cujo índice foi definido na linha anterior para ser informado ao GLPK // ****************************************************************************************************** // ATENÇÃO: perceba que na matriz w os índices e colunas são indexados a partir de ZERO ! // ****************************************************************************************************** constraintCoefficients[j] = w[i-1][j-1]; } // Passa ao GLPK a restrição que acabou de ser definida nos vetores constraintIndices e constraintCoefficients glp_set_mat_row(model, constraintNumber, n, constraintIndices, constraintCoefficients); // atualiza o indice da próxima restrição a ser inserida constraintNumber++; } // Preenchimento das restrições limitando a soma das colunas: // sum{i in 1..n} w[i,j]*x[i,j] >= l[i] para j in 1..n for (j = 1; j <= n; j++) { // Define o limite inferior (RHS) da restrição glp_set_row_bnds(model, constraintNumber, GLP_LO, l[j-1], 0.0); for (i = 1; i <= n; i++) { // Ajusta o índice da variável que será informado a rotina do GLPK constraintIndices[i] = (i-1)*n + j; // Ajusta o coeficiente da variável cujo índice foi definido na linha anterior para ser informado ao GLPK constraintCoefficients[i] = w[i-1][j-1]; } // Passa ao GLPK a restrição que acabou de ser definida nos vetores constraintIndices e constraintCoefficients glp_set_mat_row(model, constraintNumber, n, constraintIndices, constraintCoefficients); // atualiza o indice da próxima restrição a ser inserida constraintNumber++; } // Define os parâmetros que serão passados ao resolvedor glp_iocp param; glp_init_iocp(¶m); // Ativa o presolver param.presolve = GLP_ON; // Resolve o modelo int status = glp_intopt(model, ¶m); // Verifica se houve algum erro durante a otimização if (status) { printf("Ocorreu um erro durante o processo de otimizacao.\n"); } else { // Verifica se o método encontrou uma solução status = glp_mip_status(model); if ((status == GLP_OPT) || (status == GLP_FEAS)) { // Imprime a solução encontrada if (status == GLP_OPT) printf("Solucao otima encontrada!\n"); else printf("A solucao encontrada pode nao ser otima!\n"); printf("Custo da solucao: %f\n", glp_mip_obj_val(model)); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) printf("%f ", glp_mip_col_val(model, (i-1)*n + j)); printf("\n"); } } else { printf("Nenhuma solucao foi encontrada!\n"); } } // Desaloca os vetores free(constraintIndices); free(constraintCoefficients); return 0; }
void ios_feas_pump(glp_tree *T) { glp_prob *P = T->mip; int n = P->n; glp_prob *lp = NULL; struct VAR *var = NULL; RNG *rand = NULL; GLPCOL *col; glp_smcp parm; int j, k, new_x, nfail, npass, nv, ret, stalling; double dist, tol; xassert(glp_get_status(P) == GLP_OPT); /* this heuristic is applied only once on the root level */ if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; /* determine number of binary variables */ nv = 0; for (j = 1; j <= n; j++) { col = P->col[j]; /* if x[j] is continuous, skip it */ if (col->kind == GLP_CV) continue; /* if x[j] is fixed, skip it */ if (col->type == GLP_FX) continue; /* x[j] is non-fixed integer */ xassert(col->kind == GLP_IV); if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) { /* x[j] is binary */ nv++; } else { /* x[j] is general integer */ if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("FPUMP heuristic cannot be applied due to genera" "l integer variables\n"); goto done; } } /* there must be at least one binary variable */ if (nv == 0) goto done; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Applying FPUMP heuristic...\n"); /* build the list of binary variables */ var = xcalloc(1+nv, sizeof(struct VAR)); k = 0; for (j = 1; j <= n; j++) { col = P->col[j]; if (col->kind == GLP_IV && col->type == GLP_DB) var[++k].j = j; } xassert(k == nv); /* create working problem object */ lp = glp_create_prob(); more: /* copy the original problem object to keep it intact */ glp_copy_prob(lp, P, GLP_OFF); /* we are interested to find an integer feasible solution, which is better than the best known one */ if (P->mip_stat == GLP_FEAS) { int *ind; double *val, bnd; /* add a row and make it identical to the objective row */ glp_add_rows(lp, 1); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { ind[j] = j; val[j] = P->col[j]->coef; } glp_set_mat_row(lp, lp->m, n, ind, val); xfree(ind); xfree(val); /* introduce upper (minimization) or lower (maximization) bound to the original objective function; note that this additional constraint is not violated at the optimal point to LP relaxation */ #if 0 /* modified by xypron <*****@*****.**> */ if (P->dir == GLP_MIN) { bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd < P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); } else if (P->dir == GLP_MAX) { bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd > P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); } else xassert(P != P); #else bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj; /* xprintf("bnd = %f\n", bnd); */ if (P->dir == GLP_MIN) glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); else if (P->dir == GLP_MAX) glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); else xassert(P != P); #endif } /* reset pass count */ npass = 0; /* invalidate the rounded point */ for (k = 1; k <= nv; k++) var[k].x = -1; pass: /* next pass starts here */ npass++; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Pass %d\n", npass); /* initialize minimal distance between the basic point and the rounded one obtained during this pass */ dist = DBL_MAX; /* reset failure count (the number of succeeded iterations failed to improve the distance) */ nfail = 0; /* if it is not the first pass, perturb the last rounded point rather than construct it from the basic solution */ if (npass > 1) { double rho, temp; if (rand == NULL) rand = rng_create_rand(); for (k = 1; k <= nv; k++) { j = var[k].j; col = lp->col[j]; rho = rng_uniform(rand, -0.3, 0.7); if (rho < 0.0) rho = 0.0; temp = fabs((double)var[k].x - col->prim); if (temp + rho > 0.5) var[k].x = 1 - var[k].x; } goto skip; } loop: /* innermost loop begins here */ /* round basic solution (which is assumed primal feasible) */ stalling = 1; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (col->prim < 0.5) { /* rounded value is 0 */ new_x = 0; } else { /* rounded value is 1 */ new_x = 1; } if (var[k].x != new_x) { stalling = 0; var[k].x = new_x; } } /* if the rounded point has not changed (stalling), choose and flip some its entries heuristically */ if (stalling) { /* compute d[j] = |x[j] - round(x[j])| */ for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; var[k].d = fabs(col->prim - (double)var[k].x); } /* sort the list of binary variables by descending d[j] */ qsort(&var[1], nv, sizeof(struct VAR), fcmp); /* choose and flip some rounded components */ for (k = 1; k <= nv; k++) { if (k >= 5 && var[k].d < 0.35 || k >= 10) break; var[k].x = 1 - var[k].x; } } skip: /* check if the time limit has been exhausted */ if (T->parm->tm_lim < INT_MAX && (double)(T->parm->tm_lim - 1) <= 1000.0 * xdifftime(xtime(), T->tm_beg)) goto done; /* build the objective, which is the distance between the current (basic) point and the rounded one */ lp->dir = GLP_MIN; lp->c0 = 0.0; for (j = 1; j <= n; j++) lp->col[j]->coef = 0.0; for (k = 1; k <= nv; k++) { j = var[k].j; if (var[k].x == 0) lp->col[j]->coef = +1.0; else { lp->col[j]->coef = -1.0; lp->c0 += 1.0; } } /* minimize the distance with the simplex method */ glp_init_smcp(&parm); if (T->parm->msg_lev <= GLP_MSG_ERR) parm.msg_lev = T->parm->msg_lev; else if (T->parm->msg_lev <= GLP_MSG_ALL) { parm.msg_lev = GLP_MSG_ON; parm.out_dly = 10000; } ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("delta = %g\n", lp->obj_val); /* check if the basic solution is integer feasible; note that it may be so even if the minimial distance is positive */ tol = 0.3 * T->parm->tol_int; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (tol < col->prim && col->prim < 1.0 - tol) break; } if (k > nv) { /* okay; the basic solution seems to be integer feasible */ double *x = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { x[j] = lp->col[j]->prim; if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5); } #if 1 /* modified by xypron <*****@*****.**> */ /* reset direction and right-hand side of objective */ lp->c0 = P->c0; lp->dir = P->dir; /* fix integer variables */ for (k = 1; k <= nv; k++) #if 0 /* 18/VI-2013; fixed by mao * this bug causes numerical instability, because column statuses * are not changed appropriately */ { lp->col[var[k].j]->lb = x[var[k].j]; lp->col[var[k].j]->ub = x[var[k].j]; lp->col[var[k].j]->type = GLP_FX; } #else glp_set_col_bnds(lp, var[k].j, GLP_FX, x[var[k].j], 0.); #endif /* copy original objective function */ for (j = 1; j <= n; j++) lp->col[j]->coef = P->col[j]->coef; /* solve original LP and copy result */ ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } for (j = 1; j <= n; j++) if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim; #endif ret = glp_ios_heur_sol(T, x); xfree(x); if (ret == 0) { /* the integer solution is accepted */ if (ios_is_hopeful(T, T->curr->bound)) { /* it is reasonable to apply the heuristic once again */ goto more; } else { /* the best known integer feasible solution just found is close to optimal solution to LP relaxation */ goto done; } } }
static void update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n", GNUNET_i2s (&address->peer)); GNUNET_assert (NULL != address); GNUNET_assert (NULL != address->mlp_information); GNUNET_assert (NULL != address->ats); struct MLP_information *mlpi = address->mlp_information; struct GNUNET_ATS_Information *ats = address->ats; GNUNET_assert (mlpi != NULL); int c; for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { int index = mlp_lookup_ats(address, mlp->q[c]); if (index == GNUNET_SYSERR) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), (double) ats[index].value); int i = mlpi->q_avg_i[c]; double * qp = mlpi->q[c]; qp[i] = (double) ats[index].value; int t; for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), t, qp[t]); } if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH)) mlpi->q_avg_i[c] ++; else mlpi->q_avg_i[c] = 0; int c2; int c3; double avg = 0.0; switch (mlp->q[c]) { case GNUNET_ATS_QUALITY_NET_DELAY: c3 = 0; for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++) { if (mlpi->q[c][c2] != -1) { double * t2 = mlpi->q[c] ; avg += t2[c2]; c3 ++; } } if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else mlpi->q_averaged[c] = 0.0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), avg, avg / (double) c3, mlpi->q_averaged[c]); break; case GNUNET_ATS_QUALITY_NET_DISTANCE: c3 = 0; for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++) { if (mlpi->q[c][c2] != -1) { double * t2 = mlpi->q[c] ; avg += t2[c2]; c3 ++; } } if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else mlpi->q_averaged[c] = 0.0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), avg, avg / (double) c3, mlpi->q_averaged[c]); break; default: break; } if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0)) { /* Get current number of columns */ int found = GNUNET_NO; int cols = glp_get_num_cols(mlp->prob); int *ind = GNUNET_malloc (cols * sizeof (int) + 1); double *val = GNUNET_malloc (cols * sizeof (double) + 1); /* Get the matrix row of quality */ int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b); int c4; /* Get the index if matrix row of quality */ for (c4 = 1; c4 <= length; c4++ ) { if (mlpi->c_b == ind[c4]) { /* Update the value */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n", mlp_ats_to_string(mlp->q[c]), glp_get_col_name (mlp->prob, ind[c4]), glp_get_row_name (mlp->prob, mlp->r_q[c]), val[c4], mlpi->q_averaged[c]); val[c4] = mlpi->q_averaged[c]; found = GNUNET_YES; break; } } if (found == GNUNET_NO) { ind[length+1] = mlpi->c_b; val[length+1] = mlpi->q_averaged[c]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]); glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val); } else { /* Get the index if matrix row of quality */ glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val); } GNUNET_free (ind); GNUNET_free (val); } } }
int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound) { /* solve integer feasibility problem */ NPP *npp = NULL; glp_prob *mip = NULL; int *obj_ind = NULL; double *obj_val = NULL; int obj_row = 0; int i, j, k, obj_len, temp, ret; /* check the problem object */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_intfeas1: P = %p; invalid problem object\n", P); if (P->tree != NULL) xerror("glp_intfeas1: operation not allowed\n"); /* integer solution is currently undefined */ P->mip_stat = GLP_UNDEF; P->mip_obj = 0.0; /* check columns (variables) */ for (j = 1; j <= P->n; j++) { GLPCOL *col = P->col[j]; #if 0 /* currently binarization is not yet implemented */ if (!(col->kind == GLP_IV || col->type == GLP_FX)) { xprintf("glp_intfeas1: column %d: non-integer non-fixed var" "iable not allowed\n", j); #else if (!((col->kind == GLP_IV && col->lb == 0.0 && col->ub == 1.0) || col->type == GLP_FX)) { xprintf("glp_intfeas1: column %d: non-binary non-fixed vari" "able not allowed\n", j); #endif ret = GLP_EDATA; goto done; } temp = (int)col->lb; if ((double)temp != col->lb) { if (col->type == GLP_FX) xprintf("glp_intfeas1: column %d: fixed value %g is non-" "integer or out of range\n", j, col->lb); else xprintf("glp_intfeas1: column %d: lower bound %g is non-" "integer or out of range\n", j, col->lb); ret = GLP_EDATA; goto done; } temp = (int)col->ub; if ((double)temp != col->ub) { xprintf("glp_intfeas1: column %d: upper bound %g is non-int" "eger or out of range\n", j, col->ub); ret = GLP_EDATA; goto done; } if (col->type == GLP_DB && col->lb > col->ub) { xprintf("glp_intfeas1: column %d: lower bound %g is greater" " than upper bound %g\n", j, col->lb, col->ub); ret = GLP_EBOUND; goto done; } } /* check rows (constraints) */ for (i = 1; i <= P->m; i++) { GLPROW *row = P->row[i]; GLPAIJ *aij; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { temp = (int)aij->val; if ((double)temp != aij->val) { xprintf("glp_intfeas1: row = %d, column %d: constraint c" "oefficient %g is non-integer or out of range\n", i, aij->col->j, aij->val); ret = GLP_EDATA; goto done; } } temp = (int)row->lb; if ((double)temp != row->lb) { if (row->type == GLP_FX) xprintf("glp_intfeas1: row = %d: fixed value %g is non-i" "nteger or out of range\n", i, row->lb); else xprintf("glp_intfeas1: row = %d: lower bound %g is non-i" "nteger or out of range\n", i, row->lb); ret = GLP_EDATA; goto done; } temp = (int)row->ub; if ((double)temp != row->ub) { xprintf("glp_intfeas1: row = %d: upper bound %g is non-inte" "ger or out of range\n", i, row->ub); ret = GLP_EDATA; goto done; } if (row->type == GLP_DB && row->lb > row->ub) { xprintf("glp_intfeas1: row %d: lower bound %g is greater th" "an upper bound %g\n", i, row->lb, row->ub); ret = GLP_EBOUND; goto done; } } /* check the objective function */ temp = (int)P->c0; if ((double)temp != P->c0) { xprintf("glp_intfeas1: objective constant term %g is non-integ" "er or out of range\n", P->c0); ret = GLP_EDATA; goto done; } for (j = 1; j <= P->n; j++) { temp = (int)P->col[j]->coef; if ((double)temp != P->col[j]->coef) { xprintf("glp_intfeas1: column %d: objective coefficient is " "non-integer or out of range\n", j, P->col[j]->coef); ret = GLP_EDATA; goto done; } } /* save the objective function and set it to zero */ obj_ind = xcalloc(1+P->n, sizeof(int)); obj_val = xcalloc(1+P->n, sizeof(double)); obj_len = 0; obj_ind[0] = 0; obj_val[0] = P->c0; P->c0 = 0.0; for (j = 1; j <= P->n; j++) { if (P->col[j]->coef != 0.0) { obj_len++; obj_ind[obj_len] = j; obj_val[obj_len] = P->col[j]->coef; P->col[j]->coef = 0.0; } } /* add inequality to bound the objective function, if required */ if (!use_bound) xprintf("Will search for ANY feasible solution\n"); else { xprintf("Will search only for solution not worse than %d\n", obj_bound); obj_row = glp_add_rows(P, 1); glp_set_mat_row(P, obj_row, obj_len, obj_ind, obj_val); if (P->dir == GLP_MIN) glp_set_row_bnds(P, obj_row, GLP_UP, 0.0, (double)obj_bound - obj_val[0]); else if (P->dir == GLP_MAX) glp_set_row_bnds(P, obj_row, GLP_LO, (double)obj_bound - obj_val[0], 0.0); else xassert(P != P); } /* create preprocessor workspace */ xprintf("Translating to CNF-SAT...\n"); xprintf("Original problem has %d row%s, %d column%s, and %d non-z" "ero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); npp = npp_create_wksp(); /* load the original problem into the preprocessor workspace */ npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); /* perform translation to SAT-CNF problem instance */ ret = npp_sat_encode_prob(npp); if (ret == 0) ; else if (ret == GLP_ENOPFS) xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); else if (ret == GLP_ERANGE) xprintf("glp_intfeas1: translation to SAT-CNF failed because o" "f integer overflow\n"); else xassert(ret != ret); if (ret != 0) goto done; /* build SAT-CNF problem instance and try to solve it */ mip = glp_create_prob(); npp_build_prob(npp, mip); ret = glp_minisat1(mip); /* only integer feasible solution can be postprocessed */ if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) { P->mip_stat = mip->mip_stat; goto done; } /* postprocess the solution found */ npp_postprocess(npp, mip); /* the transformed problem is no longer needed */ glp_delete_prob(mip), mip = NULL; /* store solution to the original problem object */ npp_unload_sol(npp, P); /* change the solution status to 'integer feasible' */ P->mip_stat = GLP_FEAS; /* check integer feasibility */ for (i = 1; i <= P->m; i++) { GLPROW *row; GLPAIJ *aij; double sum; row = P->row[i]; sum = 0.0; for (aij = row->ptr; aij != NULL; aij = aij->r_next) sum += aij->val * aij->col->mipx; xassert(sum == row->mipx); if (row->type == GLP_LO || row->type == GLP_DB || row->type == GLP_FX) xassert(sum >= row->lb); if (row->type == GLP_UP || row->type == GLP_DB || row->type == GLP_FX) xassert(sum <= row->ub); } /* compute value of the original objective function */ P->mip_obj = obj_val[0]; for (k = 1; k <= obj_len; k++) P->mip_obj += obj_val[k] * P->col[obj_ind[k]]->mipx; xprintf("Objective value = %17.9e\n", P->mip_obj); done: /* delete the transformed problem, if it exists */ if (mip != NULL) glp_delete_prob(mip); /* delete the preprocessor workspace, if it exists */ if (npp != NULL) npp_delete_wksp(npp); /* remove inequality used to bound the objective function */ if (obj_row > 0) { int ind[1+1]; ind[1] = obj_row; glp_del_rows(P, 1, ind); } /* restore the original objective function */ if (obj_ind != NULL) { P->c0 = obj_val[0]; for (k = 1; k <= obj_len; k++) P->col[obj_ind[k]]->coef = obj_val[k]; xfree(obj_ind); xfree(obj_val); } return ret; }
void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob) { /* build LP/MIP problem instance from the model */ int m, n, i, j, t, kind, type, len, *ind; double lb, ub, *val; if (tran->phase != 3) xerror("glp_mpl_build_prob: invalid call sequence\n"); /* erase the problem object */ glp_erase_prob(prob); /* set problem name */ glp_set_prob_name(prob, mpl_get_prob_name(tran)); /* build rows (constraints) */ m = mpl_get_num_rows(tran); if (m > 0) glp_add_rows(prob, m); for (i = 1; i <= m; i++) { /* set row name */ glp_set_row_name(prob, i, mpl_get_row_name(tran, i)); /* set row bounds */ type = mpl_get_row_bnds(tran, i, &lb, &ub); switch (type) { case MPL_FR: type = GLP_FR; break; case MPL_LO: type = GLP_LO; break; case MPL_UP: type = GLP_UP; break; case MPL_DB: type = GLP_DB; break; case MPL_FX: type = GLP_FX; break; default: xassert(type != type); } if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) { type = GLP_FX; if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; } glp_set_row_bnds(prob, i, type, lb, ub); /* warn about non-zero constant term */ if (mpl_get_row_c0(tran, i) != 0.0) xprintf("glp_mpl_build_prob: row %s; constant term %.12g ig" "nored\n", mpl_get_row_name(tran, i), mpl_get_row_c0(tran, i)); } /* build columns (variables) */ n = mpl_get_num_cols(tran); if (n > 0) glp_add_cols(prob, n); for (j = 1; j <= n; j++) { /* set column name */ glp_set_col_name(prob, j, mpl_get_col_name(tran, j)); /* set column kind */ kind = mpl_get_col_kind(tran, j); switch (kind) { case MPL_NUM: break; case MPL_INT: case MPL_BIN: glp_set_col_kind(prob, j, GLP_IV); break; default: xassert(kind != kind); } /* set column bounds */ type = mpl_get_col_bnds(tran, j, &lb, &ub); switch (type) { case MPL_FR: type = GLP_FR; break; case MPL_LO: type = GLP_LO; break; case MPL_UP: type = GLP_UP; break; case MPL_DB: type = GLP_DB; break; case MPL_FX: type = GLP_FX; break; default: xassert(type != type); } if (kind == MPL_BIN) { if (type == GLP_FR || type == GLP_UP || lb < 0.0) lb = 0.0; if (type == GLP_FR || type == GLP_LO || ub > 1.0) ub = 1.0; type = GLP_DB; } if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) { type = GLP_FX; if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; } glp_set_col_bnds(prob, j, type, lb, ub); } /* load the constraint matrix */ ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) { len = mpl_get_mat_row(tran, i, ind, val); glp_set_mat_row(prob, i, len, ind, val); } /* build objective function (the first objective is used) */ for (i = 1; i <= m; i++) { kind = mpl_get_row_kind(tran, i); if (kind == MPL_MIN || kind == MPL_MAX) { /* set objective name */ glp_set_obj_name(prob, mpl_get_row_name(tran, i)); /* set optimization direction */ glp_set_obj_dir(prob, kind == MPL_MIN ? GLP_MIN : GLP_MAX); /* set constant term */ glp_set_obj_coef(prob, 0, mpl_get_row_c0(tran, i)); /* set objective coefficients */ len = mpl_get_mat_row(tran, i, ind, val); for (t = 1; t <= len; t++) glp_set_obj_coef(prob, ind[t], val[t]); break; } } /* free working arrays */ xfree(ind); xfree(val); return; }
bool isFeasible() { int nCons; int coef1[MAXNEDGES], coef2[MAXNEDGES]; int ind[MAXNEDGES+1]; double val[MAXNEDGES+1]; glp_prob * lp = glp_create_prob(); glp_set_obj_dir(lp, GLP_MAX); glp_add_cols(lp, nEdges+1); for (int i=0; i<nEdges+1; i++) glp_set_col_bnds(lp, i+1, GLP_LO, 0, 0); glp_set_obj_coef(lp, nEdges+1, 1); nCons = 0; for (int i=0; i<nEdges; i++) { nCons++; glp_add_rows(lp,1); glp_set_row_bnds(lp, nCons, GLP_UP, 0, 0); ind[1] = nEdges+1; val[1] = 1; //gamma <= l_e ind[2] = i+1; val[2] = -1; glp_set_mat_row(lp, nCons, 2, ind, val); } for (int m=0; m<k; m++) { int first = -1; for (int i=0; i<paths[m].n; i++) if (paths[m].isShort[i]) { first = i; break; } assert(first>=0); setCoef(coef1, m, first); for (int i=first+1; i<paths[m].n; i++) if (paths[m].isShort[i]) { setCoef(coef2, m, i); nCons++; glp_add_rows(lp,1); glp_set_row_bnds(lp, nCons, GLP_FX, 0, 0); int nEle = 0; for (int j=0; j<nEdges; j++) if (coef1[j] ^ coef2[j]) { nEle++; ind[nEle] = j+1; val[nEle] = (coef1[j])? 1:-1; } glp_set_mat_row(lp, nCons, nEle, ind, val); } for (int i=0; i<paths[m].n; i++) if (!paths[m].isShort[i]){ setCoef(coef2, m, i); nCons++; glp_add_rows(lp,1); glp_set_row_bnds(lp, nCons, GLP_UP, 0, 0); int nEle = 0; for (int j=0; j<nEdges; j++) if (coef1[j] ^ coef2[j]) { nEle++; ind[nEle] = j+1; val[nEle] = (coef1[j])? 1:-1; } glp_set_mat_row(lp, nCons, nEle, ind, val); } } nCons++; glp_add_rows(lp,1); glp_set_row_bnds(lp, nCons, GLP_UP, 0, 1); for (int j=0; j<nEdges; j++) { ind[j+1] = j+1; val[j+1] = 1; } glp_set_mat_row(lp, nCons, nEdges, ind, val); glp_term_out(GLP_OFF); glp_simplex(lp, NULL); double ret = glp_get_obj_val(lp); glp_delete_prob(lp); return (ret>0); }
void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], const double val[]) { /* set (replace) row of the constraint matrix */ glp_set_mat_row(lp, i, len, ind, val); return; }
/* Restrictions xj - xi >= Sij&ij + (Li - Ej)&ji and xi - xj >= Sji&ji + (Lj - Ei)&ij and &ij + &ji = 1*/ void addOrderConstraint(glp_prob * Prob, int plane1, int plane2) { int cardinal, constr[3], i = plane1, j = plane2; double cValues[3]; char buf[AUXSIZE]; int xi, xj, uij; sprintf(buf,"x%i",i); xi = glp_find_col(Prob, buf); sprintf(buf,"x%i",j); xj = glp_find_col(Prob, buf); uij = glp_add_cols(Prob, 2); sprintf(buf,"u%i,%i",i,j); glp_set_col_name(Prob, uij, buf); glp_set_col_kind(Prob, uij, GLP_BV); sprintf(buf,"u%i,%i",j,i); glp_set_col_name(Prob, uij+1, buf); glp_set_col_kind(Prob, uij+1, GLP_BV); cardinal = glp_add_rows(Prob, 2); sprintf(buf,"S%i,%i",i,j); glp_set_row_name(Prob, cardinal, buf); glp_set_row_bnds(Prob, cardinal, GLP_LO, 0, 0); constr[1] = xj; constr[2] = xi; constr[3] = uij; constr[4] = uij+1; cValues[1] = 1; cValues[2] = -1; cValues[3] = -planes[i].sep[j]; cValues[4] = planes[i].latest - planes[j].earliest; glp_set_mat_row(Prob, cardinal, 4, constr, cValues); sprintf(buf,"S%i,%i",j,i); glp_set_row_name(Prob, cardinal+1, buf); glp_set_row_bnds(Prob, cardinal+1, GLP_LO, 0, 0); constr[1] = xi; constr[2] = xj; constr[3] = uij+1; constr[4] = uij; cValues[1] = 1; cValues[2] = -1; cValues[3] = -planes[j].sep[i]; cValues[4] = planes[j].latest - planes[i].earliest; glp_set_mat_row(Prob, cardinal+1, 4, constr, cValues); cardinal = glp_add_rows(Prob, 1); sprintf(buf,"E%i,%i",i,j); glp_set_row_name(Prob, cardinal, buf); glp_set_row_bnds(Prob, cardinal, GLP_FX, 1, 0); constr[1] = uij; constr[2] = uij+1; cValues[1] = 1; cValues[2] = 1; glp_set_mat_row(Prob, cardinal, 2, constr, cValues); }
void c_glp_set_mat_row(glp_prob *lp, int i, int len, const int ind[], const double val[]){ glp_set_mat_row(lp, i, len, ind, val); }