Example #1
0
/** creates a new solution for the original problem by copying the solution of the subproblem */
static
SCIP_RETCODE createNewSol(
   SCIP*                 scip,               /**< original SCIP data structure */
   SCIP_HEUR*            heur,               /**< the current heuristic */
   SCIP_SOL*             sol,                /**< solution of the subproblem */
   SCIP_Bool*            success             /**< used to store whether new solution was found or not */
   )
{
   SCIP_VAR** vars;                          /* the original problem's variables */
   int        nvars;                         /* the original problem's number of variables */
   SCIP_Real* solvals;                       /* solution values of the subproblem */
   SCIP_SOL*  newsol;                        /* solution to be created for the original problem */

   assert(scip != NULL);

   /* get variables' data */
   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );

   SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );

   /* copy the solution */
   SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, solvals) );

   /* create new solution for the original problem */
   SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
   SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, solvals) );

   /* try to add new solution to scip and free it immediately */
   SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) );

   SCIPfreeBufferArray(scip, &solvals);

   return SCIP_OKAY;
}
Example #2
0
/** initialization method of primal heuristic (called after problem was transformed) */
static
SCIP_DECL_HEURINIT(heurInitZirounding)
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;

   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);

   heurdata = SCIPheurGetData(heur);
   assert(heurdata != NULL);

   /* create working solution */
   SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );

   return SCIP_OKAY;
}
Example #3
0
/** initialization method of primal heuristic (called after problem was transformed) */
static
SCIP_DECL_HEURINIT(heurInitRandrounding) /*lint --e{715}*/
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;

   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
   heurdata = SCIPheurGetData(heur);
   assert(heurdata != NULL);

   /* create heuristic data */
   SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
   heurdata->lastlp = -1;
   heurdata->randseed = DEFAULT_RANDSEED;

   return SCIP_OKAY;
}
/** initialization method of primal heuristic (called after problem was transformed) */
static
SCIP_DECL_HEURINIT(heurInitSimplerounding) /*lint --e{715}*/
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;

   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
   assert(SCIPheurGetData(heur) == NULL);

   /* create heuristic data */
   SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
   SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
   heurdata->lastlp = -1;
   heurdata->nroundablevars = -1;
   SCIPheurSetData(heur, heurdata);

   return SCIP_OKAY;
}
/** generate point for close cut separation
 *
 *  The constructed point is the convex combination of the point stored in set->closesol and the
 *  current LP solution. The convexity parameter is set->sepa_closecombvalue. If this parameter is
 *  0, the point coincides with the LP solution.
 */
