void B2GlpkHasher::build_hash() { glp_simplex(_lp, NULL); glp_iocp parm; glp_init_iocp(&parm); parm.presolve = GLP_ON; parm.binarize = GLP_ON; glp_intopt(_lp, &parm); double motif_count = glp_mip_obj_val(_lp); if((motif_count > 0) && (motif_count <= (_str_set.size() * 2))) { _motif_set = _trace_set; B2HashMap<B2Trace, unsigned int> &trace_vals = _motif_set.trace_vals(); for(B2HashMap<B2Trace, unsigned int>::iterator trace_it = trace_vals.begin(); trace_it != trace_vals.end(); ) { double is_motif = glp_mip_col_val(_lp, trace_it->second); if(is_motif == 0) { _motif_set.erase(trace_it->first); B2_HASH_MAP_ERASE(trace_vals, trace_it); } else { ++trace_it; }; }; } else { b2_preproc_error_inc(B2_PREPROC_ERROR_BAD_MOTIF_SET, 1); }; };
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; }
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); // } }
double solve() { glp_smcp smcp; glp_iocp iocp; glp_init_smcp(&smcp); smcp.msg_lev = GLP_MSG_ERR; glp_init_iocp(&iocp); iocp.msg_lev = GLP_MSG_ERR; glp_load_matrix(ip_, ia_.size()-1, &ia_[0], &ja_[0], &ar_[0]); glp_simplex(ip_, &smcp); glp_intopt(ip_, &iocp); return glp_mip_obj_val(ip_); }
int CMyProblem::PrintMIPSolution(ostream &out) { glp_create_index(lp); out << "MIP solution" << endl; out << "Dir;" << ((glp_get_obj_dir(lp)==GLP_MIN) ? "min" : "max") << endl; out << "f;" << glp_mip_obj_val(lp) << endl; out << "Status;" << DecodeStatus(glp_mip_status(lp)) << endl; PrintSolArray(lp,"x",out,true); PrintSolArray(lp,"y",out,true); glp_delete_index(lp); return 0; }
/* 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); }
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; }
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 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; }
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 void maybe_check_results(const int ppl_status, const double ppl_optimum_value) { const char* ppl_status_string; const char* glpk_status_string; int glpk_status; int treat_as_lp = 0; glp_smcp glpk_smcp; if (!check_results) return; if (no_mip || glpk_lp_num_int == 0) treat_as_lp = 1; glp_set_obj_dir(glpk_lp, (maximize ? GLP_MAX : GLP_MIN)); glp_init_smcp(&glpk_smcp); /* Disable GLPK output. */ glpk_smcp.msg_lev = GLP_MSG_OFF; if (treat_as_lp) { /* Set the problem class to LP: MIP problems are thus treated as LP ones. */ glp_exact(glpk_lp, &glpk_smcp); glpk_status = glp_get_status(glpk_lp); } else { /* MIP case. */ glp_simplex(glpk_lp, &glpk_smcp); glpk_status = glp_get_status(glpk_lp); if (glpk_status != GLP_NOFEAS && glpk_status != GLP_UNBND) { glp_iocp glpk_iocp; glp_init_iocp(&glpk_iocp); /* Disable GLPK output. */ glpk_iocp.msg_lev = GLP_MSG_OFF; glp_intopt(glpk_lp, &glpk_iocp); glpk_status = glp_mip_status(glpk_lp); } } /* If no_optimization is enabled, the second case is not possibile. */ if (!((ppl_status == PPL_MIP_PROBLEM_STATUS_UNFEASIBLE && glpk_status == GLP_NOFEAS) || (ppl_status == PPL_MIP_PROBLEM_STATUS_UNBOUNDED && glpk_status == GLP_UNBND) || (ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED && (glpk_status == GLP_OPT /* If no_optimization is enabled, check if the problem is unbounded for GLPK. */ || (no_optimization && (glpk_status == GLP_UNBND || glpk_status == GLP_UNDEF)))))) { if (ppl_status == PPL_MIP_PROBLEM_STATUS_UNFEASIBLE) ppl_status_string = "unfeasible"; else if (ppl_status == PPL_MIP_PROBLEM_STATUS_UNBOUNDED) ppl_status_string = "unbounded"; else if (ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED) ppl_status_string = "optimizable"; else ppl_status_string = "<?>"; switch (glpk_status) { case GLP_NOFEAS: glpk_status_string = "unfeasible"; break; case GLP_UNBND: glpk_status_string = "unbounded"; break; case GLP_OPT: glpk_status_string = "optimizable"; break; case GLP_UNDEF: glpk_status_string = "undefined"; break; default: glpk_status_string = "<?>"; break; } error("check failed: for GLPK the problem is %s, not %s", glpk_status_string, ppl_status_string); check_results_failed = 1; } else if (!no_optimization && ppl_status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED) { double glpk_optimum_value = (treat_as_lp ? glp_get_obj_val(glpk_lp) : glp_mip_obj_val(glpk_lp)); if (fabs(ppl_optimum_value - glpk_optimum_value) > check_threshold) { error("check failed: for GLPK the problem's optimum is %.20g," " not %.20g", glpk_optimum_value, ppl_optimum_value); check_results_failed = 1; } } return; }
int DBWorker::_RememberRun(CMyProblem &P, int idobjectives, const char* modelfile, double time, bool mip, int idruns) { int idrun = -1; try { sql::PreparedStatement *PrepStmt; sql::ResultSet *res; PrepStmt = con->prepareStatement( "INSERT INTO runs(idobjectives,modelfile,runtype,res_status,res_value,time_in_seconds,idruns) VALUES(?,?,?,?,?,?,?)" ); PrepStmt->setInt(1, idobjectives); PrepStmt->setString(2, modelfile); PrepStmt->setString(3, mip ? "mip" : "lp"); if(!mip) { PrepStmt->setInt(4, glp_get_status(P.GetProblem())); PrepStmt->setDouble(5, glp_get_obj_val(P.GetProblem())); PrepStmt->setNull(7,0); } else { PrepStmt->setInt(4, glp_mip_status(P.GetProblem())); PrepStmt->setDouble(5, glp_mip_obj_val(P.GetProblem())); PrepStmt->setInt(7,idruns); } PrepStmt->setDouble(6, time); PrepStmt->execute(); delete PrepStmt; if(!mip) { PrepStmt = con->prepareStatement( "SELECT LAST_INSERT_ID()" ); res = PrepStmt->executeQuery(); delete PrepStmt; res->next(); idrun = res->getInt(1); delete res; } else { idrun = idruns; } cout << "Run ID " << idrun << endl; PrepStmt = con->prepareStatement( "INSERT INTO results(idrun,var_name,i,j,value,runtype) VALUES(?,?,?,?,?,?)" ); PrepStmt->setInt(1, idrun); PrepStmt->setString(6, mip ? "mip" : "lp"); vector<vector<double>> arr; for (int vvv=1; vvv>=0; vvv--) { char* var_name = (vvv ? "x" : "y"); GetSolArray(P.GetProblem(),var_name,arr,mip); PrepStmt->setString(2, var_name); int i=1; for (std::vector<vector<double>>::iterator it = arr.begin() ; it != arr.end(); ++it) { int j=1; for (std::vector<double>::iterator it2 = (*it).begin() ; it2 != (*it).end(); ++it2) { PrepStmt->setInt(3, i); PrepStmt->setInt(4, j); PrepStmt->setDouble(5, *it2); PrepStmt->execute(); j++; } i++; } } delete PrepStmt; } catch (sql::SQLException &e) { SQLError(e); } return idrun; }
OptSolutionData* GLPKRunSolver(int ProbType) { OptSolutionData* NewSolution = NULL; int NumVariables = glp_get_num_cols(GLPKModel); int Status = 0; if (ProbType == MILP) { Status = glp_simplex(GLPKModel, NULL); // Use default settings if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } Status = glp_intopt(GLPKModel, NULL); // Use default settings if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = glp_mip_status(GLPKModel); if (Status == GLP_UNDEF || Status == GLP_NOFEAS) { NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == GLP_FEAS) { NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == GLP_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = glp_mip_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = glp_mip_col_val(GLPKModel, i+1); } } else if (ProbType == LP) { //First we check the basis matrix to ensure it is not singular if (glp_warm_up(GLPKModel) != 0) { glp_adv_basis(GLPKModel, 0); } Status = glp_simplex(GLPKModel, NULL); // Use default settings if (Status == GLP_EBADB) { /* the basis is invalid; build some valid basis */ glp_adv_basis(GLPKModel, 0); Status = glp_simplex(GLPKModel, NULL); // Use default settings } if (Status != 0) { FErrorFile() << "Failed to optimize problem." << endl; FlushErrorFile(); return NULL; } NewSolution = new OptSolutionData; Status = glp_get_status(GLPKModel); if (Status == GLP_INFEAS || Status == GLP_NOFEAS || Status == GLP_UNDEF) { cout << "Model is infeasible" << endl; FErrorFile() << "Model is infeasible" << endl; FlushErrorFile(); NewSolution->Status = INFEASIBLE; return NewSolution; } else if (Status == GLP_FEAS || Status == GLP_UNBND) { cout << "Model is unbounded" << endl; FErrorFile() << "Model is unbounded" << endl; FlushErrorFile(); NewSolution->Status = UNBOUNDED; return NewSolution; } else if (Status == GLP_OPT) { NewSolution->Status = SUCCESS; } else { delete NewSolution; FErrorFile() << "Problem status unrecognized." << endl; FlushErrorFile(); return NULL; } NewSolution->Objective = glp_get_obj_val(GLPKModel); NewSolution->SolutionData.resize(NumVariables); for (int i=0; i < NumVariables; i++) { NewSolution->SolutionData[i] = glp_get_col_prim(GLPKModel, i+1); } } else { FErrorFile() << "Optimization problem type cannot be handled by GLPK solver." << endl; FlushErrorFile(); return NULL; } return NewSolution; }
double lpx_mip_obj_val(LPX *lp) { /* retrieve objective value (MIP solution) */ return glp_mip_obj_val(lp); }
void fence_insertert::solve() { #ifdef HAVE_GLPK ilpt ilp; instrumenter.message.statistics() << "po^+ edges considered:" << unique << " cycles:" << instrumenter.set_of_cycles.size() << messaget::eom; /* sets the variables and coefficients */ //nb of po+ considered * types of fences (_e) unsigned i=1; mip_set_var(ilp, i); /* sets the constraints */ mip_set_cst(ilp, i); instrumenter.message.debug() << "3: " << i << messaget::eom; assert(i-1==constraints_number); const unsigned const_constraints_number=constraints_number; const unsigned const_unique=unique; const unsigned mat_size=const_unique*fence_options*const_constraints_number; instrumenter.message.statistics() << "size of the system: " << mat_size << messaget::eom; instrumenter.message.statistics() << "# of constraints: " << const_constraints_number << messaget::eom; instrumenter.message.statistics() << "# of variables: " << const_unique*fence_options << messaget::eom; ilp.set_size(mat_size); #ifdef DEBUG print_vars(); #endif /* fills the constraints coeff */ /* tables read from 1 in glpk -- first row/column ignored */ mip_fill_matrix(ilp, i, const_constraints_number, const_unique); instrumenter.message.statistics() << "i: " << i << " mat_size: " << mat_size << messaget::eom; //assert(i-1==mat_size); #ifdef DEBUG for(i=1; i<=mat_size; ++i) instrumenter.message.debug() << i << "[" << ilp.imat[i] << "," << ilp.jmat[i] << "]=" << ilp.vmat[i] << messaget::eom; #endif /* solves MIP by branch-and-cut */ ilp.solve(); #ifdef DEBUG print_vars(); #endif /* checks optimality */ switch(glp_mip_status(ilp.lp)) { case GLP_OPT: instrumenter.message.result() << "Optimal solution found" << messaget::eom; break; case GLP_UNDEF: instrumenter.message.result() << "Solution undefined" << messaget::eom; assert(0); case GLP_FEAS: instrumenter.message.result() << "Solution feasible, yet not proven \ optimal, due to early termination" << messaget::eom; break; case GLP_NOFEAS: instrumenter.message.result() << "No feasible solution, the system is UNSAT" << messaget::eom; assert(0); } event_grapht& egraph=instrumenter.egraph; /* loads results (x_i) */ instrumenter.message.statistics() << "minimal cost: " << glp_mip_obj_val(ilp.lp) << messaget::eom; for(unsigned j=1; j<=const_unique*fence_options; ++j) { if(glp_mip_col_val(ilp.lp, j)>=1) { /* insert that fence */ assert(map_to_e.find(col_to_var(j))!=map_to_e.end()); const edget& delay = map_to_e.find(col_to_var(j))->second; instrumenter.message.statistics() << delay.first << " -> " << delay.second << " : " << to_string(col_to_fence(j)) << messaget::eom; instrumenter.message.statistics() << "(between " << egraph[delay.first].source_location << " and " << egraph[delay.second].source_location << messaget::eom; fenced_edges.insert(std::pair<edget,fence_typet>(delay, col_to_fence(j))); } } #else throw "Sorry, musketeer requires glpk; please recompile\ musketeer with glpk."; #endif }
void inline instrumentert::instrument_minimum_interference_inserter( const std::set<event_grapht::critical_cyclet>& set_of_cycles) { /* Idea: We solve this by a linear programming approach, using for instance glpk lib. Input: the edges to instrument E, the cycles C_j Pb: min sum_{e_i in E} d(e_i).x_i s.t. for all j, sum_{e_i in C_j} >= 1, where e_i is a pair to potentially instrument, x_i is a Boolean stating whether we instrument e_i, and d() is the cost of an instrumentation. Output: the x_i, saying which pairs to instrument For this instrumentation, we propose: d(poW*)=1 d(poRW)=d(rfe)=2 d(poRR)=3 This function can be refined with the actual times we get in experimenting the different pairs in a single IRIW. */ #ifdef HAVE_GLPK /* first, identify all the unsafe pairs */ std::set<event_grapht::critical_cyclet::delayt> edges; for(std::set<event_grapht::critical_cyclet>::iterator C_j=set_of_cycles.begin(); C_j!=set_of_cycles.end(); ++C_j) for(std::set<event_grapht::critical_cyclet::delayt>::const_iterator e_i= C_j->unsafe_pairs.begin(); e_i!=C_j->unsafe_pairs.end(); ++e_i) edges.insert(*e_i); glp_prob* lp; glp_iocp parm; glp_init_iocp(&parm); parm.msg_lev=GLP_MSG_OFF; parm.presolve=GLP_ON; lp=glp_create_prob(); glp_set_prob_name(lp, "instrumentation optimisation"); glp_set_obj_dir(lp, GLP_MIN); message.debug() << "edges: "<<edges.size()<<" cycles:"<<set_of_cycles.size() << messaget::eom; /* sets the variables and coefficients */ glp_add_cols(lp, edges.size()); unsigned i=0; for(std::set<event_grapht::critical_cyclet::delayt>::iterator e_i=edges.begin(); e_i!=edges.end(); ++e_i) { ++i; std::string name="e_"+i2string(i); glp_set_col_name(lp, i, name.c_str()); glp_set_col_bnds(lp, i, GLP_LO, 0.0, 0.0); glp_set_obj_coef(lp, i, cost(*e_i)); glp_set_col_kind(lp, i, GLP_BV); } /* sets the constraints (soundness): one per cycle */ glp_add_rows(lp, set_of_cycles.size()); i=0; for(std::set<event_grapht::critical_cyclet>::iterator C_j=set_of_cycles.begin(); C_j!=set_of_cycles.end(); ++C_j) { ++i; std::string name="C_"+i2string(i); glp_set_row_name(lp, i, name.c_str()); glp_set_row_bnds(lp, i, GLP_LO, 1.0, 0.0); /* >= 1*/ } const unsigned mat_size=set_of_cycles.size()*edges.size(); message.debug() << "size of the system: " << mat_size << messaget::eom; int* imat=(int*)malloc(sizeof(int)*(mat_size+1)); int* jmat=(int*)malloc(sizeof(int)*(mat_size+1)); double* vmat=(double*)malloc(sizeof(double)*(mat_size+1)); /* fills the constraints coeff */ /* tables read from 1 in glpk -- first row/column ignored */ unsigned col=1; unsigned row=1; i=1; for(std::set<event_grapht::critical_cyclet::delayt>::iterator e_i=edges.begin(); e_i!=edges.end(); ++e_i) { row=1; for(std::set<event_grapht::critical_cyclet>::iterator C_j=set_of_cycles.begin(); C_j!=set_of_cycles.end(); ++C_j) { imat[i]=row; jmat[i]=col; if(C_j->unsafe_pairs.find(*e_i)!=C_j->unsafe_pairs.end()) vmat[i]=1.0; else vmat[i]=0.0; ++i; ++row; } ++col; } #ifdef DEBUG for(i=1; i<=mat_size; ++i) message.statistics() <<i<<"["<<imat[i]<<","<<jmat[i]<<"]="<<vmat[i] << messaget::eom; #endif /* solves MIP by branch-and-cut */ glp_load_matrix(lp, mat_size, imat, jmat, vmat); glp_intopt(lp, &parm); /* loads results (x_i) */ message.statistics() << "minimal cost: " << glp_mip_obj_val(lp) << messaget::eom; i=0; for(std::set<event_grapht::critical_cyclet::delayt>::iterator e_i=edges.begin(); e_i!=edges.end(); ++e_i) { ++i; if(glp_mip_col_val(lp, i)>=1) { const abstract_eventt& first_ev=egraph[e_i->first]; var_to_instr.insert(first_ev.variable); id2loc.insert( std::pair<irep_idt,source_locationt>(first_ev.variable,first_ev.source_location)); if(!e_i->is_po) { const abstract_eventt& second_ev=egraph[e_i->second]; var_to_instr.insert(second_ev.variable); id2loc.insert( std::pair<irep_idt,source_locationt>(second_ev.variable,second_ev.source_location)); } } } glp_delete_prob(lp); free(imat); free(jmat); free(vmat); #else throw "Sorry, minimum interference option requires glpk; " "please recompile goto-instrument with glpk."; #endif }
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, int save_pb, char *save_filename, char *filetype, double *xmin, double *fmin, double *status, double *lambda, double *redcosts, double *time, double *mem) { int typx = 0; int method; clock_t t_start = clock(); // Obsolete //lib_set_fault_hook (NULL, glpk_fault_hook); //Redirect standard output if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL); else glp_term_hook (NULL, NULL); //-- Create an empty LP/MILP object glp_prob *lp = glp_create_prob (); //-- Set the sense of optimization if (sense == 1) glp_set_obj_dir (lp, GLP_MIN); else glp_set_obj_dir (lp, GLP_MAX); //-- Define the number of unknowns and their domains. glp_add_cols (lp, n); for (int i = 0; i < n; i++) { //-- Define type of the structural variables if (! freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]); else { if (! freeLB[i] && freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]); else { if (freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]); } } // -- Set the objective coefficient of the corresponding // -- structural variable. No constant term is assumed. glp_set_obj_coef(lp,i+1,c[i]); if (isMIP) glp_set_col_kind (lp, i+1, vartype[i]); } glp_add_rows (lp, m); for (int i = 0; i < m; i++) { /* If the i-th row has no lower bound (types F,U), the corrispondent parameter will be ignored. If the i-th row has no upper bound (types F,L), the corrispondent parameter will be ignored. If the i-th row is of S type, the i-th LB is used, but the i-th UB is ignored. */ switch (ctype[i]) { case 'F': typx = GLP_FR; break; // upper bound case 'U': typx = GLP_UP; break; // lower bound case 'L': typx = GLP_LO; break; // fixed constraint case 'S': typx = GLP_FX; break; // double-bounded variable case 'D': typx = GLP_DB; break; } glp_set_row_bnds (lp, i+1, typx, b[i], b[i]); } // Load constraint matrix A glp_load_matrix (lp, nz, rn, cn, a); // Save problem if (save_pb) { if (!strcmp(filetype,"cplex")){ if (lpx_write_cpxlp (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"fixedmps")){ if (lpx_write_mps (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"freemps")){ if (lpx_write_freemps (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } }else{// plain text if (lpx_print_prob (lp, save_filename) != 0) { mexErrMsgTxt("glpkcc: unable to write the problem"); longjmp (mark, -1); } } } } } //-- scale the problem data (if required) if (glpIntParam[1] && (! glpIntParam[16] || lpsolver != 1)) lpx_scale_prob (lp); //-- build advanced initial basis (if required) if (lpsolver == 1 && ! glpIntParam[16]) lpx_adv_basis (lp); glp_smcp sParam; glp_init_smcp(&sParam); //-- set control parameters if (lpsolver==1){ //remap of control parameters for simplex method sParam.msg_lev=glpIntParam[0]; // message level // simplex method: primal/dual if (glpIntParam[2]==0) sParam.meth=GLP_PRIMAL; else sParam.meth=GLP_DUALP; // pricing technique if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD; else sParam.pricing=GLP_PT_PSE; //sParam.r_test not available sParam.tol_bnd=glpRealParam[1]; // primal feasible tollerance sParam.tol_dj=glpRealParam[2]; // dual feasible tollerance sParam.tol_piv=glpRealParam[3]; // pivot tollerance sParam.obj_ll=glpRealParam[4]; // lower limit sParam.obj_ul=glpRealParam[5]; // upper limit // iteration limit if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX; else sParam.it_lim=glpIntParam[5]; // time limit if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX; else sParam.tm_lim=(int) glpRealParam[6]; sParam.out_frq=glpIntParam[7]; // output frequency sParam.out_dly=(int) glpRealParam[7]; // output delay // presolver if (glpIntParam[16]) sParam.presolve=GLP_ON; else sParam.presolve=GLP_OFF; }else{ for(int i = 0; i < NIntP; i++) lpx_set_int_parm (lp, IParam[i], glpIntParam[i]); for (int i = 0; i < NRealP; i++) lpx_set_real_parm (lp, RParam[i], glpRealParam[i]); } // Choose simplex method ('S') or interior point method ('T') to solve the problem if (lpsolver == 1) method = 'S'; else method = 'T'; int errnum; switch (method){ case 'S': { if (isMIP){ method = 'I'; errnum = lpx_intopt (lp); } else{ errnum = glp_simplex(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. } } break; case 'T': errnum = lpx_interior(lp); break; default: xassert (method != method); } /* errnum assumes the following results: errnum = 0 <=> No errors errnum = 1 <=> Iteration limit exceeded. errnum = 2 <=> Numerical problems with basis matrix. */ if (errnum == LPX_E_OK || errnum==100){ // Get status and object value if (isMIP) { *status = glp_mip_status (lp); *fmin = glp_mip_obj_val (lp); } else { if (lpsolver == 1) { *status = glp_get_status (lp); *fmin = glp_get_obj_val (lp); } else { *status = glp_ipt_status (lp); *fmin = glp_ipt_obj_val (lp); } } // Get optimal solution (if exists) if (isMIP) { for (int i = 0; i < n; i++) xmin[i] = glp_mip_col_val (lp, i+1); } else { /* Primal values */ for (int i = 0; i < n; i++) { if (lpsolver == 1) xmin[i] = glp_get_col_prim (lp, i+1); else xmin[i] = glp_ipt_col_prim (lp, i+1); } /* Dual values */ for (int i = 0; i < m; i++) { if (lpsolver == 1) lambda[i] = glp_get_row_dual (lp, i+1); else lambda[i] = glp_ipt_row_dual (lp, i+1); } /* Reduced costs */ for (int i = 0; i < glp_get_num_cols (lp); i++) { if (lpsolver == 1) redcosts[i] = glp_get_col_dual (lp, i+1); else redcosts[i] = glp_ipt_col_dual (lp, i+1); } } *time = (clock () - t_start) / CLOCKS_PER_SEC; glp_ulong tpeak; lib_mem_usage(NULL, NULL, NULL, &tpeak); *mem=(double)(4294967296.0 * tpeak.hi + tpeak.lo) / (1024); glp_delete_prob (lp); return 0; } glp_delete_prob (lp); *status = errnum; return errnum; }
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, int save_pb, char *save_filename, char *filetype, double *xmin, double *fmin, double *status, double *lambda, double *redcosts, double *time, double *mem) { int typx = 0; int method; clock_t t_start = clock(); //Redirect standard output if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL); else glp_term_hook (NULL, NULL); //-- Create an empty LP/MILP object LPX *lp = lpx_create_prob (); //-- Set the sense of optimization if (sense == 1) glp_set_obj_dir (lp, GLP_MIN); else glp_set_obj_dir (lp, GLP_MAX); //-- Define the number of unknowns and their domains. glp_add_cols (lp, n); for (int i = 0; i < n; i++) { //-- Define type of the structural variables if (! freeLB[i] && ! freeUB[i]) { if ( lb[i] == ub[i] ) glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]); } else { if (! freeLB[i] && freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]); else { if (freeLB[i] && ! freeUB[i]) glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]); else glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]); } } // -- Set the objective coefficient of the corresponding // -- structural variable. No constant term is assumed. glp_set_obj_coef(lp,i+1,c[i]); if (isMIP) glp_set_col_kind (lp, i+1, vartype[i]); } glp_add_rows (lp, m); for (int i = 0; i < m; i++) { /* If the i-th row has no lower bound (types F,U), the corrispondent parameter will be ignored. If the i-th row has no upper bound (types F,L), the corrispondent parameter will be ignored. If the i-th row is of S type, the i-th LB is used, but the i-th UB is ignored. */ switch (ctype[i]) { case 'F': typx = GLP_FR; break; // upper bound case 'U': typx = GLP_UP; break; // lower bound case 'L': typx = GLP_LO; break; // fixed constraint case 'S': typx = GLP_FX; break; // double-bounded variable case 'D': typx = GLP_DB; break; } if ( typx == GLP_DB && -b[i] < b[i]) { glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]); } else if(typx == GLP_DB && -b[i] == b[i]) { glp_set_row_bnds (lp, i+1, GLP_FX, b[i], b[i]); } else { // this should be glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]); glp_set_row_bnds (lp, i+1, typx, b[i], b[i]); } } // Load constraint matrix A glp_load_matrix (lp, nz, rn, cn, a); // Save problem if (save_pb) { if (!strcmp(filetype,"cplex")){ if (glp_write_lp (lp, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"fixedmps")){ if (glp_write_mps (lp, GLP_MPS_DECK, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{ if (!strcmp(filetype,"freemps")){ if (glp_write_mps (lp, GLP_MPS_FILE, NULL, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } }else{// plain text if (lpx_print_prob (lp, save_filename) != 0) { mexErrMsgTxt("glpk: unable to write the problem"); longjmp (mark, -1); } } } } } //-- scale the problem data (if required) if (! glpIntParam[16] || lpsolver != 1) { switch ( glpIntParam[1] ) { case ( 0 ): glp_scale_prob( lp, GLP_SF_SKIP ); break; case ( 1 ): glp_scale_prob( lp, GLP_SF_GM ); break; case ( 2 ): glp_scale_prob( lp, GLP_SF_EQ ); break; case ( 3 ): glp_scale_prob( lp, GLP_SF_AUTO ); break; case ( 4 ): glp_scale_prob( lp, GLP_SF_2N ); break; default : mexErrMsgTxt("glpk: unrecognized scaling option"); longjmp (mark, -1); } } else { /* do nothing? or unscale? glp_unscale_prob( lp ); */ } //-- build advanced initial basis (if required) if (lpsolver == 1 && ! glpIntParam[16]) glp_adv_basis (lp, 0); glp_smcp sParam; glp_init_smcp(&sParam); //-- set control parameters for simplex/exact method if (lpsolver == 1 || lpsolver == 3){ //remap of control parameters for simplex method sParam.msg_lev=glpIntParam[0]; // message level // simplex method: primal/dual switch ( glpIntParam[2] ) { case 0: sParam.meth=GLP_PRIMAL; break; case 1: sParam.meth=GLP_DUAL; break; case 2: sParam.meth=GLP_DUALP; break; default: mexErrMsgTxt("glpk: unrecognized primal/dual method"); longjmp (mark, -1); } // pricing technique if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD; else sParam.pricing=GLP_PT_PSE; // ratio test if (glpIntParam[20]==0) sParam.r_test = GLP_RT_STD; else sParam.r_test=GLP_RT_HAR; //tollerances sParam.tol_bnd=glpRealParam[1]; // primal feasible tollerance sParam.tol_dj=glpRealParam[2]; // dual feasible tollerance sParam.tol_piv=glpRealParam[3]; // pivot tollerance sParam.obj_ll=glpRealParam[4]; // lower limit sParam.obj_ul=glpRealParam[5]; // upper limit // iteration limit if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX; else sParam.it_lim=glpIntParam[5]; // time limit if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX; else sParam.tm_lim=(int) glpRealParam[6]; sParam.out_frq=glpIntParam[7]; // output frequency sParam.out_dly=(int) glpRealParam[7]; // output delay // presolver if (glpIntParam[16]) sParam.presolve=GLP_ON; else sParam.presolve=GLP_OFF; }else{ for(int i = 0; i < NIntP; i++) { // skip assinging ratio test or if ( i == 18 || i == 20) continue; lpx_set_int_parm (lp, IParam[i], glpIntParam[i]); } for (int i = 0; i < NRealP; i++) { lpx_set_real_parm (lp, RParam[i], glpRealParam[i]); } } //set MIP params if MIP.... glp_iocp iParam; glp_init_iocp(&iParam); if ( isMIP ){ method = 'I'; switch (glpIntParam[0]) { //message level case 0: iParam.msg_lev = GLP_MSG_OFF; break; case 1: iParam.msg_lev = GLP_MSG_ERR; break; case 2: iParam.msg_lev = GLP_MSG_ON; break; case 3: iParam.msg_lev = GLP_MSG_ALL; break; default: mexErrMsgTxt("glpk: msg_lev bad param"); } switch (glpIntParam[14]) { //branching param case 0: iParam.br_tech = GLP_BR_FFV; break; case 1: iParam.br_tech = GLP_BR_LFV; break; case 2: iParam.br_tech = GLP_BR_MFV; break; case 3: iParam.br_tech = GLP_BR_DTH; break; default: mexErrMsgTxt("glpk: branch bad param"); } switch (glpIntParam[15]) { //backtracking heuristic case 0: iParam.bt_tech = GLP_BT_DFS; break; case 1: iParam.bt_tech = GLP_BT_BFS; break; case 2: iParam.bt_tech = GLP_BT_BLB; break; case 3: iParam.bt_tech = GLP_BT_BPH; break; default: mexErrMsgTxt("glpk: backtrack bad param"); } if ( glpRealParam[8] > 0.0 && glpRealParam[8] < 1.0 ) iParam.tol_int = glpRealParam[8]; // absolute tolorence else mexErrMsgTxt("glpk: tolint must be between 0 and 1"); iParam.tol_obj = glpRealParam[9]; // relative tolarence iParam.mip_gap = glpRealParam[10]; // realative gap tolerance // set time limit for mip if ( glpRealParam[6] < 0.0 || glpRealParam[6] > 1e6 ) iParam.tm_lim = INT_MAX; else iParam.tm_lim = (int)(1000.0 * glpRealParam[6] ); // Choose Cutsets for mip // shut all cuts off, then start over.... iParam.gmi_cuts = GLP_OFF; iParam.mir_cuts = GLP_OFF; iParam.cov_cuts = GLP_OFF; iParam.clq_cuts = GLP_OFF; switch( glpIntParam[17] ) { case 0: break; case 1: iParam.gmi_cuts = GLP_ON; break; case 2: iParam.mir_cuts = GLP_ON; break; case 3: iParam.cov_cuts = GLP_ON; break; case 4: iParam.clq_cuts = GLP_ON; break; case 5: iParam.clq_cuts = GLP_ON; iParam.gmi_cuts = GLP_ON; iParam.mir_cuts = GLP_ON; iParam.cov_cuts = GLP_ON; iParam.clq_cuts = GLP_ON; break; default: mexErrMsgTxt("glpk: cutset bad param"); } switch( glpIntParam[18] ) { // pre-processing for mip case 0: iParam.pp_tech = GLP_PP_NONE; break; case 1: iParam.pp_tech = GLP_PP_ROOT; break; case 2: iParam.pp_tech = GLP_PP_ALL; break; default: mexErrMsgTxt("glpk: pprocess bad param"); } if (glpIntParam[16]) iParam.presolve=GLP_ON; else iParam.presolve=GLP_OFF; if (glpIntParam[19]) iParam.binarize = GLP_ON; else iParam.binarize = GLP_OFF; } else { /* Choose simplex method ('S') or interior point method ('T') or Exact method ('E') to solve the problem */ switch (lpsolver) { case 1: method = 'S'; break; case 2: method = 'T'; break; case 3: method = 'E'; break; default: mexErrMsgTxt("glpk: lpsolver != lpsolver"); longjmp (mark, -1); } } // now run the problem... int errnum = 0; switch (method) { case 'I': errnum = glp_intopt( lp, &iParam ); errnum += 200; //this is to avoid ambiguity in the return codes. break; case 'S': errnum = glp_simplex(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. break; case 'T': errnum = glp_interior(lp, NULL ); errnum += 300; //this is to avoid ambiguity in the return codes. break; case 'E': errnum = glp_exact(lp, &sParam); errnum += 100; //this is to avoid ambiguity in the return codes. break; default: /*xassert (method != method); */ mexErrMsgTxt("glpk: method != method"); longjmp (mark, -1); } if (errnum==100 || errnum==200 || errnum==300 || errnum==106 || errnum==107 || errnum==108 || errnum==109 || errnum==209 || errnum==214 || errnum==308) { // Get status and object value if (isMIP) { *status = glp_mip_status (lp); *fmin = glp_mip_obj_val (lp); } else { if (lpsolver == 1 || lpsolver == 3) { *status = glp_get_status (lp); *fmin = glp_get_obj_val (lp); } else { *status = glp_ipt_status (lp); *fmin = glp_ipt_obj_val (lp); } } // Get optimal solution (if exists) if (isMIP) { for (int i = 0; i < n; i++) xmin[i] = glp_mip_col_val (lp, i+1); } else { /* Primal values */ for (int i = 0; i < n; i++) { if (lpsolver == 1 || lpsolver == 3) xmin[i] = glp_get_col_prim (lp, i+1); else xmin[i] = glp_ipt_col_prim (lp, i+1); } /* Dual values */ for (int i = 0; i < m; i++) { if (lpsolver == 1 || lpsolver == 3) lambda[i] = glp_get_row_dual (lp, i+1); else lambda[i] = glp_ipt_row_dual (lp, i+1); } /* Reduced costs */ for (int i = 0; i < glp_get_num_cols (lp); i++) { if (lpsolver == 1 || lpsolver == 3) redcosts[i] = glp_get_col_dual (lp, i+1); else redcosts[i] = glp_ipt_col_dual (lp, i+1); } } *time = (clock () - t_start) / CLOCKS_PER_SEC; size_t tpeak; glp_mem_usage(NULL, NULL, NULL, &tpeak); *mem=((double) tpeak) / (1024); lpx_delete_prob(lp); return 0; } else { // printf("errnum is %d\n", errnum); } lpx_delete_prob(lp); /* this shouldn't be nessiary with glp_deleted_prob, but try it if we have weird behavior again... */ glp_free_env(); *status = errnum; return errnum; }
double c_glp_mip_obj_val (glp_prob *mip){ return glp_mip_obj_val(mip); }