예제 #1
0
파일: proxy1.c 프로젝트: emersonxsu/glpk
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.
     }
}
예제 #3
0
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;
}
예제 #4
0
파일: mklp.c 프로젝트: lcsirmaz/minitip
/** 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 */
}
예제 #5
0
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;
}
예제 #6
0
파일: ip.cpp 프로젝트: satoken/ractip
 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;
   }
 }
예제 #7
0
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);
//     }
}
예제 #9
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();
}
예제 #10
0
파일: lp.c 프로젝트: kleptog/pyglpk
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;
}
예제 #11
0
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;
}
예제 #12
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;
}
예제 #13
0
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;
}
예제 #14
0
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);
};
예제 #15
0
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;
}
예제 #16
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);
}
예제 #17
0
파일: ULS.c 프로젝트: Shakit/IP2015TP2
/* 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);
}
예제 #18
0
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;
}
예제 #19
0
파일: ULS.c 프로젝트: Shakit/IP2015TP2
/* 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;
}
예제 #20
0
파일: tp3.c 프로젝트: dennisman/L3
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;
}
예제 #21
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;
}
예제 #22
0
파일: itenssquare.c 프로젝트: andlt/MC658
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(&param);
   
   // Ativa o presolver
   param.presolve = GLP_ON;

   // Resolve o modelo
   int status = glp_intopt(model, &param);

   // 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;
}
예제 #23
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;
}
예제 #24
0
void ios_feas_pump(glp_tree *T)
{     glp_prob *P = T->mip;
      int n = P->n;
      glp_prob *lp = NULL;
      struct VAR *var = NULL;
      RNG *rand = NULL;
      GLPCOL *col;
      glp_smcp parm;
      int j, k, new_x, nfail, npass, nv, ret, stalling;
      double dist, tol;
      xassert(glp_get_status(P) == GLP_OPT);
      /* this heuristic is applied only once on the root level */
      if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done;
      /* determine number of binary variables */
      nv = 0;
      for (j = 1; j <= n; j++)
      {  col = P->col[j];
         /* if x[j] is continuous, skip it */
         if (col->kind == GLP_CV) continue;
         /* if x[j] is fixed, skip it */
         if (col->type == GLP_FX) continue;
         /* x[j] is non-fixed integer */
         xassert(col->kind == GLP_IV);
         if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0)
         {  /* x[j] is binary */
            nv++;
         }
         else
         {  /* x[j] is general integer */
            if (T->parm->msg_lev >= GLP_MSG_ALL)
               xprintf("FPUMP heuristic cannot be applied due to genera"
                  "l integer variables\n");
            goto done;
         }
      }
      /* there must be at least one binary variable */
      if (nv == 0) goto done;
      if (T->parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Applying FPUMP heuristic...\n");
      /* build the list of binary variables */
      var = xcalloc(1+nv, sizeof(struct VAR));
      k = 0;
      for (j = 1; j <= n; j++)
      {  col = P->col[j];
         if (col->kind == GLP_IV && col->type == GLP_DB)
            var[++k].j = j;
      }
      xassert(k == nv);
      /* create working problem object */
      lp = glp_create_prob();
more: /* copy the original problem object to keep it intact */
      glp_copy_prob(lp, P, GLP_OFF);
      /* we are interested to find an integer feasible solution, which
         is better than the best known one */
      if (P->mip_stat == GLP_FEAS)
      {  int *ind;
         double *val, bnd;
         /* add a row and make it identical to the objective row */
         glp_add_rows(lp, 1);
         ind = xcalloc(1+n, sizeof(int));
         val = xcalloc(1+n, sizeof(double));
         for (j = 1; j <= n; j++)
         {  ind[j] = j;
            val[j] = P->col[j]->coef;
         }
         glp_set_mat_row(lp, lp->m, n, ind, val);
         xfree(ind);
         xfree(val);
         /* introduce upper (minimization) or lower (maximization)
            bound to the original objective function; note that this
            additional constraint is not violated at the optimal point
            to LP relaxation */
#if 0 /* modified by xypron <*****@*****.**> */
         if (P->dir == GLP_MIN)
         {  bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj));
            if (bnd < P->obj_val) bnd = P->obj_val;
            glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0);
         }
         else if (P->dir == GLP_MAX)
         {  bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj));
            if (bnd > P->obj_val) bnd = P->obj_val;
            glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0);
         }
         else
            xassert(P != P);