static
SCIP_RETCODE generateCloseCutPoint(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_SEPADATA*        sepadata,           /**< separator data */
   SCIP_SOL**            point               /**< point to be generated (or NULL if unsuccessful) */
   )
{
   SCIP_VAR** vars;
   SCIP_VAR* var;
   SCIP_Real val;
   SCIP_Real alpha;
   SCIP_Real onealpha;
   int nvars;
   int i;

   assert( scip != NULL );
   assert( point != NULL );

   *point = NULL;
   if ( sepadata->sepasol == NULL )
      return SCIP_OKAY;

   alpha = sepadata->sepacombvalue;
   if ( alpha < 0.001 )
      return SCIP_OKAY;
   onealpha = 1.0 - alpha;

   /* create solution */
   SCIP_CALL( SCIPcreateSol(scip, point, NULL) );

   /* generate convex combination */
   vars = SCIPgetVars(scip);
   nvars = SCIPgetNVars(scip);
   for (i = 0; i < nvars; ++i)
   {
      var = vars[i];
      val = alpha * SCIPgetSolVal(scip, sepadata->sepasol, var) + onealpha * SCIPvarGetLPSol(var);

      if ( ! SCIPisZero(scip, val) )
      {
         SCIP_CALL( SCIPsetSolVal(scip, *point, var, val) );
      }
   }

   return SCIP_OKAY;
}
/** creates a new solution for the original problem by copying the solution of the subproblem */
static
SCIP_RETCODE createNewSol(
   SCIP*                 scip,               /**< original SCIP data structure */
   SCIP*                 subscip,            /**< SCIP structure of the subproblem */
   SCIP_VAR**            subvars,            /**< the variables of the subproblem */
   SCIP_HEUR*            heur,               /**< crossover heuristic structure */
   SCIP_SOL*             subsol,             /**< solution of the subproblem */
   int*                  solindex,           /**< index of the solution */
   SCIP_Bool*            success             /**< used to store whether new solution was found or not */
   )
{
   SCIP_VAR** vars;                          /* the original problem's variables                */
   int        nvars;
   SCIP_SOL*  newsol;                        /* solution to be created for the original problem */
   SCIP_Real* subsolvals;                    /* solution values of the subproblem               */

   assert(scip != NULL);
   assert(subscip != NULL);
   assert(subvars != NULL);
   assert(subsol != NULL);

   /* get variables' data */
   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
   /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
    * since constraint copying may have required the copy of variables that are fixed in the main SCIP
    */
   assert(nvars <= SCIPgetNOrigVars(subscip));

   SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );

   /* copy the solution */
   SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) );

   /* create new solution for the original problem */
   SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
   SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
   *solindex = SCIPsolGetIndex(newsol);

   /* try to add new solution to scip and free it immediately */
   SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) );

   SCIPfreeBufferArray(scip, &subsolvals);

   return SCIP_OKAY;
}
Example #7
0
/** creates a new solution for the original problem by copying the solution of the subproblem */
static
SCIP_RETCODE createNewSol(
   SCIP*                 scip,               /**< SCIP data structure  of the original problem      */
   SCIP*                 subscip,            /**< SCIP data structure  of the subproblem            */
   SCIP_VAR**            subvars,            /**< the variables of the subproblem                     */
   SCIP_HEUR*            heur,               /**< the Localbranching heuristic                      */
   SCIP_SOL*             subsol,             /**< solution of the subproblem                          */
   SCIP_Bool*            success             /**< pointer to store, whether new solution was found  */
   )
{
   SCIP_VAR** vars;
   int nvars;
   SCIP_SOL* newsol;
   SCIP_Real* subsolvals;

   assert( scip != NULL );
   assert( subscip != NULL );
   assert( subvars != NULL );
   assert( subsol != NULL );

   /* copy the solution */
   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
   /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
    * since constraint copying may have required the copy of variables that are fixed in the main SCIP
    */
   assert(nvars <= SCIPgetNOrigVars(subscip));

   SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );

   /* copy the solution */
   SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) );

   /* create new solution for the original problem */
   SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
   SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );

   SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) );

   SCIPfreeBufferArray(scip, &subsolvals);

   return SCIP_OKAY;
}
Example #8
0
/** initialization method of primal heuristic (called after problem was transformed) */
static
SCIP_DECL_HEURINIT(heurInitLinesearchdiving)
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;

   assert(heur != NULL);

   /* get heuristic data */
   heurdata = SCIPheurGetData(heur);
   assert(heurdata != NULL);

   /* create working solution */
   SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );

   /* initialize data */
   heurdata->nlpiterations = 0;
   heurdata->nsuccess = 0;

   return SCIP_OKAY;
}
Example #9
0
/** initialization method of primal heuristic (called after problem was transformed) */
static
SCIP_DECL_HEURINIT(heurInitObjpscostdiving) /*lint --e{715}*/
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;

   assert(heur != NULL);
   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);

   /* get heuristic data */
   heurdata = SCIPheurGetData(heur);
   assert(heurdata != NULL);

   /* create working solution */
   SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );

   /* initialize data */
   heurdata->nlpiterations = 0;
   heurdata->nsuccess = 0;

   return SCIP_OKAY;
}
/** execution method of primal heuristic */
static
SCIP_DECL_HEUREXEC(heurExecOctane)
{  /*lint --e{715}*/
   SCIP_HEURDATA* heurdata;
   SCIP_SOL* sol;
   SCIP_SOL** first_sols;     /* stores the first ffirst sols in order to check for common violation of a row */

   SCIP_VAR** vars;           /* the variables of the problem */
   SCIP_VAR** fracvars;       /* variables, that are fractional in current LP solution */
   SCIP_VAR** subspacevars;   /* the variables on which the search is performed. Either coinciding with vars or with the
                               * space of all fractional variables of the current LP solution */

   SCIP_Real p;               /* n/2 - <delta,x> ( for some facet delta ) */
   SCIP_Real q;               /* <delta,a> */

   SCIP_Real* rayorigin;      /* origin of the ray, vector x in paper */
   SCIP_Real* raydirection;   /* direction of the ray, vector a in paper */
   SCIP_Real* negquotient;    /* negated quotient of rayorigin and raydirection, vector v in paper */
   SCIP_Real* lambda;         /* stores the distance of the facets (s.b.) to the origin of the ray */

   SCIP_Bool usefracspace;    /* determines whether the search concentrates on fractional variables and fixes integer ones */
   SCIP_Bool cons_viol;       /* used for checking whether a linear constraint is violated by one of the possible solutions */
   SCIP_Bool success;
   SCIP_Bool* sign;           /* signature of the direction of the ray */
   SCIP_Bool** facets;        /* list of extended facets */

   int nvars;            /* number of variables  */
   int nbinvars;         /* number of 0-1-variables */
   int nfracvars;        /* number of fractional variables in current LP solution */
   int nsubspacevars;    /* dimension of the subspace on which the search is performed */
   int nfacets;          /* number of facets hidden by the ray that where already found */
   int i;                /* counter */
   int j;                /* counter */
   int f_max;            /* {0,1}-points to be checked */
   int f_first;          /* {0,1}-points to be generated at first in order to check whether a restart is necessary */
   int r;                /* counter */
   int firstrule;

   int* perm;            /* stores the way in which the coordinates were permuted */
   int* fracspace;       /* maps the variables of the subspace to the original variables */

   assert(heur != NULL);
   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
   assert(scip != NULL);
   assert(result != NULL);
   assert(SCIPhasCurrentNodeLP(scip));

   *result = SCIP_DELAYED;

   /* only call heuristic, if an optimal LP solution is at hand */
   if( SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
      return SCIP_OKAY;

   *result = SCIP_DIDNOTRUN;

   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );

   /* OCTANE is for use in 0-1 programs only */
   if( nvars != nbinvars )
      return SCIP_OKAY;

   /* get heuristic's data */
   heurdata = SCIPheurGetData(heur);
   assert( heurdata != NULL );

   /* don't call heuristic, if it was not successful enough in the past */
   /*lint --e{647}*/
   if( SCIPgetNNodes(scip) % (SCIPheurGetNCalls(heur) / (100 * SCIPheurGetNBestSolsFound(heur) + 10*heurdata->nsuccess + 1) + 1) != 0 )
      return SCIP_OKAY;

   SCIP_CALL( SCIPgetLPBranchCands(scip, &fracvars, NULL, NULL, &nfracvars, NULL) );

   /* don't use integral starting points */
   if( nfracvars == 0 )
      return SCIP_OKAY;

   /* get working pointers from heurdata */
   sol = heurdata->sol;
   assert( sol != NULL );
   f_max = heurdata->f_max;
   f_first = heurdata->f_first;
   usefracspace = heurdata->usefracspace;

   SCIP_CALL( SCIPallocBufferArray(scip, &fracspace, nvars) );

   /* determine the space one which OCTANE should work either as the whole space or as the space of fractional variables */
   if( usefracspace )
   {
      nsubspacevars = nfracvars;
      SCIP_CALL( SCIPallocBufferArray(scip, &subspacevars, nsubspacevars) );
      BMScopyMemoryArray(subspacevars, fracvars, nsubspacevars);
      for( i = nvars - 1; i >= 0; --i )
         fracspace[i] = -1;
      for( i = nsubspacevars - 1; i >= 0; --i )
         fracspace[SCIPvarGetProbindex(subspacevars[i])] = i;
   }
   else
   {
      int currentindex;

      nsubspacevars = nvars;
      SCIP_CALL( SCIPallocBufferArray(scip, &subspacevars, nsubspacevars) );

      /* only copy the variables which are in the current LP */
      currentindex = 0;
      for( i = 0; i < nvars; ++i )
      {
         if( SCIPcolGetLPPos(SCIPvarGetCol(vars[i])) >= 0 )
         {
            subspacevars[currentindex] = vars[i];
            fracspace[i] = currentindex;
            ++currentindex;

         }
         else
         {
            fracspace[i] = -1;
            --nsubspacevars;
         }
      }
   }

   /* nothing to do for empty search space */
   if( nsubspacevars == 0 )
      return SCIP_OKAY;

   assert(0 < nsubspacevars && nsubspacevars <= nvars);

   for( i = 0; i < nsubspacevars; i++)
      assert(fracspace[SCIPvarGetProbindex(subspacevars[i])] == i);

   /* at most 2^(n-1) facets can be hit */
   if( nsubspacevars < 30 )
   {
      /*lint --e{701}*/
      assert(f_max > 0);
      f_max = MIN(f_max, 1 << (nsubspacevars - 1) );
   }

   f_first = MIN(f_first, f_max);

   /* memory allocation */
   SCIP_CALL( SCIPallocBufferArray(scip, &rayorigin, nsubspacevars) );
   SCIP_CALL( SCIPallocBufferArray(scip, &raydirection, nsubspacevars) );
   SCIP_CALL( SCIPallocBufferArray(scip, &negquotient, nsubspacevars) );
   SCIP_CALL( SCIPallocBufferArray(scip, &sign, nsubspacevars) );
   SCIP_CALL( SCIPallocBufferArray(scip, &perm, nsubspacevars) );
   SCIP_CALL( SCIPallocBufferArray(scip, &lambda, f_max + 1) );
   SCIP_CALL( SCIPallocBufferArray(scip, &facets, f_max + 1) );
   for( i = f_max; i >= 0; --i )
   {
      /*lint --e{866}*/
      SCIP_CALL( SCIPallocBufferArray(scip, &facets[i], nsubspacevars) );
   }
   SCIP_CALL( SCIPallocBufferArray(scip, &first_sols, f_first) );

   *result = SCIP_DIDNOTFIND;

   /* starting OCTANE */
   SCIPdebugMessage("run Octane heuristic on %s variables, which are %d vars, generate at most %d facets, using rule number %d\n",
      usefracspace ? "fractional" : "all", nsubspacevars, f_max, (heurdata->lastrule+1)%5);

   /* generate starting point in original coordinates */
   SCIP_CALL( generateStartingPoint(scip, rayorigin, subspacevars, nsubspacevars) );
   for( i = nsubspacevars - 1; i >= 0; --i )
      rayorigin[i] -= 0.5;

   firstrule = heurdata->lastrule;
   ++firstrule;
   for( r = firstrule; r <= firstrule + 10 && !SCIPisStopped(scip); r++ )
   {
      SCIP_ROW** rows;
      int nrows;

      /* generate shooting ray in original coordinates by certain rules */
      switch(r % 5)
      {
      case 1:
         if( heurdata->useavgnbray )
         {
            SCIP_CALL( generateAverageNBRay(scip, raydirection, fracspace, subspacevars, nsubspacevars) );
         }
         break;
      case 2:
         if( heurdata->useobjray )
         {
            SCIP_CALL( generateObjectiveRay(scip, raydirection, subspacevars, nsubspacevars) );
         }
         break;
      case 3:
         if( heurdata->usediffray )
         {
            SCIP_CALL( generateDifferenceRay(scip, raydirection, subspacevars, nsubspacevars) );
         }
         break;
      case 4:
         if( heurdata->useavgwgtray && SCIPisLPSolBasic(scip) )
         {
            SCIP_CALL( generateAverageRay(scip, raydirection, subspacevars, nsubspacevars, TRUE) );
         }
         break;
      case 0:
         if( heurdata->useavgray && SCIPisLPSolBasic(scip) )
         {
            SCIP_CALL( generateAverageRay(scip, raydirection, subspacevars, nsubspacevars, FALSE) );
         }
         break;
      default:
         SCIPerrorMessage("invalid ray rule identifier\n");
         SCIPABORT();
      }

      /* there must be a feasible direction for the shooting ray */
      if( isZero(scip, raydirection, nsubspacevars) )
         continue;

      /* transform coordinates such that raydirection >= 0 */
      flipCoords(rayorigin, raydirection, sign, nsubspacevars);

      for( i = f_max - 1; i >= 0; --i)
         lambda[i] = SCIPinfinity(scip);

      /* calculate negquotient, initialize perm, facets[0], p, and q */
      p = 0.5 * nsubspacevars;
      q = 0.0;
      for( i = nsubspacevars - 1; i >= 0; --i )
      {
         /* calculate negquotient, the ratio of rayorigin and raydirection, paying special attention to the case raydirection[i] == 0 */
         if( SCIPisFeasZero(scip, raydirection[i]) )
         {
            if( rayorigin[i] < 0 )
               negquotient[i] = SCIPinfinity(scip);
            else
               negquotient[i] = -SCIPinfinity(scip);
         }
         else
            negquotient[i] = - (rayorigin[i] / raydirection[i]);

         perm[i] = i;

         /* initialization of facets[0] to the all-one facet with p and q its characteristic values */
         facets[0][i] = TRUE;
         p -= rayorigin[i];
         q += raydirection[i];
      }

      assert(SCIPisPositive(scip, q));

      /* resort the coordinates in nonincreasing order of negquotient */
      SCIPsortDownRealRealRealBoolPtr( negquotient, raydirection, rayorigin, sign, (void**) subspacevars, nsubspacevars);

#ifndef NDEBUG
      for( i = 0; i < nsubspacevars; i++ )
         assert( raydirection[i] >= 0 );
      for( i = 1; i < nsubspacevars; i++ )
         assert( negquotient[i - 1] >= negquotient[i] );
#endif
      /* finished initialization */

      /* find the first facet of the octahedron hit by a ray shot from rayorigin into direction raydirection */
      for( i = 0; i < nsubspacevars && negquotient[i] * q > p; ++i )
      {
         facets[0][i] = FALSE;
         p += 2 * rayorigin[i];
         q -= 2 * raydirection[i];
         assert(SCIPisPositive(scip, p));
         assert(SCIPisPositive(scip, q));
      }

      /* avoid dividing by values close to 0.0 */
      if( !SCIPisFeasPositive(scip, q) )
         continue;

      /* assert necessary for flexelint */
      assert(q > 0);
      lambda[0] = p / q;

      nfacets = 1;

      /* find the first facets hit by the ray */
      for( i = 0; i < nfacets && i < f_first; ++i)
         generateNeighborFacets(scip, facets, lambda, rayorigin, raydirection, negquotient, nsubspacevars, f_max, i, &nfacets);

      /* construct the first ffirst possible solutions */
      for( i = 0; i < nfacets && i < f_first; ++i )
      {
         SCIP_CALL( SCIPcreateSol(scip, &first_sols[i], heur) );
         SCIP_CALL( getSolFromFacet(scip, facets[i], first_sols[i], sign, subspacevars, nsubspacevars) );
         assert( first_sols[i] != NULL );
      }

      /* try, whether there is a row violated by all of the first ffirst solutions */
      cons_viol = FALSE;
      SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
      for( i = nrows - 1; i >= 0; --i )
      {
         if( !SCIProwIsLocal(rows[i]) )
         {
            SCIP_COL** cols;
            SCIP_Real constant;
            SCIP_Real lhs;
            SCIP_Real rhs;
            SCIP_Real rowval;
            SCIP_Real* coeffs;
            int nnonzerovars;
            int k;

            /* get the row's data */
            constant = SCIProwGetConstant(rows[i]);
            lhs = SCIProwGetLhs(rows[i]);
            rhs = SCIProwGetRhs(rows[i]);
            coeffs = SCIProwGetVals(rows[i]);
            nnonzerovars = SCIProwGetNNonz(rows[i]);
            cols = SCIProwGetCols(rows[i]);
            rowval = constant;

            for( j = nnonzerovars - 1; j >= 0; --j )
               rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[0], SCIPcolGetVar(cols[j]));

            /* if the row's lhs is violated by the first sol, test, whether it is violated by the next ones, too */
            if( lhs > rowval )
            {
               cons_viol = TRUE;
               for( k = MIN(f_first, nfacets) - 1; k > 0; --k )
               {
                  rowval = constant;
                  for( j = nnonzerovars - 1; j >= 0; --j )
                     rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[k], SCIPcolGetVar(cols[j]));
                  if( lhs <= rowval )
                  {
                     cons_viol = FALSE;
                     break;
                  }
               }
            }
            /* dito for the right hand side */
            else if( rhs < rowval )
            {
               cons_viol = TRUE;
               for( k = MIN(f_first, nfacets) - 1; k > 0; --k )
               {
                  rowval = constant;
                  for( j = nnonzerovars - 1; j >= 0; --j )
                     rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[k], SCIPcolGetVar(cols[j]));
                  if( rhs >= rowval )
                  {
                     cons_viol = FALSE;
                     break;
                  }
               }
            }
            /* break as soon as one row is violated by all of the ffirst solutions */
            if( cons_viol )
               break;
         }
      }


      if( !cons_viol )
      {
         /* if there was no row violated by all solutions, try whether one or more of them are feasible */
         for( i = MIN(f_first, nfacets) - 1; i >= 0; --i )
         {
            assert(first_sols[i] != NULL);
            SCIP_CALL( SCIPtrySol(scip, first_sols[i], FALSE, TRUE, FALSE, TRUE, &success) );
            if( success )
               *result = SCIP_FOUNDSOL;
         }
         /* search for further facets and construct and try solutions out of facets fixed as closest ones */
         for( i = f_first; i < f_max; ++i)
         {
            if( i >= nfacets )
               break;
            generateNeighborFacets(scip, facets, lambda, rayorigin, raydirection, negquotient, nsubspacevars, f_max, i, &nfacets);
            SCIP_CALL( getSolFromFacet(scip, facets[i], sol, sign, subspacevars, nsubspacevars) );
            SCIP_CALL( SCIPtrySol(scip, sol, FALSE, TRUE, FALSE, TRUE, &success) );
            if( success )
               *result = SCIP_FOUNDSOL;
         }
      }

      /* finished OCTANE */
      for( i = MIN(f_first, nfacets) - 1; i >= 0; --i )
      {
         SCIP_CALL( SCIPfreeSol(scip, &first_sols[i]) );
      }
   }
   heurdata->lastrule = r;

   if( *result == SCIP_FOUNDSOL )
      ++(heurdata->nsuccess);

   /* free temporary memory */
   SCIPfreeBufferArray(scip, &first_sols);
   for( i = f_max; i >= 0; --i )
      SCIPfreeBufferArray(scip, &facets[i]);
   SCIPfreeBufferArray(scip, &facets);
   SCIPfreeBufferArray(scip, &lambda);
   SCIPfreeBufferArray(scip, &perm);
   SCIPfreeBufferArray(scip, &sign);
   SCIPfreeBufferArray(scip, &negquotient);
   SCIPfreeBufferArray(scip, &raydirection);
   SCIPfreeBufferArray(scip, &rayorigin);
   SCIPfreeBufferArray(scip, &subspacevars);
   SCIPfreeBufferArray(scip, &fracspace);

   return SCIP_OKAY;
}
Example #11
0
/** transforms given solution of the master problem into solution of the original problem
 *  @todo think about types of epsilons used in this method
 */
