void ios_proxy_heur(glp_tree *T) { glp_prob *prob; int j, status; double *xstar, zstar; /* this heuristic is applied only once on the root level */ if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; prob = glp_create_prob(); glp_copy_prob(prob, T->mip, 0); xstar = xcalloc(1+prob->n, sizeof(double)); for (j = 1; j <= prob->n; j++) xstar[j] = 0.0; if (T->mip->mip_stat != GLP_FEAS) status = proxy(prob, &zstar, xstar, NULL, 0.0, T->parm->ps_tm_lim, 1); else { double *xinit = xcalloc(1+prob->n, sizeof(double)); for (j = 1; j <= prob->n; j++) xinit[j] = T->mip->col[j]->mipx; status = proxy(prob, &zstar, xstar, xinit, 0.0, T->parm->ps_tm_lim, 1); xfree(xinit); } if (status == 0) glp_ios_heur_sol(T, xstar); xfree(xstar); glp_delete_prob(prob); done: return; }
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. } }
int main(void) { glp_prob *mip; glp_tran *tran; int ret; mip = glp_create_prob(); tran = glp_mpl_alloc_wksp(); ret = glp_mpl_read_model(tran, "sudoku.mod", 1); if (ret != 0) { fprintf(stderr, "Error on translating model\n"); goto skip; } ret = glp_mpl_read_data(tran, "sudoku.dat"); if (ret != 0) { fprintf(stderr, "Error on translating data\n"); goto skip; } ret = glp_mpl_generate(tran, NULL); if (ret != 0) { fprintf(stderr, "Error on generating model\n"); goto skip; } glp_mpl_build_prob(tran, mip); glp_simplex(mip, NULL); glp_intopt(mip, NULL); ret = glp_mpl_postsolve(tran, mip, GLP_MPL_MIP); if (ret != 0) fprintf(stderr, "Error on postsolving model\n"); skip: glp_mpl_free_wksp(tran); glp_delete_prob(mip); return 0; }
/** create the initial glp problem, define the rows and columns **/ static void create_glp(void) {int i; P=glp_create_prob(); glp_add_cols(P,cols); glp_add_rows(P,rows); /* set the objective to all zero */ for(i=0;i<=cols;i++)glp_set_obj_coef(P,i,0.0); glp_set_obj_dir(P,GLP_MIN); /* minimize */ }
int main(void) { glp_prob *mip = glp_create_prob(); glp_set_prob_name(mip, "sample"); glp_set_obj_dir(mip, GLP_MAX); // 拘束条件 // 具体的な関数は後で glp_add_rows(mip, 3); // 拘束条件の数 glp_set_row_name(mip, 1, "c1"); glp_set_row_bnds(mip, 1, GLP_DB, 0.0, 20.0); glp_set_row_name(mip, 2, "c2"); glp_set_row_bnds(mip, 2, GLP_DB, 0.0, 30.0); glp_set_row_name(mip, 3, "c3"); glp_set_row_bnds(mip, 3, GLP_FX, 0.0, 0); // 変数 // 変数そのものにかかる拘束は、拘束条件ではなくてこちらで管理 glp_add_cols(mip, 4); // 変数の数 glp_set_col_name(mip, 1, "x1"); glp_set_col_bnds(mip, 1, GLP_DB, 0.0, 40.0); glp_set_obj_coef(mip, 1, 1.0); glp_set_col_name(mip, 2, "x2"); glp_set_col_bnds(mip, 2, GLP_LO, 0.0, 0.0); glp_set_obj_coef(mip, 2, 2.0); glp_set_col_name(mip, 3, "x3"); glp_set_col_bnds(mip, 3, GLP_LO, 0.0, 0.0); glp_set_obj_coef(mip, 3, 3.0); glp_set_col_kind(mip, 3, GLP_IV); // 整数値としての宣言 glp_set_col_name(mip, 4, "x4"); glp_set_col_bnds(mip, 4, GLP_DB, 2.0, 3.0); glp_set_obj_coef(mip, 4, 1.0); glp_set_col_kind(mip, 4, GLP_IV); // 整数値としての宣言 int ia[1+9], ja[1+9]; double ar[1+9]; ia[1]=1,ja[1]=1,ar[1]=-1; // a[1,1] = -1 ia[2]=1,ja[2]=2,ar[2]=1; // a[1,2] = 1 ia[3]=1,ja[3]=3,ar[3]=1; // a[1,3] = 1 ia[4]=1,ja[4]=4,ar[4]=10; // a[1,4] = 10 ia[5]=2,ja[5]=1,ar[5]=1; // a[2,1] = 1 ia[6]=2,ja[6]=2,ar[6]=-3; // a[2,2] = -3 ia[7]=2,ja[7]=3,ar[7]=1; // a[2,3] = 1 ia[8]=3,ja[8]=2,ar[8]=1; // a[3,2] = 1 ia[9]=3,ja[9]=4,ar[9]=-3.5; // a[3,4] = -3.5 glp_load_matrix(mip, 9, ia, ja, ar); glp_iocp parm; glp_init_iocp(&parm); parm.presolve = GLP_ON; int err = glp_intopt(mip, &parm); double z = glp_mip_obj_val(mip); double x1 = glp_mip_col_val(mip, 1); double x2 = glp_mip_col_val(mip, 2); double x3 = glp_mip_col_val(mip, 3); double x4 = glp_mip_col_val(mip, 4); printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g, x4 = %g\n", z, x1, x2, x3, x4); // z = 122.5; x1 = 40; x2 = 10.5; x3 = 19.5, x4 = 3 glp_delete_prob(mip); return 0; }
IPimpl(IP::DirType dir, int n_th) : ip_(NULL), ia_(1), ja_(1), ar_(1) { ip_ = glp_create_prob(); switch (dir) { case IP::MIN: glp_set_obj_dir(ip_, GLP_MIN); break; case IP::MAX: glp_set_obj_dir(ip_, GLP_MAX); break; } }
int main(void) { glp_prob *P; P = glp_create_prob(); glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); glp_adv_basis(P, 0); glp_simplex(P, NULL); glp_print_sol(P, "25fv47.txt"); glp_delete_prob(P); return 0; }
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); // } }
void CMyProblem::_alloc( int _n) { n=_n; r.resize(n,0); w.resize(n,0); original_index.resize(n,0); for(int i=0;i<n;i++) original_index[i]=i; lp = glp_create_prob(); }
static PyObject* LPX_Erase(LPXObject *self) { #if GLPK_VERSION(4, 29) glp_erase_prob(LP); #else // Approximate the functionality by deleting and reassigning the // underlying pointer. The Python code shouldn't actually know the // difference. if (LP) glp_delete_prob(LP); self->lp = glp_create_prob(); #endif Py_RETURN_NONE; }
int main(void) { glp_prob *P; glp_smcp parm; P = glp_create_prob(); glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); glp_init_smcp(&parm); parm.meth = GLP_DUAL; glp_simplex(P, &parm); glp_print_sol(P, "25fv47.txt"); glp_delete_prob(P); return 0; }
NUMlinprog NUMlinprog_new (bool maximize) { NUMlinprog me = nullptr; try { me = Melder_calloc (structNUMlinprog, 1); my linearProgram = glp_create_prob (); // TODO: check glp_set_obj_dir (my linearProgram, maximize ? GLP_MAX : GLP_MIN); } catch (MelderError) { if (me) NUMlinprog_delete (me); return NULL; } return me; }
int GLPKInitialize() { if (GLPKModel != NULL) { if (GLPKClearSolver() == FAIL) { return FAIL; } } GLPKModel = glp_create_prob(); //lpx_set_int_parm(GLPKModel, LPX_K_BFTYPE,3); //lpx_set_class(GLPKModel, LPX_LP); There is no equivalent in the new API return SUCCESS; }
B2GlpkHasher::B2GlpkHasher(const B2TraceCoeffs &trace_coeffs, const B2StrSet &str_set) : B2HasherBase(str_set) { _lp = glp_create_prob(); glp_set_prob_name(_lp, "Bouma2-GLPK"); glp_set_obj_dir(_lp, GLP_MIN); add_trace_vars(trace_coeffs); add_str_constraints(); #ifdef B2_GLPK_DEBUG glp_write_prob(_lp, 0, b2_preproc_config(B2_CFG_GLPK_DEBUG_FILE).c_str()); #endif //B2_GLPK_DEBUG build_hash(); _motif_set.remove_duplicates(trace_coeffs); };
int main(void) { glp_prob *lp; int ia[1+1000], ja[1+1000]; double ar[1+1000], z, x1, x2, x3; s1: lp = glp_create_prob(); s2: glp_set_prob_name(lp, "sample"); s3: glp_set_obj_dir(lp, GLP_MAX); s4: glp_add_rows(lp, 3); s5: glp_set_row_name(lp, 1, "p"); s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); s7: glp_set_row_name(lp, 2, "q"); s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); s9: glp_set_row_name(lp, 3, "r"); s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); s11: glp_add_cols(lp, 3); s12: glp_set_col_name(lp, 1, "x1"); s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); s14: glp_set_obj_coef(lp, 1, 10.0); s15: glp_set_col_name(lp, 2, "x2"); s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); s17: glp_set_obj_coef(lp, 2, 6.0); s18: glp_set_col_name(lp, 3, "x3"); s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); s20: glp_set_obj_coef(lp, 3, 4.0); s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ s30: glp_load_matrix(lp, 9, ia, ja, ar); s31: glp_simplex(lp, NULL); s32: z = glp_get_obj_val(lp); s33: x1 = glp_get_col_prim(lp, 1); s34: x2 = glp_get_col_prim(lp, 2); s35: x3 = glp_get_col_prim(lp, 3); s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", z, x1, x2, x3); s37: glp_delete_prob(lp); return 0; }
/** * Build a model with one column * @param forceError force error if bit 0 = 1 */ void buildModel(int forceError) { glp_prob *lp; /* create problem */ lp = glp_create_prob(); if (forceError & 1) { /* add -1 column * this will cause an error. */ glp_add_cols(lp, -1); } else { /* add 1 column */ glp_add_cols(lp, 1); } /* delete problem */ glp_delete_prob(lp); }
/* 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); }
LPX *lpx_read_model(const char *model, const char *data, const char *output) { /* read LP/MIP model written in GNU MathProg language */ LPX *lp = NULL; glp_tran *tran; /* allocate the translator workspace */ tran = glp_mpl_alloc_wksp(); /* read model section and optional data section */ if (glp_mpl_read_model(tran, model, data != NULL)) goto done; /* read separate data section, if required */ if (data != NULL) if (glp_mpl_read_data(tran, data)) goto done; /* generate the model */ if (glp_mpl_generate(tran, output)) goto done; /* build the problem instance from the model */ lp = glp_create_prob(); glp_mpl_build_prob(tran, lp); done: /* free the translator workspace */ glp_mpl_free_wksp(tran); /* bring the problem object to the calling program */ return lp; }
/* 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; }
int main(int argc, char *argv[]) { /* structures de données propres à GLPK */ glp_prob *prob; // déclaration d'un pointeur sur le problème int ia[1 + NBCREUX]; int ja[1 + NBCREUX]; double ar[1 + NBCREUX]; // déclaration des 3 tableaux servant à définir la partie creuse de la matrice des contraintes int p[N+1]; p[1] = 34; p[2] = 6; p[3] = 8; p[4] = 17; p[5] = 16; p[6] = 5; p[7] = 13; p[8] = 21; p[9] = 25; p[10] = 31; p[11] = 14; p[12] = 13; p[13] = 33; p[14] = 9; p[15] = 25; p[16] = 25; /* variables récupérant les résultats de la résolution du problème (fonction objectif et valeur des variables) */ int i,j,pos; double z; double x[NBVAR]; /* Les déclarations suivantes sont optionnelles, leur but est de donner des noms aux variables et aux contraintes. Cela permet de lire plus facilement le modèle saisi si on en demande un affichage à GLPK, ce qui est souvent utile pour détecter une erreur! */ char nomcontr[NBCONTR][8]; /* ici, les contraintes seront nommées "caisse1", "caisse2",... */ char numero[NBCONTR][3]; /* pour un nombre à deux chiffres */ char nomvar[NBVAR][3]; /* "xA", "xB", ... */ /* Création d'un problème (initialement vide) */ prob = glp_create_prob(); /* allocation mémoire pour le problème */ glp_set_prob_name(prob, "wagons"); /* affectation d'un nom (on pourrait mettre NULL) */ glp_set_obj_dir(prob, GLP_MIN); /* Il s'agit d'un problème de minimisation, on utiliserait la constante GLP_MAX dans le cas contraire */ /* Déclaration du nombre de contraintes (nombre de lignes de la matrice des contraintes) : NBCONTR */ glp_add_rows(prob, NBCONTR); /* On commence par préciser les bornes sur les constrainte, les indices des contraintes commencent à 1 (!) dans GLPK */ for(i = 1;i <= N;i++) { /* partie optionnelle : donner un nom aux contraintes */ strcpy(nomcontr[i-1], "caisse"); sprintf(numero[i-1], "%d", i); strcat(nomcontr[i-1], numero[i-1]); /* Les contraintes sont nommés "salle1", "salle2"... */ glp_set_row_name(prob, i, nomcontr[i-1]); /* Affectation du nom à la contrainte i */ /* partie indispensable : les bornes sur les contraintes */ glp_set_row_bnds(prob, i, GLP_FX, 1.0, 1.0); } for(i = N+1;i <= NBCONTR;i++) { /* partie optionnelle : donner un nom aux contraintes */ strcpy(nomcontr[i-1], "chaMax"); sprintf(numero[i-1], "%d", i); strcat(nomcontr[i-1], numero[i-1]); /* Les contraintes sont nommés "chargemax", "chargemax2"... */ glp_set_row_name(prob, i, nomcontr[i-1]); /* Affectation du nom à la contrainte i */ // il doit manquer un bout ici glp_set_row_bnds(prob, i, GLP_UP, 0.0, 0.0); //<=0 // on met cmax a gauche car c'est une variable // il aura le coeff -1 dans la mat creuse } /* Déclaration du nombre de variables : NBVAR */ glp_add_cols(prob, NBVAR); /* On précise le type des variables, les indices commencent à 1 également pour les variables! */ for(i = 1;i <= NBVAR;i++) { if(i==NBVAR){ sprintf(nomvar[i-1],"Cm"); glp_set_col_name(prob, i , nomvar[i-1]); glp_set_col_bnds(prob, i, GLP_LO, 0.0, 0.0); }else{ /* partie optionnelle : donner un nom aux variables */ sprintf(nomvar[i-1],"x%d",i-1); glp_set_col_name(prob, i , nomvar[i-1]); /* Les variables sont nommées "xA", "xB"... afin de respecter les noms de variables de l'exercice 2.2 */ /* partie obligatoire : bornes éventuelles sur les variables, et type */ glp_set_col_bnds(prob, i, GLP_DB, 0.0, 1.0); /* bornes sur les variables, comme sur les contraintes */ glp_set_col_kind(prob, i, GLP_BV); /* les variables sont par défaut continues, nous précisons ici qu'elles sont binaires avec la constante GLP_BV, on utiliserait GLP_IV pour des variables entières */ } } /* définition des coefficients des variables dans la fonction objectif */ for(i = 1;i <= N*M;i++) glp_set_obj_coef(prob,i,0.0); // Tous les coûts sont ici à 0! Mais on doit specifier quand meme glp_set_obj_coef(prob,N*M+1,1.0); // 1 fois cmax /* Définition des coefficients non-nuls dans la matrice des contraintes, autrement dit les coefficients de la matrice creuse */ /* Les indices commencent également à 1 ! */ // pour i de 1 a n //pour i de 1 a m /* xij intervient dans la ligne i avec un coeff 1 et dans la ligne n+j avec un coeff pi ia -> i et n+j ar -> 1 et pi ja -> xij -> (i-1)*m+j */ pos = 1; for(i=1; i<=N; i++){ for(j=1; j<=M; j++){ ia[pos] = i; ja[pos] = (i-1)*M+j; ar[pos] = 1; pos++; ia[pos] = N+j; ja[pos] = (i-1)*M+j; ar[pos] = p[i]; pos++; } } //Cmax a -1 !!! for(i=N+1; i<=N+M;i++){ ia[pos] = i; ja[pos] = N*M+1; ar[pos] = -1; pos++; } /* chargement de la matrice dans le problème */ glp_load_matrix(prob,NBCREUX,ia,ja,ar); /* Optionnel : écriture de la modélisation dans un fichier (TRES utile pour debugger!) */ glp_write_lp(prob,NULL,"wagons.lp"); /* Résolution, puis lecture des résultats */ glp_simplex(prob,NULL); glp_intopt(prob,NULL); /* Résolution */ z = glp_mip_obj_val(prob); /* Récupération de la valeur optimale. Dans le cas d'un problème en variables continues, l'appel est différent : z = glp_get_obj_val(prob); */ for(i = 0;i < NBVAR; i++) x[i] = glp_mip_col_val(prob,i+1); /* Récupération de la valeur des variables, Appel différent dans le cas d'un problème en variables continues : for(i = 0;i < p.nbvar;i++) x[i] = glp_get_col_prim(prob,i+1); */ printf("z = %lf\n",z); for(i = 0;i < NBVAR;i++) printf("x%d = %d, ",i,(int)(x[i] + 0.5)); /* un cast est ajouté, x[i] pourrait être égal à 0.99999... */ puts(""); /* libération mémoire */ glp_delete_prob(prob); /* J'adore qu'un plan se déroule sans accroc! */ return 0; }
static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) { /* solve MIP using the preprocessor */ ENV *env = get_env_ptr(); int term_out = env->term_out; NPP *npp; glp_prob *mip = NULL; glp_bfcp bfcp; glp_smcp smcp; int ret; if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Preprocessing...\n"); /* create preprocessor workspace */ npp = npp_create_wksp(); /* load original problem into the preprocessor workspace */ npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); /* process MIP prior to applying the branch-and-bound method */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; ret = npp_integer(npp, parm); env->term_out = term_out; if (ret == 0) ; else if (ret == GLP_ENOPFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); } else if (ret == GLP_ENODFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); } else xassert(ret != ret); if (ret != 0) goto done; /* build transformed MIP */ mip = glp_create_prob(); npp_build_prob(npp, mip); /* if the transformed MIP is empty, it has empty solution, which is optimal */ if (mip->m == 0 && mip->n == 0) { mip->mip_stat = GLP_OPT; mip->mip_obj = mip->c0; if (parm->msg_lev >= GLP_MSG_ALL) { xprintf("Objective value = %17.9e\n", mip->mip_obj); xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" "\n"); } goto post; } /* display some statistics */ if (parm->msg_lev >= GLP_MSG_ALL) { int ni = glp_get_num_int(mip); int nb = glp_get_num_bin(mip); char s[50]; xprintf("%d row%s, %d column%s, %d non-zero%s\n", mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : "s", mip->nnz, mip->nnz == 1 ? "" : "s"); if (nb == 0) strcpy(s, "none of"); else if (ni == 1 && nb == 1) strcpy(s, ""); else if (nb == 1) strcpy(s, "one of"); else if (nb == ni) strcpy(s, "all of"); else sprintf(s, "%d of", nb); xprintf("%d integer variable%s, %s which %s binary\n", ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } /* inherit basis factorization control parameters */ glp_get_bfcp(P, &bfcp); glp_set_bfcp(mip, &bfcp); /* scale the transformed problem */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_scale_prob(mip, GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); env->term_out = term_out; /* build advanced initial basis */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_adv_basis(mip, 0); env->term_out = term_out; /* solve initial LP relaxation */ if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Solving LP relaxation...\n"); glp_init_smcp(&smcp); smcp.msg_lev = parm->msg_lev; mip->it_cnt = P->it_cnt; ret = glp_simplex(mip, &smcp); P->it_cnt = mip->it_cnt; if (ret != 0) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: cannot solve LP relaxation\n"); ret = GLP_EFAIL; goto done; } /* check status of the basic solution */ ret = glp_get_status(mip); if (ret == GLP_OPT) ret = 0; else if (ret == GLP_NOFEAS) ret = GLP_ENOPFS; else if (ret == GLP_UNBND) ret = GLP_ENODFS; else xassert(ret != ret); if (ret != 0) goto done; /* solve the transformed MIP */ mip->it_cnt = P->it_cnt; #if 0 /* 11/VII-2013 */ ret = solve_mip(mip, parm); #else if (parm->use_sol) { mip->mip_stat = P->mip_stat; mip->mip_obj = P->mip_obj; } ret = solve_mip(mip, parm, P, npp); #endif P->it_cnt = mip->it_cnt; /* 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 solution from the transformed MIP */ post: npp_postprocess(npp, mip); /* the transformed MIP is no longer needed */ glp_delete_prob(mip), mip = NULL; /* store solution to the original problem */ npp_unload_sol(npp, P); done: /* delete the transformed MIP, if it exists */ if (mip != NULL) glp_delete_prob(mip); /* delete preprocessor workspace */ npp_delete_wksp(npp); return ret; }
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; }
int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, int x[/*1+ne*/]) { glp_prob *lp; glp_smcp smcp; int i, k, nz, flow, *rn, *cn; double temp, *aa; /* create LP problem instance */ lp = glp_create_prob(); /* create LP rows; i-th row is the conservation condition of the * flow at i-th node, i = 1, ..., nn */ glp_add_rows(lp, nn); for (i = 1; i <= nn; i++) glp_set_row_bnds(lp, i, GLP_FX, 0.0, 0.0); /* create LP columns; k-th column is the elementary flow thru * k-th edge, k = 1, ..., ne; the last column with the number * ne+1 is the total flow through the network, which goes along * a dummy feedback edge from the sink to the source */ glp_add_cols(lp, ne+1); for (k = 1; k <= ne; k++) { xassert(cap[k] > 0); glp_set_col_bnds(lp, k, GLP_DB, -cap[k], +cap[k]); } glp_set_col_bnds(lp, ne+1, GLP_FR, 0.0, 0.0); /* build the constraint matrix; structurally this matrix is the * incidence matrix of the network, so each its column (including * the last column for the dummy edge) has exactly two non-zero * entries */ rn = xalloc(1+2*(ne+1), sizeof(int)); cn = xalloc(1+2*(ne+1), sizeof(int)); aa = xalloc(1+2*(ne+1), sizeof(double)); nz = 0; for (k = 1; k <= ne; k++) { /* x[k] > 0 means the elementary flow thru k-th edge goes from * node beg[k] to node end[k] */ nz++, rn[nz] = beg[k], cn[nz] = k, aa[nz] = -1.0; nz++, rn[nz] = end[k], cn[nz] = k, aa[nz] = +1.0; } /* total flow thru the network goes from the sink to the source * along the dummy feedback edge */ nz++, rn[nz] = t, cn[nz] = ne+1, aa[nz] = -1.0; nz++, rn[nz] = s, cn[nz] = ne+1, aa[nz] = +1.0; /* check the number of non-zero entries */ xassert(nz == 2*(ne+1)); /* load the constraint matrix into the LP problem object */ glp_load_matrix(lp, nz, rn, cn, aa); xfree(rn); xfree(cn); xfree(aa); /* objective function is the total flow through the network to * be maximized */ glp_set_obj_dir(lp, GLP_MAX); glp_set_obj_coef(lp, ne + 1, 1.0); /* solve LP instance with the (primal) simplex method */ glp_term_out(0); glp_adv_basis(lp, 0); glp_term_out(1); glp_init_smcp(&smcp); smcp.msg_lev = GLP_MSG_ON; smcp.out_dly = 5000; xassert(glp_simplex(lp, &smcp) == 0); xassert(glp_get_status(lp) == GLP_OPT); /* obtain optimal elementary flows thru edges of the network */ /* (note that the constraint matrix is unimodular and the data * are integral, so all elementary flows in basic solution should * also be integral) */ for (k = 1; k <= ne; k++) { temp = glp_get_col_prim(lp, k); x[k] = (int)floor(temp + .5); xassert(fabs(x[k] - temp) <= 1e-6); } /* obtain the maximum flow thru the original network which is the * flow thru the dummy feedback edge */ temp = glp_get_col_prim(lp, ne+1); flow = (int)floor(temp + .5); xassert(fabs(flow - temp) <= 1e-6); /* delete LP problem instance */ glp_delete_prob(lp); /* return to the calling program */ return flow; }
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; } } }
int main(int argc, char *argv[]) { /* Structures de données propres à GLPK */ glp_prob *prob; // Déclaration d'un pointeur sur le problème int ia[1 + NBCREUX]; int ja[1 + NBCREUX]; double ar[1 + NBCREUX]; // Déclaration des 3 tableaux servant à définir la partie creuse de la matrice des contraintes /* Variables récupérant les résultats de la résolution du problème (fonction objectif et valeur des variables) */ int i, j; double z; double x[NBVAR]; // Autres variables int * p = (int*)malloc(n * sizeof(int)); p[1] = 34; p[2] = 6; p[3] = 8; p[4] = 17; p[5] = 16; p[6] = 5; p[7] = 13; p[8] = 21; p[9] = 25; p[10] = 31; p[11] = 14; p[12] = 13; p[13] = 33; p[14] = 9; p[15] = 25; p[16] = 25; /* Transfert de ces données dans les structures utilisées par la bibliothèque GLPK */ prob = glp_create_prob(); /* allocation mémoire pour le problème */ glp_set_prob_name(prob, "wagons"); /* affectation d'un nom */ glp_set_obj_dir(prob, GLP_MIN); /* Il s'agit d'un problème de minimisation */ /* Déclaration du nombre de contraintes (nombre de lignes de la matrice des contraintes) */ glp_add_rows(prob, NBCONTR); /* On commence par préciser les bornes sur les contraintes, les indices commencent à 1 (!) dans GLPK */ /* Premier ensemble de contraintes ( c = 1 ) */ for(i = 1; i <= n; i++) { glp_set_row_bnds(prob, i, GLP_FX, 1.0, 1.0); } /* Second ensembles de contraintes (c <= 0 ) */ for(i = n + 1; i <= NBCONTR; i++) { glp_set_row_bnds(prob, i, GLP_UP, 0.0, 0.0); } /* Déclaration du nombre de variables */ glp_add_cols(prob, NBVAR); /* On précise le type des variables, les indices commencent à 1 également pour les variables! */ for(i = 1; i <= NBVAR - 1; i++) { glp_set_col_bnds(prob, i, GLP_DB, 0.0, 1.0); glp_set_col_kind(prob, i, GLP_BV); /* les variables sont binaires */ } glp_set_col_bnds(prob, NBVAR, GLP_LO, 0.0, 0.0); /* La dernière variables est continue (par défaut) non négative */ /* Définition des coefficients des variables dans la fonction objectif */ for(i = 1;i <= n*m;i++) { glp_set_obj_coef(prob,i,0.0); // Tous les coûts sont à 0 (sauf le dernier) } /* Dernier coût (qui vaut 1) */ glp_set_obj_coef(prob,n*m + 1,1.0); /* Définition des coefficients non-nuls dans la matrice des contraintes, autrement dit les coefficients de la matrice creuse */ int pos = 1; for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { // Première moitié de la matrice ja[pos] = (i - 1)*m + j; ia[pos] = i; ar[pos] = 1; pos++; // Deuxième moitié de la matrice ja[pos] = (i - 1)*m + j; ia[pos] = n + j; ar[pos] = p[i]; pos++; } } // ajout des -1 dans la dernière colonne for(i = n + 1; i <= n + m; i++) { ja[pos] = n*m + 1; ia[pos] = i; ar[pos] = -1; pos++; } /* Chargement de la matrice dans le problème */ glp_load_matrix(prob,NBCREUX,ia,ja,ar); /* Ecriture de la modélisation dans un fichier */ glp_write_lp(prob,NULL,"wagons.lp"); /* Résolution, puis lecture des résultats */ glp_simplex(prob,NULL); glp_intopt(prob,NULL); /* Résolution */ z = glp_mip_obj_val(prob); /* Récupération de la valeur optimale. Dans le cas d'un problème en variables continues, l'appel est différent : z = glp_get_obj_val(prob); */ for(i = 0;i < NBVAR; i++) x[i] = glp_mip_col_val(prob,i+1); /* Récupération de la valeur des variables, Appel différent dans le cas d'un problème en variables continues : for(i = 0;i < p.nbvar;i++) x[i] = glp_get_col_prim(prob,i+1); */ printf("z = %lf\n",z); for(i = 0;i < NBVAR;i++) printf("x%c = %d, ",'B'+i,(int)(x[i] + 0.5)); /* un cast est ajouté, x[i] pourrait être égal à 0.99999... */ puts(""); /* Libération de la mémoire */ glp_delete_prob(prob); free(p); return 0; }
/** * Create the MLP problem * * @param mlp the MLP handle * @param addresses the hashmap containing all adresses * @return GNUNET_OK or GNUNET_SYSERR */ static int mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses) { int res = GNUNET_OK; int col; int c; char *name; GNUNET_assert (mlp->prob == NULL); /* create the glpk problem */ mlp->prob = glp_create_prob (); /* Set a problem name */ glp_set_prob_name (mlp->prob, "gnunet ats bandwidth distribution"); /* Set optimization direction to maximize */ glp_set_obj_dir (mlp->prob, GLP_MAX); /* Adding invariant columns */ /* Diversity d column */ col = glp_add_cols (mlp->prob, 1); mlp->c_d = col; /* Column name */ glp_set_col_name (mlp->prob, col, "d"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_D); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); /* Utilization u column */ col = glp_add_cols (mlp->prob, 1); mlp->c_u = col; /* Column name */ glp_set_col_name (mlp->prob, col, "u"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_U); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); #if ENABLE_C9 /* Relativity r column */ col = glp_add_cols (mlp->prob, 1); mlp->c_r = col; /* Column name */ glp_set_col_name (mlp->prob, col, "r"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_R); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); #endif /* Quality metric columns */ col = glp_add_cols(mlp->prob, mlp->m_q); for (c = 0; c < mlp->m_q; c++) { mlp->c_q[c] = col + c; GNUNET_asprintf (&name, "q_%u", mlp->q[c]); glp_set_col_name (mlp->prob, col + c, name); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col + c, GLP_LO, 0.0, 0.0); GNUNET_free (name); /* Coefficient == Qm */ glp_set_obj_coef (mlp->prob, col + c, mlp->co_Q[c]); } /* Add columns for addresses */ GNUNET_CONTAINER_multihashmap_iterate (addresses, create_columns_it, mlp); /* Add constraints */ mlp_add_constraints_all_addresses (mlp, addresses); /* Load the matrix */ glp_load_matrix(mlp->prob, (mlp->ci-1), mlp->ia, mlp->ja, mlp->ar); return res; }
/** * Init the MLP problem solving component * * @param cfg the GNUNET_CONFIGURATION_Handle handle * @param stats the GNUNET_STATISTICS handle * @param max_duration maximum numbers of iterations for the LP/MLP Solver * @param max_iterations maximum time limit for the LP/MLP Solver * @return struct GAS_MLP_Handle * on success, NULL on fail */ struct GAS_MLP_Handle * GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_STATISTICS_Handle *stats, struct GNUNET_TIME_Relative max_duration, unsigned int max_iterations) { struct GAS_MLP_Handle * mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle)); double D; double R; double U; unsigned long long tmp; unsigned int b_min; unsigned int n_min; struct GNUNET_TIME_Relative i_exec; int c; char * quota_out_str; char * quota_in_str; /* Init GLPK environment */ int res = glp_init_env(); switch (res) { case 0: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", "initialization successful"); break; case 1: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", "environment is already initialized"); break; case 2: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", "initialization failed (insufficient memory)"); GNUNET_free(mlp); return NULL; break; case 3: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", "initialization failed (unsupported programming model)"); GNUNET_free(mlp); return NULL; break; default: break; } /* Create initial MLP problem */ mlp->prob = glp_create_prob(); GNUNET_assert (mlp->prob != NULL); mlp->BIG_M = (double) BIG_M_VALUE; /* Get diversity coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_D", &tmp)) D = (double) tmp / 100; else D = 1.0; /* Get proportionality coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_R", &tmp)) R = (double) tmp / 100; else R = 1.0; /* Get utilization coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_U", &tmp)) U = (double) tmp / 100; else U = 1.0; /* Get quality metric coefficients from configuration */ int i_delay = -1; int i_distance = -1; int q[GNUNET_ATS_QualityPropertiesCount] = GNUNET_ATS_QualityProperties; for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { /* initialize quality coefficients with default value 1.0 */ mlp->co_Q[c] = 1.0; mlp->q[c] = q[c]; if (q[c] == GNUNET_ATS_QUALITY_NET_DELAY) i_delay = c; if (q[c] == GNUNET_ATS_QUALITY_NET_DISTANCE) i_distance = c; } if ((i_delay != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_QUALITY_DELAY", &tmp))) mlp->co_Q[i_delay] = (double) tmp / 100; else mlp->co_Q[i_delay] = 1.0; if ((i_distance != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_QUALITY_DISTANCE", &tmp))) mlp->co_Q[i_distance] = (double) tmp / 100; else mlp->co_Q[i_distance] = 1.0; /* Get minimum bandwidth per used address from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "MIN_BANDWIDTH", &tmp)) b_min = tmp; else { b_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); } /* Get minimum number of connections from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "MIN_CONNECTIONS", &tmp)) n_min = tmp; else n_min = 4; /* Init network quotas */ int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType; for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) { mlp->quota_index[c] = quotas[c]; static char * entry_in = NULL; static char * entry_out = NULL; unsigned long long quota_in = 0; unsigned long long quota_out = 0; switch (quotas[c]) { case GNUNET_ATS_NET_UNSPECIFIED: entry_out = "UNSPECIFIED_QUOTA_OUT"; entry_in = "UNSPECIFIED_QUOTA_IN"; break; case GNUNET_ATS_NET_LOOPBACK: entry_out = "LOOPBACK_QUOTA_OUT"; entry_in = "LOOPBACK_QUOTA_IN"; break; case GNUNET_ATS_NET_LAN: entry_out = "LAN_QUOTA_OUT"; entry_in = "LAN_QUOTA_IN"; break; case GNUNET_ATS_NET_WAN: entry_out = "WAN_QUOTA_OUT"; entry_in = "WAN_QUOTA_IN"; break; case GNUNET_ATS_NET_WLAN: entry_out = "WLAN_QUOTA_OUT"; entry_in = "WLAN_QUOTA_IN"; break; default: break; } if ((entry_in == NULL) || (entry_out == NULL)) continue; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str)) { if (0 == strcmp(quota_out_str, BIG_M_STRING) || (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, "a_out))) quota_out = mlp->BIG_M; GNUNET_free (quota_out_str); quota_out_str = NULL; } else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_out = mlp->BIG_M; } else { quota_out = mlp->BIG_M; } if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str)) { if (0 == strcmp(quota_in_str, BIG_M_STRING) || (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, "a_in))) quota_in = mlp->BIG_M; GNUNET_free (quota_in_str); quota_in_str = NULL; } else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_in = mlp->BIG_M; } else { quota_in = mlp->BIG_M; } /* Check if defined quota could make problem unsolvable */ if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c])) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); GAS_mlp_done(mlp); mlp = NULL; return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n", entry_out, quota_out, entry_in, quota_in); GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO); GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO); mlp->quota_out[c] = quota_out; mlp->quota_in[c] = quota_in; } /* Get minimum number of connections from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "ats", "ATS_EXEC_INTERVAL", &i_exec)) mlp->exec_interval = i_exec; else mlp->exec_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30); mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; mlp->max_iterations = max_iterations; mlp->max_exec_duration = max_duration; mlp->auto_solve = GNUNET_YES; /* Redirect GLPK output to GNUnet logging */ glp_error_hook((void *) mlp, &mlp_term_hook); /* Init LP solving parameters */ glp_init_smcp(&mlp->control_param_lp); mlp->control_param_lp.msg_lev = GLP_MSG_OFF; #if VERBOSE_GLPK mlp->control_param_lp.msg_lev = GLP_MSG_ALL; #endif mlp->control_param_lp.it_lim = max_iterations; mlp->control_param_lp.tm_lim = max_duration.rel_value; /* Init MLP solving parameters */ glp_init_iocp(&mlp->control_param_mlp); mlp->control_param_mlp.msg_lev = GLP_MSG_OFF; #if VERBOSE_GLPK mlp->control_param_mlp.msg_lev = GLP_MSG_ALL; #endif mlp->control_param_mlp.tm_lim = max_duration.rel_value; mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS; mlp->co_D = D; mlp->co_R = R; mlp->co_U = U; mlp->b_min = b_min; mlp->n_min = n_min; mlp->m_q = GNUNET_ATS_QualityPropertiesCount; mlp->semaphore = GNUNET_NO; return mlp; }
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; }
static void solve(char* file_name) { ppl_Constraint_System_t ppl_cs; #ifndef NDEBUG ppl_Constraint_System_t ppl_cs_copy; #endif ppl_Generator_t optimum_location; ppl_Linear_Expression_t ppl_le; int dimension, row, num_rows, column, nz, i, j, type; int* coefficient_index; double lb, ub; double* coefficient_value; mpq_t rational_lb, rational_ub; mpq_t* rational_coefficient; mpq_t* objective; ppl_Linear_Expression_t ppl_objective_le; ppl_Coefficient_t optimum_n; ppl_Coefficient_t optimum_d; mpq_t optimum; mpz_t den_lcm; int optimum_found; glp_mpscp glpk_mpscp; glpk_lp = glp_create_prob(); glp_init_mpscp(&glpk_mpscp); if (verbosity == 0) { /* FIXME: find a way to suppress output from glp_read_mps. */ } #ifdef PPL_LPSOL_SUPPORTS_TIMINGS if (print_timings) start_clock(); #endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */ if (glp_read_mps(glpk_lp, GLP_MPS_FILE, &glpk_mpscp, file_name) != 0) fatal("cannot read MPS file `%s'", file_name); #ifdef PPL_LPSOL_SUPPORTS_TIMINGS if (print_timings) { fprintf(stderr, "Time to read the input file: "); print_clock(stderr); fprintf(stderr, " s\n"); start_clock(); } #endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */ glpk_lp_num_int = glp_get_num_int(glpk_lp); if (glpk_lp_num_int > 0 && !no_mip && !use_simplex) fatal("the enumeration solving method can not handle MIP problems"); dimension = glp_get_num_cols(glpk_lp); /* Read variables constrained to be integer. */ if (glpk_lp_num_int > 0 && !no_mip && use_simplex) { if (verbosity >= 4) fprintf(output_file, "Integer variables:\n"); integer_variables = (ppl_dimension_type*) malloc((glpk_lp_num_int + 1)*sizeof(ppl_dimension_type)); for (i = 0, j = 0; i < dimension; ++i) { int col_kind = glp_get_col_kind(glpk_lp, i+1); if (col_kind == GLP_IV || col_kind == GLP_BV) { integer_variables[j] = i; if (verbosity >= 4) { ppl_io_fprint_variable(output_file, i); fprintf(output_file, " "); } ++j; } } } coefficient_index = (int*) malloc((dimension+1)*sizeof(int)); coefficient_value = (double*) malloc((dimension+1)*sizeof(double)); rational_coefficient = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t)); ppl_new_Constraint_System(&ppl_cs); mpq_init(rational_lb); mpq_init(rational_ub); for (i = 1; i <= dimension; ++i) mpq_init(rational_coefficient[i]); mpz_init(den_lcm); if (verbosity >= 4) fprintf(output_file, "\nConstraints:\n"); /* Set up the row (ordinary) constraints. */ num_rows = glp_get_num_rows(glpk_lp); for (row = 1; row <= num_rows; ++row) { /* Initialize the least common multiple computation. */ mpz_set_si(den_lcm, 1); /* Set `nz' to the number of non-zero coefficients. */ nz = glp_get_mat_row(glpk_lp, row, coefficient_index, coefficient_value); for (i = 1; i <= nz; ++i) { set_mpq_t_from_double(rational_coefficient[i], coefficient_value[i]); /* Update den_lcm. */ mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_coefficient[i])); } lb = glp_get_row_lb(glpk_lp, row); ub = glp_get_row_ub(glpk_lp, row); set_mpq_t_from_double(rational_lb, lb); set_mpq_t_from_double(rational_ub, ub); mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb)); mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub)); ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension); for (i = 1; i <= nz; ++i) { mpz_mul(tmp_z, den_lcm, mpq_numref(rational_coefficient[i])); mpz_divexact(tmp_z, tmp_z, mpq_denref(rational_coefficient[i])); ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z); ppl_Linear_Expression_add_to_coefficient(ppl_le, coefficient_index[i]-1, ppl_coeff); } type = glp_get_row_type(glpk_lp, row); add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs); ppl_delete_Linear_Expression(ppl_le); } free(coefficient_value); for (i = 1; i <= dimension; ++i) mpq_clear(rational_coefficient[i]); free(rational_coefficient); free(coefficient_index); #ifndef NDEBUG ppl_new_Constraint_System_from_Constraint_System(&ppl_cs_copy, ppl_cs); #endif /* FIXME: here we could build the polyhedron and minimize it before adding the variable bounds. */ /* Set up the columns constraints, i.e., variable bounds. */ for (column = 1; column <= dimension; ++column) { lb = glp_get_col_lb(glpk_lp, column); ub = glp_get_col_ub(glpk_lp, column); set_mpq_t_from_double(rational_lb, lb); set_mpq_t_from_double(rational_ub, ub); /* Initialize the least common multiple computation. */ mpz_set_si(den_lcm, 1); mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb)); mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub)); ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension); ppl_assign_Coefficient_from_mpz_t(ppl_coeff, den_lcm); ppl_Linear_Expression_add_to_coefficient(ppl_le, column-1, ppl_coeff); type = glp_get_col_type(glpk_lp, column); add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs); ppl_delete_Linear_Expression(ppl_le); } mpq_clear(rational_ub); mpq_clear(rational_lb); /* Deal with the objective function. */ objective = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t)); /* Initialize the least common multiple computation. */ mpz_set_si(den_lcm, 1); mpq_init(objective[0]); set_mpq_t_from_double(objective[0], glp_get_obj_coef(glpk_lp, 0)); for (i = 1; i <= dimension; ++i) { mpq_init(objective[i]); set_mpq_t_from_double(objective[i], glp_get_obj_coef(glpk_lp, i)); /* Update den_lcm. */ mpz_lcm(den_lcm, den_lcm, mpq_denref(objective[i])); } /* Set the ppl_objective_le to be the objective function. */ ppl_new_Linear_Expression_with_dimension(&ppl_objective_le, dimension); /* Set value for objective function's inhomogeneous term. */ mpz_mul(tmp_z, den_lcm, mpq_numref(objective[0])); mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[0])); ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z); ppl_Linear_Expression_add_to_inhomogeneous(ppl_objective_le, ppl_coeff); /* Set values for objective function's variable coefficients. */ for (i = 1; i <= dimension; ++i) { mpz_mul(tmp_z, den_lcm, mpq_numref(objective[i])); mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[i])); ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z); ppl_Linear_Expression_add_to_coefficient(ppl_objective_le, i-1, ppl_coeff); } if (verbosity >= 4) { fprintf(output_file, "Objective function:\n"); if (mpz_cmp_si(den_lcm, 1) != 0) fprintf(output_file, "("); ppl_io_fprint_Linear_Expression(output_file, ppl_objective_le); } for (i = 0; i <= dimension; ++i) mpq_clear(objective[i]); free(objective); if (verbosity >= 4) { if (mpz_cmp_si(den_lcm, 1) != 0) { fprintf(output_file, ")/"); mpz_out_str(output_file, 10, den_lcm); } fprintf(output_file, "\n%s\n", (maximize ? "Maximizing." : "Minimizing.")); } ppl_new_Coefficient(&optimum_n); ppl_new_Coefficient(&optimum_d); ppl_new_Generator_zero_dim_point(&optimum_location); optimum_found = use_simplex ? solve_with_simplex(ppl_cs, ppl_objective_le, optimum_n, optimum_d, optimum_location) : solve_with_generators(ppl_cs, ppl_objective_le, optimum_n, optimum_d, optimum_location); ppl_delete_Linear_Expression(ppl_objective_le); if (glpk_lp_num_int > 0) free(integer_variables); if (optimum_found) { mpq_init(optimum); ppl_Coefficient_to_mpz_t(optimum_n, tmp_z); mpq_set_num(optimum, tmp_z); ppl_Coefficient_to_mpz_t(optimum_d, tmp_z); mpz_mul(tmp_z, tmp_z, den_lcm); mpq_set_den(optimum, tmp_z); if (verbosity == 1) fprintf(output_file, "Optimized problem.\n"); if (verbosity >= 2) fprintf(output_file, "Optimum value: %.10g\n", mpq_get_d(optimum)); if (verbosity >= 3) { fprintf(output_file, "Optimum location:\n"); ppl_Generator_divisor(optimum_location, ppl_coeff); ppl_Coefficient_to_mpz_t(ppl_coeff, tmp_z); for (i = 0; i < dimension; ++i) { mpz_set(mpq_denref(tmp1_q), tmp_z); ppl_Generator_coefficient(optimum_location, i, ppl_coeff); ppl_Coefficient_to_mpz_t(ppl_coeff, mpq_numref(tmp1_q)); ppl_io_fprint_variable(output_file, i); fprintf(output_file, " = %.10g\n", mpq_get_d(tmp1_q)); } } #ifndef NDEBUG { ppl_Polyhedron_t ph; unsigned int relation; ppl_new_C_Polyhedron_recycle_Constraint_System(&ph, ppl_cs_copy); ppl_delete_Constraint_System(ppl_cs_copy); relation = ppl_Polyhedron_relation_with_Generator(ph, optimum_location); ppl_delete_Polyhedron(ph); assert(relation == PPL_POLY_GEN_RELATION_SUBSUMES); } #endif maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED, mpq_get_d(optimum)); mpq_clear(optimum); } ppl_delete_Constraint_System(ppl_cs); ppl_delete_Coefficient(optimum_d); ppl_delete_Coefficient(optimum_n); ppl_delete_Generator(optimum_location); glp_delete_prob(glpk_lp); }
int c_simplex_sparse(int m, int n, DMAT(c), DMAT(b), DVEC(s)) { glp_prob *lp; lp = glp_create_prob(); glp_set_obj_dir(lp, GLP_MAX); int i,j,k; int tot = cr - n; glp_add_rows(lp, m); glp_add_cols(lp, n); //printf("%d %d\n",m,n); // the first n values for (k=1;k<=n;k++) { glp_set_obj_coef(lp, k, AT(c, k-1, 2)); //printf("%d %f\n",k,AT(c, k-1, 2)); } int * ia = malloc((1+tot)*sizeof(int)); int * ja = malloc((1+tot)*sizeof(int)); double * ar = malloc((1+tot)*sizeof(double)); for (k=1; k<= tot; k++) { ia[k] = rint(AT(c,k-1+n,0)); ja[k] = rint(AT(c,k-1+n,1)); ar[k] = AT(c,k-1+n,2); //printf("%d %d %f\n",ia[k],ja[k],ar[k]); } glp_load_matrix(lp, tot, ia, ja, ar); int t; for (i=1;i<=m;i++) { switch((int)rint(AT(b,i-1,0))) { case 0: { t = GLP_FR; break; } case 1: { t = GLP_LO; break; } case 2: { t = GLP_UP; break; } case 3: { t = GLP_DB; break; } default: { t = GLP_FX; break; } } glp_set_row_bnds(lp, i, t , AT(b,i-1,1), AT(b,i-1,2)); } for (j=1;j<=n;j++) { switch((int)rint(AT(b,m+j-1,0))) { case 0: { t = GLP_FR; break; } case 1: { t = GLP_LO; break; } case 2: { t = GLP_UP; break; } case 3: { t = GLP_DB; break; } default: { t = GLP_FX; break; } } glp_set_col_bnds(lp, j, t , AT(b,m+j-1,1), AT(b,m+j-1,2)); } glp_term_out(0); glp_simplex(lp, NULL); sp[0] = glp_get_status(lp); sp[1] = glp_get_obj_val(lp); for (k=1; k<=n; k++) { sp[k+1] = glp_get_col_prim(lp, k); } glp_delete_prob(lp); free(ia); free(ja); free(ar); return 0; }