#else
         bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj;
         /* xprintf("bnd = %f\n", bnd); */
         if (P->dir == GLP_MIN)
            glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0);
         else if (P->dir == GLP_MAX)
            glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0);
         else
            xassert(P != P);
#endif
      }
      /* reset pass count */
      npass = 0;
      /* invalidate the rounded point */
      for (k = 1; k <= nv; k++)
         var[k].x = -1;
pass: /* next pass starts here */
      npass++;
      if (T->parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Pass %d\n", npass);
      /* initialize minimal distance between the basic point and the
         rounded one obtained during this pass */
      dist = DBL_MAX;
      /* reset failure count (the number of succeeded iterations failed
         to improve the distance) */
      nfail = 0;
      /* if it is not the first pass, perturb the last rounded point
         rather than construct it from the basic solution */
      if (npass > 1)
      {  double rho, temp;
         if (rand == NULL)
            rand = rng_create_rand();
         for (k = 1; k <= nv; k++)
         {  j = var[k].j;
            col = lp->col[j];
            rho = rng_uniform(rand, -0.3, 0.7);
            if (rho < 0.0) rho = 0.0;
            temp = fabs((double)var[k].x - col->prim);
            if (temp + rho > 0.5) var[k].x = 1 - var[k].x;
         }
         goto skip;
      }
loop: /* innermost loop begins here */
      /* round basic solution (which is assumed primal feasible) */
      stalling = 1;
      for (k = 1; k <= nv; k++)
      {  col = lp->col[var[k].j];
         if (col->prim < 0.5)
         {  /* rounded value is 0 */
            new_x = 0;
         }
         else
         {  /* rounded value is 1 */
            new_x = 1;
         }
         if (var[k].x != new_x)
         {  stalling = 0;
            var[k].x = new_x;
         }
      }
      /* if the rounded point has not changed (stalling), choose and
         flip some its entries heuristically */
      if (stalling)
      {  /* compute d[j] = |x[j] - round(x[j])| */
         for (k = 1; k <= nv; k++)
         {  col = lp->col[var[k].j];
            var[k].d = fabs(col->prim - (double)var[k].x);
         }
         /* sort the list of binary variables by descending d[j] */
         qsort(&var[1], nv, sizeof(struct VAR), fcmp);
         /* choose and flip some rounded components */
         for (k = 1; k <= nv; k++)
         {  if (k >= 5 && var[k].d < 0.35 || k >= 10) break;
            var[k].x = 1 - var[k].x;
         }
      }
skip: /* check if the time limit has been exhausted */
      if (T->parm->tm_lim < INT_MAX &&
         (double)(T->parm->tm_lim - 1) <=
         1000.0 * xdifftime(xtime(), T->tm_beg)) goto done;
      /* build the objective, which is the distance between the current
         (basic) point and the rounded one */
      lp->dir = GLP_MIN;
      lp->c0 = 0.0;
      for (j = 1; j <= n; j++)
         lp->col[j]->coef = 0.0;
      for (k = 1; k <= nv; k++)
      {  j = var[k].j;
         if (var[k].x == 0)
            lp->col[j]->coef = +1.0;
         else
         {  lp->col[j]->coef = -1.0;
            lp->c0 += 1.0;
         }
      }
      /* minimize the distance with the simplex method */
      glp_init_smcp(&parm);
      if (T->parm->msg_lev <= GLP_MSG_ERR)
         parm.msg_lev = T->parm->msg_lev;
      else if (T->parm->msg_lev <= GLP_MSG_ALL)
      {  parm.msg_lev = GLP_MSG_ON;
         parm.out_dly = 10000;
      }
      ret = glp_simplex(lp, &parm);
      if (ret != 0)
      {  if (T->parm->msg_lev >= GLP_MSG_ERR)
            xprintf("Warning: glp_simplex returned %d\n", ret);
         goto done;
      }
      ret = glp_get_status(lp);
      if (ret != GLP_OPT)
      {  if (T->parm->msg_lev >= GLP_MSG_ERR)
            xprintf("Warning: glp_get_status returned %d\n", ret);
         goto done;
      }
      if (T->parm->msg_lev >= GLP_MSG_DBG)
         xprintf("delta = %g\n", lp->obj_val);
      /* check if the basic solution is integer feasible; note that it
         may be so even if the minimial distance is positive */
      tol = 0.3 * T->parm->tol_int;
      for (k = 1; k <= nv; k++)
      {  col = lp->col[var[k].j];
         if (tol < col->prim && col->prim < 1.0 - tol) break;
      }
      if (k > nv)
      {  /* okay; the basic solution seems to be integer feasible */
         double *x = xcalloc(1+n, sizeof(double));
         for (j = 1; j <= n; j++)
         {  x[j] = lp->col[j]->prim;
            if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5);
         }
#if 1 /* modified by xypron <*****@*****.**> */
         /* reset direction and right-hand side of objective */
         lp->c0  = P->c0;
         lp->dir = P->dir;
         /* fix integer variables */
         for (k = 1; k <= nv; k++)
#if 0 /* 18/VI-2013; fixed by mao
       * this bug causes numerical instability, because column statuses
       * are not changed appropriately */
         {  lp->col[var[k].j]->lb   = x[var[k].j];
            lp->col[var[k].j]->ub   = x[var[k].j];
            lp->col[var[k].j]->type = GLP_FX;
         }
#else
            glp_set_col_bnds(lp, var[k].j, GLP_FX, x[var[k].j], 0.);
#endif
         /* copy original objective function */
         for (j = 1; j <= n; j++)
            lp->col[j]->coef = P->col[j]->coef;
         /* solve original LP and copy result */
         ret = glp_simplex(lp, &parm);
         if (ret != 0)
         {  if (T->parm->msg_lev >= GLP_MSG_ERR)
               xprintf("Warning: glp_simplex returned %d\n", ret);
            goto done;
         }
         ret = glp_get_status(lp);
         if (ret != GLP_OPT)
         {  if (T->parm->msg_lev >= GLP_MSG_ERR)
               xprintf("Warning: glp_get_status returned %d\n", ret);
            goto done;
         }
         for (j = 1; j <= n; j++)
            if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim;
#endif
         ret = glp_ios_heur_sol(T, x);
         xfree(x);
         if (ret == 0)
         {  /* the integer solution is accepted */
            if (ios_is_hopeful(T, T->curr->bound))
            {  /* it is reasonable to apply the heuristic once again */
               goto more;
            }
            else
            {  /* the best known integer feasible solution just found
                  is close to optimal solution to LP relaxation */
               goto done;
            }
         }
      }
예제 #25
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;

}
/**
 * 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, &quota_out_str))
    {
      if (0 == strcmp(quota_out_str, BIG_M_STRING) ||
          (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &quota_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, &quota_in_str))
    {
      if (0 == strcmp(quota_in_str, BIG_M_STRING) ||
          (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &quota_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;
}
예제 #28
0
파일: glpapi20.c 프로젝트: emersonxsu/glpk
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;
}
예제 #29
0
파일: ppl_lpsol.c 프로젝트: hnxiao/ppl
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);
}
예제 #30
0
파일: glpk.c 프로젝트: AllThing/hmatrix
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;
}