SCIP_RETCODE GCGrelaxTransformMastersolToOrigsol(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_SOL*             mastersol,          /**< solution of the master problem, or NULL for current LP solution */
   SCIP_SOL**            origsol             /**< pointer to store the new created original problem's solution */
   )
{
   SCIP* masterprob;
   int npricingprobs;
   int* blocknrs;
   SCIP_Real* blockvalue;
   SCIP_Real increaseval;
   SCIP_VAR** mastervars;
   SCIP_Real* mastervals;
   int nmastervars;
   SCIP_VAR** vars;
   int nvars;
   SCIP_Real feastol;
   int i;
   int j;

   assert(scip != NULL);
   assert(origsol != NULL);

   masterprob = GCGrelaxGetMasterprob(scip);
   npricingprobs = GCGrelaxGetNPricingprobs(scip);

   assert( !SCIPisInfinity(scip, SCIPgetSolOrigObj(masterprob, mastersol)) );
   
   SCIP_CALL( SCIPcreateSol(scip, origsol, GCGrelaxGetProbingheur(scip)) );

   SCIP_CALL( SCIPallocBufferArray(scip, &blockvalue, npricingprobs) );
   SCIP_CALL( SCIPallocBufferArray(scip, &blocknrs, npricingprobs) );

   /* get variables of the master problem and their solution values */
   SCIP_CALL( SCIPgetVarsData(masterprob, &mastervars, &nmastervars, NULL, NULL, NULL, NULL) );
   assert(mastervars != NULL);
   assert(nmastervars >= 0);

   SCIP_CALL( SCIPallocBufferArray(scip, &mastervals, nmastervars) );
   SCIP_CALL( SCIPgetSolVals(masterprob, mastersol, nmastervars, mastervars, mastervals) );

   /* initialize the block values for the pricing problems */
   for( i = 0; i < npricingprobs; i++ )
   {
      blockvalue[i] = 0.0;
      blocknrs[i] = 0;
   }

   /* loop over all given master variables */
   for( i = 0; i < nmastervars; i++ )
   {
      SCIP_VAR** origvars;
      int norigvars;
      SCIP_Real* origvals;
      SCIP_Bool isray;
      int blocknr;

      origvars = GCGmasterVarGetOrigvars(mastervars[i]);
      norigvars = GCGmasterVarGetNOrigvars(mastervars[i]);
      origvals = GCGmasterVarGetOrigvals(mastervars[i]);
      blocknr = GCGvarGetBlock(mastervars[i]);
      isray = GCGmasterVarIsRay(mastervars[i]);

      assert(GCGvarIsMaster(mastervars[i]));
      assert(!SCIPisFeasNegative(scip, mastervals[i]));

      /** @todo handle infinite master solution values */
      assert(!SCIPisInfinity(scip, mastervals[i]));

      /* first of all, handle variables representing rays */
      if( isray )
      {
         assert(blocknr >= 0);
         /* we also want to take into account variables representing rays, that have a small value (between normal and feas eps),
          * so we do no feas comparison here */
         if( SCIPisPositive(scip, mastervals[i]) )
         {
            /* loop over all original variables contained in the current master variable */
            for( j = 0; j < norigvars; j++ )
            {
               if( SCIPisZero(scip, origvals[j]) )
                  break;

               assert(!SCIPisZero(scip, origvals[j]));

               /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done later) */
               if( GCGvarIsLinking(origvars[j]) )
                  continue;

               SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origvars[j]), origvals[j] * mastervals[i], SCIPvarGetName(mastervars[i]));
               /* increase the corresponding value */
               SCIP_CALL( SCIPincSolVal(scip, *origsol, origvars[j], origvals[j] * mastervals[i]) );
            }
         }
         mastervals[i] = 0.0;
         continue;
      }

      /* handle the variables with value >= 1 to get integral values in original solution */
      while( SCIPisFeasGE(scip, mastervals[i], 1.0) )
      {
         /* variable was directly transferred to the master problem (only in linking conss or linking variable) */
         /** @todo this may be the wrong place for this case, handle it before the while loop
          * and remove the similar case in the next while loop */
         if( blocknr == -1 )
         {
            assert(norigvars == 1);
            assert(origvals[0] == 1.0);

            /* increase the corresponding value */
            SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origvars[0]), origvals[0] * mastervals[i],  SCIPvarGetName(mastervars[i]));
            SCIP_CALL( SCIPincSolVal(scip, *origsol, origvars[0], origvals[0] * mastervals[i]) );
            mastervals[i] = 0.0;
         }
         else
         {
            assert(blocknr >= 0);
            /* loop over all original variables contained in the current master variable */
            for( j = 0; j < norigvars; j++ )
            {
               SCIP_VAR* pricingvar;
               int norigpricingvars;
               SCIP_VAR** origpricingvars;
               if( SCIPisZero(scip, origvals[j]) )
                  break;
               assert(!SCIPisZero(scip, origvals[j]));

               /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done above) */
               if( GCGvarIsLinking(origvars[j]) )
                  continue;

               pricingvar = GCGoriginalVarGetPricingVar(origvars[j]);
               assert(GCGvarIsPricing(pricingvar));

               norigpricingvars = GCGpricingVarGetNOrigvars(pricingvar);
               origpricingvars = GCGpricingVarGetOrigvars(pricingvar);

               /* just in case a variable has a value higher than the number of blocks, it represents */
               if( norigpricingvars <= blocknrs[blocknr] )
               {
                  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[norigpricingvars-1]), mastervals[i] * origvals[j], SCIPvarGetName(mastervars[i]));
                  /* increase the corresponding value */
                  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[norigpricingvars-1], mastervals[i] * origvals[j]) );
                  mastervals[i] = 1.0;
               }
               /* this should be default */
               else
               {
                  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[blocknrs[blocknr]]), origvals[j], SCIPvarGetName(mastervars[i]) );
                  /* increase the corresponding value */
                  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[blocknrs[blocknr]], origvals[j]) );
               }
            }
            mastervals[i] = mastervals[i] - 1.0;
            blocknrs[blocknr]++;
         }
      }
   }

   /* loop over all given master variables */
   for( i = 0; i < nmastervars; i++ )
   {
      SCIP_VAR** origvars;
      int norigvars;
      SCIP_Real* origvals;
      int blocknr;

      origvars = GCGmasterVarGetOrigvars(mastervars[i]);
      norigvars = GCGmasterVarGetNOrigvars(mastervars[i]);
      origvals = GCGmasterVarGetOrigvals(mastervars[i]);
      blocknr = GCGvarGetBlock(mastervars[i]);

      if( SCIPisFeasZero(scip, mastervals[i]) )
      {
         continue;
      }
      assert(SCIPisFeasGE(scip, mastervals[i], 0.0) && SCIPisFeasLT(scip, mastervals[i], 1.0));

      while( SCIPisFeasPositive(scip, mastervals[i]) )
      {
         assert(GCGvarIsMaster(mastervars[i]));
         assert(!GCGmasterVarIsRay(mastervars[i]));

         if( blocknr == -1 )
         {
            assert(norigvars == 1);
            assert(origvals[0] == 1.0);

            SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origvars[0]), origvals[0] * mastervals[i], SCIPvarGetName(mastervars[i]) );
            /* increase the corresponding value */
            SCIP_CALL( SCIPincSolVal(scip, *origsol, origvars[0], origvals[0] * mastervals[i]) );
            mastervals[i] = 0.0;
         }
         else
         {
            increaseval = MIN(mastervals[i], 1.0 - blockvalue[blocknr]);
            /* loop over all original variables contained in the current master variable */
            for( j = 0; j < norigvars; j++ )
            {
               SCIP_VAR* pricingvar;
               int norigpricingvars;
               SCIP_VAR** origpricingvars;

               if( SCIPisZero(scip, origvals[j]) )
                  continue;

               /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done above) */
               if( GCGvarIsLinking(origvars[j]) )
                  continue;

               pricingvar = GCGoriginalVarGetPricingVar(origvars[j]);
               assert(GCGvarIsPricing(pricingvar));

               norigpricingvars = GCGpricingVarGetNOrigvars(pricingvar);
               origpricingvars = GCGpricingVarGetOrigvars(pricingvar);

               if( norigpricingvars <= blocknrs[blocknr] )
               {
                  increaseval = mastervals[i];

                  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[norigpricingvars-1]), origvals[j] * increaseval, SCIPvarGetName(mastervars[i]) );
                  /* increase the corresponding value */
                  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[norigpricingvars-1], origvals[j] * increaseval) );
               }
               else
               {
                  /* increase the corresponding value */
                  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[blocknrs[blocknr]]), origvals[j] * increaseval, SCIPvarGetName(mastervars[i]) );
                  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[blocknrs[blocknr]], origvals[j] * increaseval) );
               }
            }

            mastervals[i] = mastervals[i] - increaseval;
            if( SCIPisFeasZero(scip, mastervals[i]) )
            {
               mastervals[i] = 0.0;
            }
            blockvalue[blocknr] += increaseval;

            /* if the value assigned to the block is equal to 1, this block is full and we take the next block */
            if( SCIPisFeasGE(scip, blockvalue[blocknr], 1.0) )
            {
               blockvalue[blocknr] = 0.0;
               blocknrs[blocknr]++;
            }
         }
      }
   }

   SCIPfreeBufferArray(scip, &mastervals);
   SCIPfreeBufferArray(scip, &blocknrs);
   SCIPfreeBufferArray(scip, &blockvalue);

   /* if the solution violates one of its bounds by more than feastol
    * and less than 10*feastol, round it and print a warning
    */
   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
   SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
   for( i = 0; i < nvars; ++i )
   {
      SCIP_Real solval;
      SCIP_Real lb;
      SCIP_Real ub;

      solval = SCIPgetSolVal(scip, *origsol, vars[i]);
      lb = SCIPvarGetLbLocal(vars[i]);
      ub = SCIPvarGetUbLocal(vars[i]);

      if( SCIPisFeasGT(scip, solval, ub) && EPSEQ(solval, ub, 10 * feastol) )
      {
         SCIP_CALL( SCIPsetSolVal(scip, *origsol, vars[i], ub) );
         SCIPwarningMessage(scip, "Variable %s rounded from %g to %g in relaxation solution\n",
            SCIPvarGetName(vars[i]), solval, ub);
      }
      else if( SCIPisFeasLT(scip, solval, lb) && EPSEQ(solval, lb, 10 * feastol) )
      {
         SCIP_CALL( SCIPsetSolVal(scip, *origsol, vars[i], lb) );
         SCIPwarningMessage(scip, "Variable %s rounded from %g to %g in relaxation solution\n",
            SCIPvarGetName(vars[i]), solval, lb);
      }
   }

   return SCIP_OKAY;
}
Example #12
0
/** reads a given xml solution file */
static
SCIP_RETCODE readXMLSol(
   SCIP*                 scip,               /**< SCIP data structure */
   const char*           filename            /**< name of the input file */
   )
{
   SCIP_Bool unknownvariablemessage;
   SCIP_SOL* sol;
   SCIP_Bool error;
   XML_NODE* start;
   const XML_NODE* varsnode;
   const XML_NODE* varnode;
   const char* tag;

   assert( scip != NULL );
   assert( filename != NULL );

   /* read xml file */
   start = xmlProcess(filename);

   if( start == NULL )
   {
      SCIPerrorMessage("Some error occured during parsing the XML solution file.\n");
      return SCIP_READERROR;
   }

   /* create zero solution */
   SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );

   error = FALSE;

   /* find variable sections */
   tag = "variables";
   varsnode = xmlFindNodeMaxdepth(start, tag, 0, 3);
   if( varsnode == NULL )
   {
      /* free xml data */
      xmlFreeNode(start);

      SCIPerrorMessage("Variable section not found.\n");
      return SCIP_READERROR;
   }

   /* loop through all variables */
   unknownvariablemessage = FALSE;
   for( varnode = xmlFirstChild(varsnode); varnode != NULL; varnode = xmlNextSibl(varnode) )
   {
      SCIP_VAR* var;
      const char* varname;
      const char* varvalue;
      SCIP_Real value;
      int nread;

      /* find variable name */
      varname = xmlGetAttrval(varnode, "name");
      if( varname == NULL )
      {
         SCIPerrorMessage("Attribute \"name\" of variable not found.\n");
         error = TRUE;
         break;
      }

      /* find the variable */
      var = SCIPfindVar(scip, varname);
      if( var == NULL )
      {
         if( !unknownvariablemessage )
         {
            SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> of solution file <%s>\n", 
               varname, filename);
            SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "  (further unknown variables are ignored)\n");
            unknownvariablemessage = TRUE;
         }
         continue;
      }

      /* find value of variable */
      varvalue = xmlGetAttrval(varnode, "value");
      if( varvalue == NULL )
      {
         SCIPerrorMessage("Attribute \"value\" of variable not found.\n");
         error = TRUE;
         break;
      }

      /* cast the value */
      if( strncasecmp(varvalue, "inv", 3) == 0 )
         continue;
      else if( strncasecmp(varvalue, "+inf", 4) == 0 || strncasecmp(varvalue, "inf", 3) == 0 )
         value = SCIPinfinity(scip);
      else if( strncasecmp(varvalue, "-inf", 4) == 0 )
         value = -SCIPinfinity(scip);
      else
      {
         nread = sscanf(varvalue, "%lf", &value);
         if( nread != 1 )
         {
            SCIPwarningMessage(scip, "invalid solution value <%s> for variable <%s> in XML solution file <%s>\n", varvalue, varname, filename);
            error = TRUE;
            break;
         }
      }

      /* set the solution value of the variable, if not multiaggregated */
      if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
      {
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var));
      }
      else
      {
         SCIP_RETCODE retcode;
         retcode = SCIPsetSolVal(scip, sol, var, value);

         if( retcode == SCIP_INVALIDDATA )
         {
            if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED )
            {
               SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n",
                  SCIPvarGetName(var));
            }
            else
            {
               SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n",
                  SCIPvarGetName(var));
            }
         }
         else
         {
            SCIP_CALL( retcode );
         }
      }
   }

   if( !error )
   {
      SCIP_Bool stored;

      /* add and free the solution */
      if( SCIPisTransformed(scip) )
      {
         SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, &stored) );

         /* display result */
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n",
            filename, stored ? "accepted" : "rejected - solution is infeasible or objective too poor");
      }
      else
      {
         SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) );

         /* display result */
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n",
            filename, stored ? "accepted as candidate, will be checked when solving starts" : "rejected - solution objective too poor");
      }
   }
   else
   {
      /* free solution */
      SCIP_CALL( SCIPfreeSol(scip, &sol) );

      /* free xml data */
      xmlFreeNode(start);

      return SCIP_READERROR;
   }

   /* free xml data */
   xmlFreeNode(start);

   return SCIP_OKAY;
}
Example #13
0
/** execution method of primal heuristic */
static
SCIP_DECL_HEUREXEC(heurExecTrivial)
{  /*lint --e{715}*/
   SCIP_VAR** vars;
   SCIP_SOL* lbsol;                     /* solution where all variables are set to their lower bounds */
   SCIP_SOL* ubsol;                     /* solution where all variables are set to their upper bounds */
   SCIP_SOL* zerosol;                   /* solution where all variables are set to zero */
   SCIP_SOL* locksol;                   /* solution where all variables are set to the bound with the fewer locks */

   SCIP_Real large;

   int nvars;
   int nbinvars;
   int i;

   SCIP_Bool success;
   SCIP_Bool zerovalid;

   *result = SCIP_DIDNOTRUN;

   if( SCIPgetNRuns(scip) > 1 )
      return SCIP_OKAY;

   *result = SCIP_DIDNOTFIND;
   success = FALSE;

   /* initialize data structure */
   SCIP_CALL( SCIPcreateSol(scip, &lbsol, heur) );
   SCIP_CALL( SCIPcreateSol(scip, &ubsol, heur) );
   SCIP_CALL( SCIPcreateSol(scip, &zerosol, heur) );
   SCIP_CALL( SCIPcreateSol(scip, &locksol, heur) );

   /* determine large value to set variables to */
   large = SCIPinfinity(scip);
   if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) )
      large = 0.1 / SCIPfeastol(scip);

   SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );

   /* if the problem is binary, we do not have to check the zero solution, since it is equal to the lower bound
    * solution */
   zerovalid = (nvars != nbinvars);
   assert(vars != NULL || nvars == 0);

   for( i = 0; i < nvars; i++ )
   {
      SCIP_Real lb;
      SCIP_Real ub;

      assert(vars != NULL); /* this assert is needed for flexelint */

      lb = SCIPvarGetLbLocal(vars[i]);
      ub = SCIPvarGetUbLocal(vars[i]);
      
      /* if problem is obviously infeasible due to empty domain, stop */
      if( SCIPisGT(scip, lb, ub) )
         goto TERMINATE;

      /* set bounds to sufficient large value */
      if( SCIPisInfinity(scip, -lb) )
         lb = MIN(-large, ub);
      if( SCIPisInfinity(scip, ub) )
      {
         SCIP_Real tmp;

         tmp = SCIPvarGetLbLocal(vars[i]);
         ub = MAX(tmp, large);
      }

      SCIP_CALL( SCIPsetSolVal(scip, lbsol, vars[i], lb) );
      SCIP_CALL( SCIPsetSolVal(scip, ubsol, vars[i], ub) );

      /* try the zero vector, if it is in the bounds region */
      if( zerovalid )
      {
         if( SCIPisLE(scip, lb, 0.0) && SCIPisLE(scip, 0.0, ub) )
         {
            SCIP_CALL( SCIPsetSolVal(scip, zerosol, vars[i], 0.0) );
         }
         else
            zerovalid = FALSE;
      }

      /* set variables to the bound with fewer locks, if tie choose an average value */
      if( SCIPvarGetNLocksDown(vars[i]) >  SCIPvarGetNLocksUp(vars[i]) )
      {
         SCIP_CALL( SCIPsetSolVal(scip, locksol, vars[i], ub) );
      }
      else if( SCIPvarGetNLocksDown(vars[i]) <  SCIPvarGetNLocksUp(vars[i]) )
      {
         SCIP_CALL( SCIPsetSolVal(scip, locksol, vars[i], lb) );
      }
      else
      {
         SCIP_Real solval;
         solval = (lb+ub)/2.0;

         /* if a tie occurs, roughly every third integer variable will be rounded up */
         if( SCIPvarGetType(vars[i]) != SCIP_VARTYPE_CONTINUOUS )
            solval = i % 3 == 0 ? SCIPceil(scip,solval) : SCIPfloor(scip,solval);

         assert(SCIPisFeasLE(scip,SCIPvarGetLbLocal(vars[i]),solval) && SCIPisFeasLE(scip,solval,SCIPvarGetUbLocal(vars[i])));

         SCIP_CALL( SCIPsetSolVal(scip, locksol, vars[i], solval) );
      }
   }

   /* try lower bound solution */
   SCIPdebugMessage("try lower bound solution\n");
   SCIP_CALL( SCIPtrySol(scip, lbsol, FALSE, FALSE, TRUE, TRUE, &success) );

   if( success )
   {
      SCIPdebugMessage("found feasible lower bound solution:\n");
      SCIPdebug( SCIP_CALL( SCIPprintSol(scip, lbsol, NULL, FALSE) ) );

      *result = SCIP_FOUNDSOL;
   }

   /* try upper bound solution */
   SCIPdebugMessage("try upper bound solution\n");
   SCIP_CALL( SCIPtrySol(scip, ubsol, FALSE, FALSE, TRUE, TRUE, &success) );

   if( success )
   {
      SCIPdebugMessage("found feasible upper bound solution:\n");
      SCIPdebug( SCIP_CALL( SCIPprintSol(scip, ubsol, NULL, FALSE) ) );

      *result = SCIP_FOUNDSOL;
   }

   /* try zero solution */
   if( zerovalid )
   {
      SCIPdebugMessage("try zero solution\n");
      SCIP_CALL( SCIPtrySol(scip, zerosol, FALSE, FALSE, TRUE, TRUE, &success) );

      if( success )
      {
         SCIPdebugMessage("found feasible zero solution:\n");
         SCIPdebug( SCIP_CALL( SCIPprintSol(scip, zerosol, NULL, FALSE) ) );

         *result = SCIP_FOUNDSOL;
      }
   }

   /* try lock solution */
   SCIPdebugMessage("try lock solution\n");
   SCIP_CALL( SCIPtrySol(scip, locksol, FALSE, FALSE, TRUE, TRUE, &success) );

   if( success )
   {
      SCIPdebugMessage("found feasible lock solution:\n");
      SCIPdebug( SCIP_CALL( SCIPprintSol(scip, locksol, NULL, FALSE) ) );

      *result = SCIP_FOUNDSOL;
   }

TERMINATE:
   /* free solutions */
   SCIP_CALL( SCIPfreeSol(scip, &lbsol) );
   SCIP_CALL( SCIPfreeSol(scip, &ubsol) );
   SCIP_CALL( SCIPfreeSol(scip, &zerosol) );
   SCIP_CALL( SCIPfreeSol(scip, &locksol) );

   return SCIP_OKAY;
}
Example #14
0
/** try one-opt on given solution */
static
SCIP_RETCODE tryOneOpt(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_HEUR*            heur,               /**< indicator heuristic */
   SCIP_HEURDATA*        heurdata,           /**< heuristic data */
   int                   nindconss,          /**< number of indicator constraints */
   SCIP_CONS**           indconss,           /**< indicator constraints */
   SCIP_Bool*            solcand,            /**< values for indicator variables in partial solution */
   int*                  nfoundsols          /**< number of solutions found */
   )
{
   SCIP_Bool cutoff;
   SCIP_Bool lperror;
   SCIP_Bool stored;
   SCIP_SOL* sol;
   int cnt = 0;
   int i;
   int c;

   assert( scip != NULL );
   assert( heur != NULL );
   assert( heurdata != NULL );
   assert( nindconss == 0 || indconss != NULL );
   assert( solcand != NULL );
   assert( nfoundsols != NULL );

   SCIPdebugMessage("Performing one-opt ...\n");
   *nfoundsols = 0;

   SCIP_CALL( SCIPstartProbing(scip) );

   for (i = 0; i < nindconss; ++i)
   {
      SCIP_VAR* binvar;

      /* skip nonactive constraints */
      if ( ! SCIPconsIsActive(indconss[i]) )
         continue;

      binvar = SCIPgetBinaryVarIndicator(indconss[i]);
      assert( binvar != NULL );

      /* skip constraints with fixed variables */
      if ( SCIPvarGetUbLocal(binvar) < 0.5 || SCIPvarGetLbLocal(binvar) > 0.5 )
         continue;

      /* return if the we would exceed the depth limit of the tree */
      if( SCIPgetDepthLimit(scip) <= SCIPgetDepth(scip) )
         break;

      /* get rid of all bound changes */
      SCIP_CALL( SCIPnewProbingNode(scip) );
      ++cnt;

      /* fix variables */
      for (c = 0; c < nindconss; ++c)
      {
         SCIP_Bool s;

         /* skip nonactive constraints */
         if ( ! SCIPconsIsActive(indconss[c]) )
            continue;

         binvar = SCIPgetBinaryVarIndicator(indconss[c]);
         assert( binvar != NULL );

         /* fix variables according to solution candidate, except constraint i */
         if ( c == i )
            s = ! solcand[c];
         else
            s = solcand[c];

         if ( ! s )
         {
            if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
            {
               SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
            }
         }
         else
         {
            if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
            {
               SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
            }
         }
      }

      /* propagate variables */
      SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
      if ( cutoff )
      {
         SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
         continue;
      }

      /* solve LP to move continuous variables */
      SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );

      /* the LP often reaches the objective limit - we currently do not use such solutions */
      if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
      {
#ifdef SCIP_DEBUG
         if ( lperror )
            SCIPdebugMessage("An LP error occured.\n");
#endif
         SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
         continue;
      }

      /* create solution */
      SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );

      /* copy the current LP solution to the working solution */
      SCIP_CALL( SCIPlinkLPSol(scip, sol) );

      /* check solution for feasibility */
      SCIPdebugMessage("One-opt found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));

      /* only check integrality, because we solved an LP */
      SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, TRUE, FALSE, &stored) );
      if ( stored )
         ++(*nfoundsols);
      SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
   }
   SCIP_CALL( SCIPendProbing(scip) );

   SCIPdebugMessage("Finished one-opt (tried variables: %d, found sols: %d).\n", cnt, *nfoundsols);

   return SCIP_OKAY;
}
Example #15
0
/** try given solution */
static
SCIP_RETCODE trySolCandidate(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_HEUR*            heur,               /**< indicator heuristic */
   SCIP_HEURDATA*        heurdata,           /**< heuristic data */
   int                   nindconss,          /**< number of indicator constraints */
   SCIP_CONS**           indconss,           /**< indicator constraints */
   SCIP_Bool*            solcand,            /**< values for indicator variables in partial solution */
   int*                  nfoundsols          /**< number of solutions found */
   )
{
   SCIP_Bool cutoff;
   SCIP_Bool lperror;
   SCIP_Bool stored;
   SCIP_SOL* sol;
   int c;

   assert( scip != NULL );
   assert( heur != NULL );
   assert( heurdata != NULL );
   assert( nindconss == 0 || indconss != NULL );
   assert( solcand != NULL );
   assert( nfoundsols != NULL );

   SCIPdebugMessage("Trying to generate feasible solution with indicators from solution candidate ...\n");
   *nfoundsols = 0;

   SCIP_CALL( SCIPstartProbing(scip) );

   /* we can stop here if we have already reached the maximal depth */
   if( SCIPgetDepthLimit(scip) <= SCIPgetDepth(scip) )
   {
      SCIP_CALL( SCIPendProbing(scip) );
      return SCIP_OKAY;
   }

   SCIP_CALL( SCIPnewProbingNode(scip) );

   /* fix variables */
   for (c = 0; c < nindconss; ++c)
   {
      SCIP_VAR* binvar;

      /* skip nonactive constraints */
      if ( ! SCIPconsIsActive(indconss[c]) )
         continue;

      binvar = SCIPgetBinaryVarIndicator(indconss[c]);
      assert( binvar != NULL );

      /* Fix binary variables not in cover to 1 and corresponding slack variables to 0. The other binary variables are fixed to 0. */
      if ( ! solcand[c] )
      {
         /* to be sure, check for non-fixed variables */
         if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
         {
            SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
         }
      }
      else
      {
         if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
         {
            SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
         }
      }
   }

   /* propagate variables */
   SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
   if ( cutoff )
   {
      SCIPdebugMessage("Solution candidate reaches cutoff (in propagation).\n");
      SCIP_CALL( SCIPendProbing(scip) );
      return SCIP_OKAY;
   }

   /* solve LP to move continuous variables */
   SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );

   /* the LP often reaches the objective limit - we currently do not use such solutions */
   if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
   {
#ifdef SCIP_DEBUG
      if ( lperror )
         SCIPdebugMessage("An LP error occured.\n");
      else
         SCIPdebugMessage("Solution candidate reaches cutoff (in LP solving).\n");
#endif
      SCIP_CALL( SCIPendProbing(scip) );
      return SCIP_OKAY;
   }

   /* create solution */
   SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );

   /* copy the current LP solution to the working solution */
   SCIP_CALL( SCIPlinkLPSol(scip, sol) );

   /* check solution for feasibility */
#ifdef SCIP_DEBUG
   SCIPdebugMessage("Found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));
#ifdef SCIP_MORE_DEBUG
   SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) );
#endif
   SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, &stored) );
   if ( stored )
   {
      ++(*nfoundsols);
      SCIPdebugMessage("Solution is feasible and stored.\n");
   }
   else
      SCIPdebugMessage("Solution was not stored.\n");
#else
   /* only check integrality, because we solved an LP */
   SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, TRUE, FALSE, &stored) );
   if ( stored )
      ++(*nfoundsols);
#endif
   SCIP_CALL( SCIPendProbing(scip) );

   /* possibly perform one-opt */
   if ( stored && heurdata->oneopt )
   {
      int nfound = 0;
      assert( *nfoundsols > 0 );
      SCIP_CALL( tryOneOpt(scip, heur, heurdata, nindconss, indconss, solcand, &nfound) );
   }

   return SCIP_OKAY;
}
Example #16
0
/** reads a given SCIP solution file, problem has to be transformed in advance */
static
SCIP_RETCODE readSol(
   SCIP*                 scip,               /**< SCIP data structure */
   const char*           fname               /**< name of the input file */
   )
{
   SCIP_SOL* sol;
   SCIP_FILE* file;
   SCIP_Bool error;
   SCIP_Bool unknownvariablemessage;
   SCIP_Bool stored;
   SCIP_Bool usevartable;
   int lineno;

   assert(scip != NULL);
   assert(fname != NULL);

   SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );

   if( !usevartable )
   {
      SCIPerrorMessage("Cannot read solution file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n");
      return SCIP_READERROR;
   }

   /* open input file */
   file = SCIPfopen(fname, "r");
   if( file == NULL )
   {
      SCIPerrorMessage("cannot open file <%s> for reading\n", fname);
      SCIPprintSysError(fname);
      return SCIP_NOFILE;
   }

   /* create zero solution */
   SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );

   /* read the file */
   error = FALSE;
   unknownvariablemessage = FALSE;
   lineno = 0;
   while( !SCIPfeof(file) && !error )
   {
      char buffer[SCIP_MAXSTRLEN];
      char varname[SCIP_MAXSTRLEN];
      char valuestring[SCIP_MAXSTRLEN];
      char objstring[SCIP_MAXSTRLEN];
      SCIP_VAR* var;
      SCIP_Real value;
      int nread;

      /* get next line */
      if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL )
         break;
      lineno++;

      /* there are some lines which may preceed the solution information */
      if( strncasecmp(buffer, "solution status:", 16) == 0 || strncasecmp(buffer, "objective value:", 16) == 0 ||
         strncasecmp(buffer, "Log started", 11) == 0 || strncasecmp(buffer, "Variable Name", 13) == 0 ||
         strncasecmp(buffer, "All other variables", 19) == 0 || strncasecmp(buffer, "\n", 1) == 0 || 
         strncasecmp(buffer, "NAME", 4) == 0 || strncasecmp(buffer, "ENDATA", 6) == 0 )    /* allow parsing of SOL-format on the MIPLIB 2003 pages */
         continue;

      /* parse the line */
      nread = sscanf(buffer, "%s %s %s\n", varname, valuestring, objstring);
      if( nread < 2 )
      {
         SCIPerrorMessage("Invalid input line %d in solution file <%s>: <%s>.\n", lineno, fname, buffer);
         error = TRUE;
         break;
      }

      /* find the variable */
      var = SCIPfindVar(scip, varname);
      if( var == NULL )
      {
         if( !unknownvariablemessage )
         {
            SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n", 
               varname, lineno, fname);
            SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "  (further unknown variables are ignored)\n");
            unknownvariablemessage = TRUE;
         }
         continue;
      }

      /* cast the value */
      if( strncasecmp(valuestring, "inv", 3) == 0 )
         continue;
      else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 )
         value = SCIPinfinity(scip);
      else if( strncasecmp(valuestring, "-inf", 4) == 0 )
         value = -SCIPinfinity(scip);
      else
      {
         nread = sscanf(valuestring, "%lf", &value);
         if( nread != 1 )
         {
            SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n",
               valuestring, varname, lineno, fname);
            error = TRUE;
            break;
         }
      }

      /* set the solution value of the variable, if not multiaggregated */
      if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
      {
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var));
      }
      else
      {
         SCIP_RETCODE retcode;
         retcode = SCIPsetSolVal(scip, sol, var, value);

         if( retcode == SCIP_INVALIDDATA )
         {
            if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED )
            {
               SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n",
                  SCIPvarGetName(var));
            }
            else
            {
               SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n",
                  SCIPvarGetName(var));
            }
         }
         else
         {
            SCIP_CALL( retcode );
         }
      }
   }

   /* close input file */
   SCIPfclose(file);

   if( !error )
   {
      /* add and free the solution */
      if( SCIPisTransformed(scip) )
      {
         SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, &stored) );

         /* display result */
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n",
            fname, stored ? "accepted" : "rejected - solution is infeasible or objective too poor");
      }
      else
      {
         /* add primal solution to solution candidate storage, frees the solution afterwards */
         SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) );

         /* display result */
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n",
            fname, stored ? "accepted as candidate, will be checked when solving starts" : "rejected - solution objective too poor");
      }

      return SCIP_OKAY;
   }
   else
   {
      /* free solution */
      SCIP_CALL( SCIPfreeSol(scip, &sol) );

      return SCIP_READERROR;
   }
}
Example #17
0
/** execution method of primal heuristic */
static
SCIP_DECL_HEUREXEC(heurExecForward)
{  /*lint --e{715}*/
	
   SCIP_PROBDATA* probdata;
	int	n;
	int	p;
	int	ndep;

	/* "_" means the matrix for blas */
	SCIP_Real*	y;				/* [n] */
	SCIP_Real*	orig_X_;		/* [n*p] */
	SCIP_Real*	orig_Q_;		/* [p*p] <- (X^t) X */
	SCIP_Real*	orig_q;		/* [p]   <- (X^t) y */
	SCIP_Real	r;

	int*	Mdep;					/* [ndep] */
	int*	groupX;				/* [ndep*p] */

	/* for forward selection */
	int	dim;
	int*	list;					/* [p] */
	SCIP_Real*	a;				/* [dim] */
	SCIP_Real*	a_old;		/* [dim-1] */
	SCIP_Real*	a_new;		/* [dim] */
	SCIP_Real	RSS;			/* residual sum of square */
	SCIP_Real	RSS_new;
	SCIP_Real	AIC;
	SCIP_Real	AIC_new;

	int	ublb;
	int	*Branchz;		/* [3*p] */

	/*
	 *	X: sub matrix of orig_X_ 
	 *	Y:	(X^t X)^-1 
	 * X_new = (X, x_i);
	 * Z: (X_new ^t X_new)^-1
	 *		= ( V   v
	 			 v^t u )
	 */

	SCIP_Real*	Xy;	/* sub vector of orig_q */ 
	SCIP_Real*	X_;	
	SCIP_Real*	Y_;	/* [(dim-1)*(dim-1)] */
	SCIP_Real*	Z_;	/* [dim*dim] */
	SCIP_Real*	W_;	/* [dim*dim] */
	SCIP_Real*	V_;	/* [(dim-1)*(dim-1)] */
	SCIP_Real*	v;		/* [dim-1] */
	SCIP_Real	u;
	
	SCIP_Real*	b;		/* [dim-1] */
	SCIP_Real*	c;		/* [dim-1] */
	SCIP_Real*	d;		/* [n] */

	/* variables */
	SCIP_VAR**	var_a;		/* [p] continuous variables */
	SCIP_VAR**	var_z;		/* [p] 01 variables */
	SCIP_VAR**	var_ep;		/* [n] continuous variables */
	SCIP_VAR*	var_rss;		/* continuous variable, residual sum of squares */
	SCIP_VAR*	var_log;		/* continuous variable, log(rss) */

	/* set solution */ 
	SCIP_Real *ep;
	
	int	nsols;
	int	store;
	SCIP_SOL**	sols;
	SCIP_Real	objval;

	SCIP_SOL*	sol;
	SCIP_Real*	solvals;
	SCIP_Bool	success;
	int			nvars	=	SCIPgetNVars(scip);
	SCIP_VAR**	vars;

	int 	i,j,t,ct;
	int	memo;

   assert(heur != NULL);
   assert(scip != NULL);
   assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
   assert(result != NULL);

#if MYPARA_LOG
	printf("forward selection!\n");
#endif

   /* get heuristic data */
	/*
   SCIP_HEURDATA* heurdata;
   heurdata = SCIPheurGetData(heur);
   assert(heurdata != NULL);
   assert(lastsolindices != NULL);
	*/

	/* get values from probdata */
   probdata = SCIPgetProbData(scip);
   assert(probdata != NULL);

	n	=	SCIPprobdataGetNdatas(probdata);
	p	=	SCIPprobdataGetNexvars(probdata);
	ndep	=	SCIPprobdataGetNdep(probdata);

	y	=	SCIPprobdataGety(probdata);
	orig_X_	=	SCIPprobdataGetX(probdata);
	orig_Q_	=	SCIPprobdataGetQ(probdata);
	orig_q	=	SCIPprobdataGetq(probdata);
	r	=	SCIPprobdataGetr(probdata);

	if( ndep ){
		Mdep		=	SCIPprobdataGetMdep(probdata);
		groupX	=	SCIPprobdataGetgroupX(probdata);
	}else{
		Mdep		=	NULL;
		groupX	=	NULL;
	}

	/* variables */
	var_a		=	SCIPprobdataGetVars_a(probdata);
	var_z		=	SCIPprobdataGetVars_z(probdata);
	var_ep	=	SCIPprobdataGetVars_ep(probdata);
	var_rss	=	SCIPprobdataGetVar_rss(probdata);
	var_log	=	SCIPprobdataGetVar_log(probdata);

	/* get branching info */
	/* alloc */
	SCIP_CALL( SCIPallocBufferArray(scip, &Branchz, 3*p));
	
	GenerateZeroVecInt( 3*p, Branchz);

	for(i=0; i<p; ++i){
		ublb					=	SCIPround(scip, SCIPcomputeVarUbLocal(scip, var_z[i]) 
								+	SCIPcomputeVarLbLocal(scip, var_z[i]));
		*(Branchz+(ublb*p)+i) 	= 	1;
	}

#if MYPARA_LOG
	for(i=0; i<3; i++){
		for(j=0; j<p; j++){
			printf("%d, ", *(Branchz+(i*p)+j));
		}
		newline();
	}
#endif

	if( ndep ){
		for(i=0; i<ndep; i++){
			memo = -1; 
			for(j=0; j<p; j++){
				if( *(groupX+(i*p)+j)==1 ){
					if( *(Branchz+j)==1 ) break;
					if( *(Branchz+p+j)==1 ) memo=j;
					if( j==Mdep[i] ){
						if( memo==-1 ){
							printf("error in heur_backward.c\n");
							stop();
						}
						*(Branchz+p+memo) = 0;
						*(Branchz+memo) = 1;
						break;
					}
				}
			}
		}
	}
	
#if MYPARA_LOG
	printf("linear dependent\n");
	if( ndep ){
		for(i=0; i<3; i++){
			for(j=0; j<p; j++){
				printf("%d, ", *(Branchz+(i*p)+j));
			}
			newline();
		}
	}
#endif
	
	/* alloc */
	SCIP_CALL( SCIPallocBufferArray(scip, &X_, n*p));
	SCIP_CALL( SCIPallocBufferArray(scip, &Xy, p));
	SCIP_CALL( SCIPallocBufferArray(scip, &d, n));
	SCIP_CALL( SCIPallocBufferArray(scip, &list, p));
	
	/* initialize from Branchz */
#if MYPARA_LOG
	printf("initialization\n");
#endif

	GenerateZeroVecInt( p, list);

	dim = 0;
	memo = -1;
	AIC = 1e+06;
	SCIP_CALL( SCIPallocBufferArray(scip, &a_old, dim+1));

	for(i=0; i<p; i++){
		
		if( Branchz[i]==1 ){ /* if z_i is fixed to 0 */
			list[i] = -1;
		}else if( Branchz[p+i]==1 ){ /* if z_i is unfixed */
			list[i] = 0;
		}else if( Branchz[2*p+i]==1 ){ /* if z_i is fixed 1 */
			dim++;
			list[i] = dim;

			if( dim == 1 ){

				a_old[0] = orig_q[i] / mat_( orig_Q_, p, i, i);
				RSS = RSSvalue( 1, a_old, &orig_q[i], r);
				AIC = AICvalue( n, dim, RSS);

				/* update X_ and Xy */
				mydcopy_( &orig_X_[n * i], &X_[n * (dim-1)], n);
				Xy[dim-1] = orig_q[i];

				/* generate Y ( dim = 1 ) */
				SCIP_CALL( SCIPallocBufferArray( scip, &Y_, dim*dim));
				Y_[0] = 1 / mat_( orig_Q_, p, i, i);
		
			}else{
				/* alloc */
				SCIPfreeBufferArray(scip, &a_old);
				SCIP_CALL( SCIPallocBufferArray( scip, &a_old, dim));
				SCIP_CALL( SCIPallocBufferArray( scip, &b, dim-1));
				SCIP_CALL( SCIPallocBufferArray( scip, &c, dim-1));
				SCIP_CALL( SCIPallocBufferArray( scip, &v, dim-1));
				SCIP_CALL( SCIPallocBufferArray( scip, &V_, (dim-1)*(dim-1)));
				SCIP_CALL( SCIPallocBufferArray( scip, &Z_, (dim)*(dim)));
				
				/* 1. b <- X^t x_i */
				dgemv_t( X_, n, dim-1, &orig_X_[n * i], b);
				//printv( dim-1, b);

				/* 2. c <- Y b */
				dgemv_2( Y_, dim-1, dim-1, b, c);
				//printv( dim-1, c);

				/* 3. d <- - X c + x_i */
				dgemv_1( X_, n, dim-1, c, &orig_X_[n * i], -1.0, 1.0, d);
				//printv( n, d);

				/* 4. u <- 1/<x_i, d> */
				u = 1.0 / myddot_( &orig_X_[n * i], d, n);
				//prints(u);
				
				/* 5. v <- - u c */
				mydscal_( c, dim-1, -u, v);
				//printv( dim-1, v);

				/* 6. V <- Y + u c c^t */
				dger_1( Y_, c, c, dim-1, dim-1, u, V_);
				//printM_( V_, dim-1, dim-1);

				/* 7. Z */
				/* V */
				for(j=0; j<(dim-1); j++){
					for(t=0; t<(dim-1); t++){
						*(Z_ + j + (t*dim) ) = mat_( V_, dim-1, j, t);
					}
				}
				/* v */
				for(j=0; j<(dim-1); j++){
					*(Z_ + dim-1 + (j*dim) )  = v[j];
					*(Z_ + j + ((dim-1)*dim)) = v[j];
				}

				/* u */
				*(Z_ + dim-1 + ((dim-1)*dim)) = u;
				//printM_( Z_, dim, dim);

				/* 8. a_old <- Z (Xy) */
				Xy[dim-1] = orig_q[i];
				dgemv_2( Z_, dim, dim, Xy, a_old);
				//printv( dim, a_old);

				RSS = RSSvalue( dim, a_old, Xy, r);
				AIC = AICvalue( n, dim, RSS);

				/* copy */
				SCIPfreeBufferArray(scip, &Y_);
				SCIP_CALL( SCIPallocBufferArray(scip, &Y_, dim*dim));
				mydcopy_( Z_, Y_, dim*dim);
	
				/* update X_ and Xy */
				mydcopy_( &orig_X_[n * i], &X_[n * (dim-1)], n);
				Xy[dim-1] = orig_q[i];

				/* free */
				SCIPfreeBufferArray(scip, &b);
				SCIPfreeBufferArray(scip, &c);
				SCIPfreeBufferArray(scip, &v);
				SCIPfreeBufferArray(scip, &V_);
				SCIPfreeBufferArray(scip, &Z_);
			}

#if MYPARA_LOG
			printf("---> %dth variable, AIC:%f\n", i, AIC);
#endif

		}else{
			printf("error:heur_forward.c\n");
			stop();
		}
	}


	if( dim == 0 ){
#if MYPARA_LOG
		printf("[dim:0]\n");
#endif
		dim++;
		RSS = 1e+06;
		for(i=0; i<p; i++){
			if( list[i] == 0 ){
				a_old[0] = orig_q[i] / mat_( orig_Q_, p, i, i);
				RSS_new = RSSvalue( 1, a_old, &orig_q[i], r);
				if( RSS_new < RSS ){
					RSS = RSS_new;
					memo = i;
				}
#if MYPARA_LOG
			printf("%d: RSS = %f\n", i, RSS_new);
#endif
			}
		}
		
		if( memo < 0 || memo >= p ){
			printf("error in heur_forward.c\n");
			stop();
		}
	
		AIC = AICvalue( n, dim, RSS);
		list[memo] = dim;
		
		/* update X_ and Xy */
		mydcopy_( &orig_X_[n * memo], &X_[n * (dim-1)], n);
		Xy[dim-1] = orig_q[memo];
	
		/* generate Y ( dim = 1 ) */
		SCIP_CALL( SCIPallocBufferArray( scip, &Y_, dim*dim));
		Y_[0] = 1 / mat_( orig_Q_, p, memo, memo);
	
#if MYPARA_LOG
		printf("---> %dth variable, AIC:%f\n", memo, AIC);
#endif
	} /* if ( dim==0 ) */

	while(1){
		dim++;
		memo = -1;
		RSS = 1e+06;
#if MYPARA_LOG
		printf("(dim=%d) ", dim);
		Longline();
#endif

		/* alloc */
		SCIP_CALL( SCIPallocBufferArray( scip, &a_new, dim));
		SCIP_CALL( SCIPallocBufferArray( scip, &a, dim));
		SCIP_CALL( SCIPallocBufferArray( scip, &b, dim-1));
		SCIP_CALL( SCIPallocBufferArray( scip, &c, dim-1));
		SCIP_CALL( SCIPallocBufferArray( scip, &v, dim-1));
		SCIP_CALL( SCIPallocBufferArray( scip, &V_, (dim-1)*(dim-1)));
		SCIP_CALL( SCIPallocBufferArray( scip, &Z_, (dim)*(dim)));
		SCIP_CALL( SCIPallocBufferArray( scip, &W_, (dim)*(dim)));
		
		for(i=0; i<p; i++){
			/*
			 * 1. b <- X^t x_i
			 * 2.	c <- Y b
			 * 3. d <- - X c + x_i
			 * 4. u <- 1 / <x_i, d> 
			 * 5. v <- - u c
			 * 6. V <- Y + u c c^t
			 * 7. Z <- ( V    v
			 	          v^t  u )
			 * 8. a_new <- Z (Xy)
			 */

			if( list[i]==0 ){

				/* 1. b <- X^t x_i */
				dgemv_t( X_, n, dim-1, &orig_X_[n * i], b);
				//printv( dim-1, b);

				/* 2. c <- Y b */
				dgemv_2( Y_, dim-1, dim-1, b, c);
				//printv( dim-1, c);

				/* 3. d <- - X c + x_i */
				dgemv_1( X_, n, dim-1, c, &orig_X_[n * i], -1.0, 1.0, d);
				//printv( n, d);

				/* 4. u <- 1/<x_i, d> */
				u = 1.0 / myddot_( &orig_X_[n * i], d, n);
				//prints(u);
				
				/* 5. v <- - u c */
				mydscal_( c, dim-1, -u, v);
				//printv( dim-1, v);

				/* 6. V <- Y + u c c^t */
				dger_1( Y_, c, c, dim-1, dim-1, u, V_);
				//printM_( V_, dim-1, dim-1);

				/* 7. Z */
				/* V */
				for(j=0; j<(dim-1); j++){
					for(t=0; t<(dim-1); t++){
						*(Z_ + j + (t*dim) ) = mat_( V_, dim-1, j, t);
					}
				}
				/* v */
				for(j=0; j<(dim-1); j++){
					*(Z_ + dim-1 + (j*dim) )  = v[j];
					*(Z_ + j + ((dim-1)*dim)) = v[j];
				}

				/* u */
				*(Z_ + dim-1 + ((dim-1)*dim)) = u;
				//printM_( Z_, dim, dim);

				/* 8. a_new <- Z (Xy) */
				Xy[dim-1] = orig_q[i];
				dgemv_2( Z_, dim, dim, Xy, a_new);
				//printv( dim, a_new);

				/* test */
				RSS_new = RSSvalue( dim, a_new, Xy, r);
				if( RSS_new < RSS ){
					RSS = RSS_new;
					memo = i;
					mydcopy_( Z_, W_, dim*dim);
					mydcopy_( a_new, a, dim);
				}

#if MYPARA_LOG
				printf("%d: RSS = %f\n", i, RSS_new);
#endif

			}
		}

		if( memo < 0 || memo >= p ){
			if( memo == -1 ){
				for(i=0; i<p; i++){
					if( list[i] == 0 ){
						memo = i;
						break;
					}
				}
				if( memo != -1 ){
					printf("error in heur_forward.c\n");
					stop();
				}
			}else{
				printf("error in heur_forward.c\n");
				stop();
			}
		}

		AIC_new = AICvalue( n, dim, RSS);
		if( AIC_new < AIC ){
			AIC = AIC_new;
			list[memo] = dim;

#if MYPARA_LOG
			printf("---> %dth variable, AIC:%f\n", memo, AIC);
#endif

			/* copy and free */
			SCIPfreeBufferArray(scip, &Y_);
			SCIP_CALL( SCIPallocBufferArray(scip, &Y_, dim*dim));
			mydcopy_( W_, Y_, dim*dim);

			SCIPfreeBufferArray(scip, &a_old);
			SCIP_CALL( SCIPallocBufferArray(scip, &a_old, dim));
			mydcopy_( a, a_old, dim);

			/* update X_ and Xy */
			mydcopy_( &orig_X_[n * memo], &X_[n * (dim-1)], n);
			Xy[dim-1] = orig_q[memo];

		}else{
			memo = -1;
			SCIPfreeBufferArray(scip, Y_);
#if MYPARA_LOG
			printf("--> no selection, (AIC:%f)\n", AIC_new);
#endif
		}

		/* free */
		SCIPfreeBufferArray(scip, &a_new);
		SCIPfreeBufferArray(scip, &a);
		SCIPfreeBufferArray(scip, &b);
		SCIPfreeBufferArray(scip, &c);
		SCIPfreeBufferArray(scip, &v);
		SCIPfreeBufferArray(scip, &V_);
		SCIPfreeBufferArray(scip, &Z_);
		SCIPfreeBufferArray(scip, &W_);

		if( memo == -1 ){
			dim--;
			break;
		}
	}

	nsols = SCIPgetNSols(scip);
	
	if( nsols < MP_NUM_SOL ){
		store = 1;
	}else{
		sols = SCIPgetSols(scip);
		objval = AIC;
		nsols = MP_NUM_SOL;

		if( objval < SCIPgetSolOrigObj(scip,sols[nsols-1]) ){
			store = 1;
		}else{
			store = 0;
		}
	}

	if( store ){
		/*  generate solution  */
		/* alloc */
		SCIP_CALL( SCIPallocBufferArray(scip, &ep, n));
		dgemv_1( X_, n, dim, a_old, y, -1.0, 1.0, ep);
		
	
		/* set solution */
		/* alloc */
		SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars));
		SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars));
	
		ct=0;
		
		/* a */
		for(i=0; i<p; ++i){
			vars[ct] = var_a[i];
			if( list[i] > 0 ){
				solvals[ct] = a_old[list[i]-1];
			}else{
				solvals[ct] = 0.0;
			}
			ct++;
		}
	
		/* z */
		for(i=0; i<p; i++){
			vars[ct] = var_z[i];
			if( list[i] > 0 ){
				solvals[ct] = 1.0;
			}else{
				solvals[ct] = 0.0;
			}
			ct++;
		}
	
		/* ep */
		for(i=0; i<n; ++i){
			vars[ct]		=	var_ep[i];
			solvals[ct]	=	ep[i];
			ct++;
		}
	
		vars[ct]		=	var_rss;
		solvals[ct] =	myddot_( ep, ep, n);
		ct++;
	
		vars[ct]		=	var_log;
		solvals[ct]	=	log(myddot_( ep, ep, n));
		ct++;
	
		if( ct!=nvars ){
			SCIPerrorMessage("It is unexpected error in set sol,");
			printf("( ct, nvars) = ( %d, %d)", ct, nvars);
			stop();
		}
	
		SCIP_CALL( SCIPcreateSol(scip, &sol, heur));
		SCIP_CALL( SCIPsetSolVals(scip, sol, nvars, vars, solvals));
		SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, FALSE, TRUE, TRUE, &success));

		/* free */
		SCIPfreeBufferArray(scip, &ep);
		SCIPfreeBufferArray(scip, &solvals);
		SCIPfreeBufferArray(scip, &vars);
	}

	/* free */
	SCIPfreeBufferArray(scip, &d);
	SCIPfreeBufferArray(scip, &X_);
	SCIPfreeBufferArray(scip, &Xy);
	SCIPfreeBufferArray(scip, &a_old);
	SCIPfreeBufferArray(scip, &list);
	SCIPfreeBufferArray(scip, &Branchz);

	*result = SCIP_FOUNDSOL;
   return SCIP_OKAY;
}