Пример #1
0
void RestorationProblem::evaluate( const Matrix &xi, const Matrix &lambda,
                                   double *objval, Matrix &constr,
                                   Matrix &gradObj, double *&jacNz, int *&jacIndRow, int *&jacIndCol,
                                   SymMatrix *&hess, int dmode, int *info )
{
    int iCon, i;
    double diff, regTerm;
    Matrix xiOrig, slack;

    // The first nVar elements of the variable vector correspond to the variables of the original problem
    xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 );
    slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 );

    // Evaluate constraints of the original problem
    parent->evaluate( xiOrig, lambda, objval, constr,
                      gradObj, jacNz, jacIndRow, jacIndCol, hess, dmode, info );

    // Subtract slacks
    for( iCon=0; iCon<nCon; iCon++ )
        constr( iCon ) -= slack( iCon );


    /* Evaluate objective: minimize slacks plus deviation from reference point */
    if( dmode < 0 )
        return;

    *objval = 0.0;

    // First part: sum of slack variables
    for( i=0; i<nCon; i++ )
        *objval += slack( i ) * slack( i );
    *objval = 0.5 * rho * (*objval);

    // Second part: regularization term
    regTerm = 0.0;
    for( i=0; i<parent->nVar; i++ )
    {
        diff = xiOrig( i ) - xiRef( i );
        regTerm += diagScale( i ) * diff * diff;
    }
    regTerm = 0.5 * zeta * regTerm;
    *objval += regTerm;

    if( dmode > 0 )
    {// compute objective gradient

        // gradient w.r.t. xi (regularization term)
        for( i=0; i<parent->nVar; i++ )
            gradObj( i ) = zeta * diagScale( i ) * diagScale( i ) * (xiOrig( i ) - xiRef( i ));

        // gradient w.r.t. slack variables
        for( i=parent->nVar; i<nVar; i++ )
            gradObj( i ) = rho * xi( i );
    }

    *info = 0;
}
Пример #2
0
void RestorationProblem::initialize( Matrix &xi, Matrix &lambda, Matrix &constrJac )
{
    int i, info;
    double objval;
    Matrix xiOrig, slack, constrJacOrig, constrRef;

    xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 );
    slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 );
    constrJacOrig.Submatrix( constrJac, parent->nCon, parent->nVar, 0, 0 );

    // Call initialize of the parent problem to set up linear constraint matrix correctly
    parent->initialize( xiOrig, lambda, constrJacOrig );

    // Jacobian entries for slacks
    for( i=0; i<parent->nCon; i++ )
        constrJac( i, parent->nVar+i ) = -1.0;

    // The reference point is the starting value for the restoration phase
    for( i=0; i<parent->nVar; i++ )
        xiOrig( i ) = xiRef( i );

    // Initialize slack variables such that the constraints are feasible
    constrRef.Dimension( nCon );
    parent->evaluate( xiOrig, &objval, constrRef, &info );

    for( i=0; i<nCon; i++ )
    {
        if( constrRef( i ) <= parent->bl( parent->nVar + i ) )// if lower bound is violated
            slack( i ) = constrRef( i ) - parent->bl( parent->nVar + i );
        else if( constrRef( i ) > parent->bu( parent->nVar + i ) )// if upper bound is violated
            slack( i ) = constrRef( i ) - parent->bu( parent->nVar + i );
    }

    // Set diagonal scaling matrix
    diagScale.Dimension( parent->nVar ).Initialize( 1.0 );
    for( i=0; i<parent->nVar; i++ )
        if( fabs( xiRef( i ) ) > 1.0 )
            diagScale( i ) = 1.0 / fabs( xiRef( i ) );

    // Regularization factor zeta and rho \todo wie setzen?
    zeta = 1.0e-3;
    rho = 1.0e3;

    lambda.Initialize( 0.0 );
}
Пример #3
0
bool Constraint::violated(Active<Variable, Constraint> *variables,
							  double *x,
							  double *sl) const
{
	double s = slack(variables, x);

	if (sl) *sl = s;

	return violated(s);
}
Пример #4
0
bool ACPI::append(const char *sig, const char *extra, const uint32_t extra_len)
{
	// check if enough space to append
	acpi_sdt *table = find_child(sig, rsdt, 4);

	if (!table || slack(table) < extra_len)
		return 0;

	memcpy((char *)table + table->len, extra, extra_len);
	table->len += extra_len;
	table->checksum += checksum((const char *)table, table->len);

	if (options->debug.acpi)
		dump(table, 0);

	return 1;
}
Пример #5
0
void ACPI::add_child(const acpi_sdt *replacement, acpi_sdt *const parent, const unsigned ptrsize)
{
	// if insufficient space, replace unimportant tables
	if (slack(parent) < ptrsize) {
		const char *expendable[] = {"FPDT", "EINJ", "TCPA", "BERT", "ERST", "HEST"};
		for (unsigned i = 0; i < (sizeof expendable / sizeof expendable[0]); i++) {
			if (replace_child(expendable[i], replacement, parent, ptrsize)) {
				printf("Replaced %s table\n", expendable[i]);
				return;
			}
		}

		fatal("Out of space when adding entry for ACPI table %s to %s", replacement->sig.s, parent->sig.s);
	}

	assert_checksum(replacement, replacement->len);
	uint64_t newp = 0;
	memcpy(&newp, &replacement, sizeof replacement);
	unsigned i = parent->len - sizeof(*parent);
	memcpy(&parent->data[i], &newp, ptrsize);
	if (memcmp(&parent->data[i], &newp, ptrsize))
		goto again;

	parent->len += ptrsize;
	xassert(parent->len < RSDT_MAX);
	parent->checksum += checksum((const char *)parent, parent->len);
	return;

again:
	if (!bios_shadowed) {
		shadow_bios();
		add_child(replacement, parent, ptrsize);
		return;
	}

	fatal("ACPI tables immutable when adding child at 0x%p", &parent->data[i]);
}
Пример #6
0
// Test KKT conditions on the solution.
// The function returns true if the tested KKT conditions are satisfied
// and false otherwise.
// The function assumes that the model currently extracted to CPLEX is fully
// described by obj, vars and rngs.
static bool
checkkkt (IloCplex& cplex, IloObjective const& obj, IloNumVarArray const& vars,
          IloRangeArray const& rngs, IloIntArray const& cone, double tol)
{
   IloEnv env = cplex.getEnv();
   IloModel model = cplex.getModel();
   IloNumArray x(env), dslack(env);
   IloNumArray pi(env, rngs.getSize()), slack(env);

   // Read primal and dual solution information.
   cplex.getValues(x, vars);
   cplex.getSlacks(slack, rngs);

   // pi for second order cone constraints.
   getsocpconstrmultipliers(cplex, vars, rngs, pi, dslack);

   // pi for linear constraints.
   for (IloInt i = 0; i < rngs.getSize(); ++i) {
      IloRange r = rngs[i];
      if ( !r.getQuadIterator().ok() )
         pi[idx(r)] = cplex.getDual(r);
   }

   // Print out the data we just fetched.
   streamsize oprec = env.out().precision(3);
   ios_base::fmtflags oflags = env.out().setf(ios::fixed | ios::showpos);
   env.out() << "x      = [";
   for (IloInt i = 0; i < x.getSize(); ++i)
      env.out() << " " << x[i];
   env.out() << " ]" << endl;
   env.out() << "dslack = [";
   for (IloInt i = 0; i < dslack.getSize(); ++i)
      env.out() << " " << dslack[i];
   env.out() << " ]" << endl;
   env.out() << "pi     = [";
   for (IloInt i = 0; i < rngs.getSize(); ++i)
      env.out() << " " << pi[i];
   env.out() << " ]" << endl;
   env.out() << "slack  = [";
   for (IloInt i = 0; i < rngs.getSize(); ++i)
      env.out() << " " << slack[i];
   env.out() << " ]" << endl;
   env.out().precision(oprec);
   env.out().flags(oflags);

   // Test primal feasibility.
   // This example illustrates the use of dual vectors returned by CPLEX
   // to verify dual feasibility, so we do not test primal feasibility
   // here.

   // Test dual feasibility.
   // We must have
   // - for all <= constraints the respective pi value is non-negative,
   // - for all >= constraints the respective pi value is non-positive,
   // - the dslack value for all non-cone variables must be non-negative.
   // Note that we do not support ranged constraints here.
   for (IloInt i = 0; i < vars.getSize(); ++i) {
      IloNumVar v = vars[i];
      if ( cone[i] == NOT_IN_CONE && dslack[i] < -tol ) {
         env.error() << "Dual multiplier for " << v << " is not feasible: "
                     << dslack[i] << endl;
         return false;
      }
   }
   for (IloInt i = 0; i < rngs.getSize(); ++i) {
      IloRange r = rngs[i];
      if ( fabs (r.getLB() - r.getUB()) <= tol ) {
         // Nothing to check for equality constraints.
      }
      else if ( r.getLB() > -IloInfinity && pi[i] > tol ) {
         env.error() << "Dual multiplier " << pi[i] << " for >= constraint"
                     << endl << r << endl
                     << "not feasible"
                     << endl;
         return false;
      }
      else if ( r.getUB() < IloInfinity && pi[i] < -tol ) {
         env.error() << "Dual multiplier " << pi[i] << " for <= constraint"
                     << endl << r << endl
                     << "not feasible"
                     << endl;
         return false;
      }
   }

   // Test complementary slackness.
   // For each constraint either the constraint must have zero slack or
   // the dual multiplier for the constraint must be 0. We must also
   // consider the special case in which a variable is not explicitly
   // contained in a second order cone constraint.
   for (IloInt i = 0; i < vars.getSize(); ++i) {
      if ( cone[i] == NOT_IN_CONE ) {
         if ( fabs(x[i]) > tol && dslack[i] > tol ) {
            env.error() << "Invalid complementary slackness for " << vars[i]
                        << ":" << endl
                        << " " << x[i] << " and " << dslack[i]
                        << endl;
            return false;
         }
      }
   }
   for (IloInt i = 0; i < rngs.getSize(); ++i) {
      if ( fabs(slack[i]) > tol && fabs(pi[i]) > tol ) {
         env.error() << "Invalid complementary slackness for "
                     << endl << rngs[i] << ":" << endl
                     << " " << slack[i] << " and " << pi[i]
                     << endl;
         return false;
      }
   }

   // Test stationarity.
   // We must have
   //  c - g[i]'(X)*pi[i] = 0
   // where c is the objective function, g[i] is the i-th constraint of the
   // problem, g[i]'(x) is the derivate of g[i] with respect to x and X is the
   // optimal solution.
   // We need to distinguish the following cases:
   // - linear constraints g(x) = ax - b. The derivative of such a
   //   constraint is g'(x) = a.
   // - second order constraints g(x[1],...,x[n]) = -x[1] + |(x[2],...,x[n])|
   //   the derivative of such a constraint is
   //     g'(x) = (-1, x[2]/|(x[2],...,x[n])|, ..., x[n]/|(x[2],...,x[n])|
   //   (here |.| denotes the Euclidean norm).
   // - bound constraints g(x) = -x for variables that are not explicitly
   //   contained in any second order cone constraint. The derivative for
   //   such a constraint is g'(x) = -1.
   // Note that it may happen that the derivative of a second order cone
   // constraint is not defined at the optimal solution X (this happens if
   // X=0). In this case we just skip the stationarity test.
   IloNumArray sum(env, vars.getSize());
   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      sum[idx(it.getVar())] = it.getCoef();

   for (IloInt i = 0; i < vars.getSize(); ++i) {
      IloNumVar v = vars[i];
      if ( cone[i] == NOT_IN_CONE )
         sum[i] -= dslack[i];
   }
   for (IloInt i = 0; i < rngs.getSize(); ++i) {
      IloRange r = rngs[i];
      if ( r.getQuadIterator().ok() ) {
         // Quadratic (second order cone) constraint.
         IloNum norm = 0.0;
         for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) {
            if ( q.getCoef() > 0 )
               norm += x[idx(q.getVar1())] * x[idx(q.getVar1())];
         }
         norm = sqrt(norm);
         if ( fabs(norm) <= tol ) {
            // Derivative is not defined. Skip test.
            env.warning() << "Cannot test stationarity at non-differentiable point."
                          << endl;
            return true;
         }
         else {
            for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) {
               if ( q.getCoef() < 0 )
                  sum[idx(q.getVar1())] -= pi[i];
               else
                  sum[idx(q.getVar1())] += pi[i] * x[idx(q.getVar1())] / norm;
            }
         }
      }
      else {
         // Linear constraint.
         for (IloExpr::LinearIterator l = r.getLinearIterator(); l.ok(); ++l)
            sum[idx(l.getVar())] -= pi[i] * l.getCoef();
      }
   }

   // Now test that all elements in sum[] are 0.
   for (IloInt i = 0; i < vars.getSize(); ++i) {
      if ( fabs(sum[i]) > tol ) {
         env.error() << "Invalid stationarity " << sum[i] << " for "
                     << vars[i] << endl;
         return false;
      }
   }

   return true;   
}
Пример #7
0
double TriConstraint::slackAtInitial () const
{
    return slack(u->initialPos(scanDim), v->initialPos(scanDim),
            w->initialPos(scanDim));
}
Пример #8
0
double TriConstraint::slackAtFinal() const {
    return 
        slack(u->finalPos(), 
              v->finalPos(), 
              w->finalPos());
}
Пример #9
0
bool Hungarian::solve()
{
	int i, j, m, n, k, l, s, t, q, unmatched, cost;

	m = m_rows;
	n = m_cols;

	int INF = std::numeric_limits<int>::max();

	//vertex alternating paths,
	vector<int> col_vertex(m), row_vertex(n), unchosen_row(m), parent_row(n),
				row_dec(m),  col_inc(n),  slack_row(m),    slack(n);

	cost=0;

	for (i=0;i<m_rows;i++) 
	{
		col_vertex[i]=0;
		unchosen_row[i]=0;
		row_dec[i]=0;
		slack_row[i]=0;
	}

	for (j=0;j<m_cols;j++) 
	{
		row_vertex[j]=0;
		parent_row[j] = 0;
		col_inc[j]=0;
		slack[j]=0;
	}

	//Double check assignment matrix is 0
	m_assignment.assign(m, vector<int>(n, HUNGARIAN_NOT_ASSIGNED));

  // Begin subtract column minima in order to start with lots of zeroes 12
	if (verbose)
	{
		fprintf(stderr, "Using heuristic\n");
	}

	for (l=0;l<n;l++)
	{
		s = m_costmatrix[0][l];

		for (k=1;k<m;k++) 
		{
			if (m_costmatrix[k][l] < s)
			{
				s=m_costmatrix[k][l];
			}
			cost += s;
		}

		if (s!=0)
		{
			for (k=0;k<m;k++)
			{
				m_costmatrix[k][l]-=s;
			}
		}

		//pre-initialize state 16
		row_vertex[l]= -1;
		parent_row[l]= -1;
		col_inc[l]=0;
		slack[l]=INF;
	}
  // End subtract column minima in order to start with lots of zeroes 12

  // Begin initial state 16
	t=0;

	for (k=0;k<m;k++)
	{
		bool row_done = false;
		s=m_costmatrix[k][0];

		for (l=0;l<n;l++)
		{

			if(l > 0)
			{
				if (m_costmatrix[k][l] < s)
				{
					s = m_costmatrix[k][l];
				}
				row_dec[k]=s;
			}

			if (s == m_costmatrix[k][l] && row_vertex[l]<0)
				{
					col_vertex[k]=l;
					row_vertex[l]=k;

					if (verbose)
					{
						fprintf(stderr, "matching col %d==row %d\n",l,k);
					}
					row_done = true;
					break;
				}
		}

		if(!row_done)
		{
			col_vertex[k]= -1;

			if (verbose)
			{
				fprintf(stderr, "node %d: unmatched row %d\n",t,k);
			}
		
			unchosen_row[t++]=k;
		}

	}
  // End initial state 16

	bool checked = false;

  // Begin Hungarian algorithm 18

	//is matching already complete?
	if (t == 0)
	{
		checked = check_solution(row_dec, col_inc, col_vertex);
		if (checked)
		{
			//finish assignment, wrap up and done.
			bool assign = assign_solution(row_dec, col_inc, col_vertex);
			return true;
		}
		else
		{
			if(verbose)
			{
				fprintf(stderr, "Could not solve. Error.\n");
			}
			return false;
		}
	}

	unmatched=t;


	while (1)
	{
		if (verbose)
		{
			fprintf(stderr, "Matched %d rows.\n",m-t);
		}
		q=0;
		bool try_matching;
		while (1)
		{
			while (q<t)
			{
			// Begin explore node q of the forest 19
				
				k=unchosen_row[q];
				s=row_dec[k];
				for (l=0;l<n;l++)
				{
					if (slack[l])
					{
						int del;
						del=m_costmatrix[k][l]-s+col_inc[l];
						if (del<slack[l])
						{
							if (del==0)
							{
								if (row_vertex[l]<0)
								{
									goto breakthru;
								}
								slack[l]=0;
								parent_row[l]=k;
								if (verbose){
									fprintf(stderr, "node %d: row %d==col %d--row %d\n",
										t,row_vertex[l],l,k);}
								unchosen_row[t++]=row_vertex[l];
							}
							else
							{
								slack[l]=del;
								slack_row[l]=k;
							}
						}
					}
				}
			// End explore node q of the forest 19
				q++;	
			}
 
	  // Begin introduce a new zero into the matrix 21
		s=INF;
		for (l=0;l<n;l++)
		{
			if (slack[l] && slack[l]<s)
			{
				s=slack[l];
			}
		}
		for (q=0;q<t;q++)
		{
			row_dec[unchosen_row[q]]+=s;
		}
		for (l=0;l<n;l++)
		{
			//check slack
			if (slack[l])
			{
				slack[l]-=s;
				if (slack[l]==0)
				{
					// Begin look at a new zero 22
					k=slack_row[l];
					if (verbose)
					{
						fprintf(stderr, 
						"Decreasing uncovered elements by %d produces zero at [%d,%d]\n",
						s,k,l);
					}
					if (row_vertex[l]<0)
					{
						for (j=l+1;j<n;j++)
							if (slack[j]==0)
							{
								col_inc[j]+=s;
							}

						goto breakthru;
					}
					else
					{
						parent_row[l]=k;
						if (verbose)
							{ fprintf(stderr, "node %d: row %d==col %d--row %d\n",t,row_vertex[l],l,k);}
						unchosen_row[t++]=row_vertex[l];
						
					}
		// End look at a new zero 22
				}
			}
			else
			{
				col_inc[l]+=s;
			}
		}
	// End introduce a new zero into the matrix 21
	}

    breakthru:
      // Begin update the matching 20
		if (verbose)
		{
			fprintf(stderr, "Breakthrough at node %d of %d!\n",q,t);
		}
		while (1)
		{
			j=col_vertex[k];
			col_vertex[k]=l;
			row_vertex[l]=k;
			if (verbose)
			{
				fprintf(stderr, "rematching col %d==row %d\n",l,k);
			}
			if (j<0)
			{
				break;
			}
			k=parent_row[j];
			l=j;
		}
		// End update the matching 20
		if (--unmatched == 0)
		{
			checked = check_solution(row_dec, col_inc, col_vertex);
			if (checked)
			{
				//finish assignment, wrap up and done.
				bool assign = assign_solution(row_dec, col_inc, col_vertex);
				return true;
			}
			else
			{
				if(verbose)
				{
					fprintf(stderr, "Could not solve. Error.\n");
				}
				return false;
			}
		}
		
		// Begin get ready for another stage 17
			t=0;
			for (l=0;l<n;l++)
			{
				parent_row[l]= -1;
				slack[l]=INF;
			}
			for (k=0;k<m;k++)
			{
				if (col_vertex[k]<0)
				{
					if (verbose)
					{ fprintf(stderr, "node %d: unmatched row %d\n",t,k);}
					unchosen_row[t++]=k;
				}
			}
		// End get ready for another stage 17
	}// back to while loop


}
Пример #10
0
void RestorationProblem::initialize( Matrix &xi, Matrix &lambda, double *&jacNz, int *&jacIndRow, int *&jacIndCol )
{
    int i, info;
    double objval;
    Matrix xiOrig, slack, constrRef;

    xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 );
    slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 );

    // Call initialize of the parent problem. There, the sparse Jacobian is allocated
    double *jacNzOrig = NULL;
    int *jacIndRowOrig = NULL, *jacIndColOrig = NULL, nnz, nnzOrig;
    parent->initialize( xiOrig, lambda, jacNzOrig, jacIndRowOrig, jacIndColOrig );
    nnzOrig = jacIndColOrig[parent->nVar];

    // Copy sparse Jacobian from original problem
    nnz = nnzOrig + nCon;
    jacNz = new double[nnz];
    jacIndRow = new int[nnz + (nVar+1)];
    jacIndCol = jacIndRow + nnz;
    for( i=0; i<nnzOrig; i++ )
    {
        jacNz[i] = jacNzOrig[i];
        jacIndRow[i] = jacIndRowOrig[i];
    }
    for( i=0; i<parent->nVar; i++ )
        jacIndCol[i] = jacIndColOrig[i];

    // Jacobian entries for slacks (one nonzero entry per column)
    for( i=nnzOrig; i<nnz; i++ )
    {
        jacNz[i] = -1.0;
        jacIndRow[i] = i-nnzOrig;
    }
    for( i=parent->nVar; i<nVar+1; i++ )
        jacIndCol[i] = nnzOrig + i - parent->nVar;

    // The reference point is the starting value for the restoration phase
    for( i=0; i<parent->nVar; i++ )
        xiOrig( i ) = xiRef( i );

    // Initialize slack variables such that the constraints are feasible
    constrRef.Dimension( nCon );
    parent->evaluate( xiOrig, &objval, constrRef, &info );

    for( i=0; i<nCon; i++ )
    {
        if( constrRef( i ) <= parent->bl( parent->nVar + i ) )// if lower bound is violated
            slack( i ) = constrRef( i ) - parent->bl( parent->nVar + i );
        else if( constrRef( i ) > parent->bu( parent->nVar + i ) )// if upper bound is violated
            slack( i ) = constrRef( i ) - parent->bu( parent->nVar + i );
    }

    // Set diagonal scaling matrix
    diagScale.Dimension( parent->nVar ).Initialize( 1.0 );
    for( i=0; i<parent->nVar; i++ )
        if( fabs( xiRef( i ) ) > 1.0 )
            diagScale( i ) = 1.0 / fabs( xiRef( i ) );

    // Regularization factor zeta and rho \todo wie setzen?
    zeta = 1.0e-3;
    rho = 1.0e3;

    lambda.Initialize( 0.0 );
}
Пример #11
0
int
main (int argc, char **argv)
{
   int result = 0;
   IloEnv env;

   try {
      static int indices[] = { 0, 1, 2, 3, 4, 5, 6 };
      IloModel model(env);

      /* ***************************************************************** *
       *                                                                   *
       *    S E T U P   P R O B L E M                                      *
       *                                                                   *
       *  The model we setup here is                                       *
       * Minimize                                                          *
       *  obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7                       *
       * Subject To                                                        *
       *  c1: x1 + x2 = 4                                                  *
       *  c2: x1 + x3 >= 3                                                 *
       *  c3: x6 + x7 <= 5                                                 *
       *  c4: -x1 + x7 >= -2                                               *
       *  q1: [ -x1^2 + x2^2 ] <= 0                                        *
       *  q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2  ] + 2 x1 <= 9.0
       *  q3: [ x6^2 - x7^2 ] >= 4                                         *
       * Bounds                                                            *
       *  0 <= x1 <= 3                                                     *
       *  x2 Free                                                          *
       *  0 <= x3 <= 0.5                                                   *
       *  x4 Free                                                          *
       *  x5 Free                                                          *
       *  x7 Free                                                          *
       * End                                                               *
       *                                                                   *
       * ***************************************************************** */

      IloNumVarArray x(env);
      x.add(IloNumVar(env, 0, 3, "x1"));
      x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x2"));
      x.add(IloNumVar(env, 0, 0.5, "x3"));
      x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x4"));
      x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x5"));
      x.add(IloNumVar(env, 0, IloInfinity, "x6"));
      x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x7"));
      for (IloInt i = 0; i < x.getSize(); ++i)
         x[i].setObject(&indices[i]);

      IloObjective obj = IloMinimize(env,
                                     3*x[0] - x[1] + 3*x[2] + 2*x[3] +
                                     x[4] + 2*x[5] + 4*x[6], "obj");
      model.add(obj);

      IloRangeArray linear(env);
      linear.add(IloRange(env, 4.0, x[0] + x[1], 4.0, "c1"));
      linear.add(IloRange(env, 3.0, x[0] + x[2], IloInfinity, "c2"));
      linear.add(IloRange(env, -IloInfinity, x[5] + x[6], 5.0, "c3"));
      linear.add(IloRange(env, -2.0, -x[0] + x[6], IloInfinity, "c4"));
      for (IloInt i = 0; i < linear.getSize(); ++i)
         linear[i].setObject(&indices[i]);
      model.add(linear);

      IloRangeArray quad(env);
      quad.add(IloRange(env, -IloInfinity, -x[0]*x[0] + x[1] * x[1], 0, "q1"));
      quad.add(IloRange(env, -IloInfinity,
                        4.25*x[2]*x[2] - 2*x[2]*x[3] + 4.25*x[3]*x[3] +
                        -2*x[3]*x[4] + 4*x[4]*x[4] + 2*x[0],
                        9.0, "q2"));
      quad.add(IloRange(env, 4.0, x[5]*x[5] - x[6]*x[6], IloInfinity, "q3"));
      for (IloInt i = 0; i < quad.getSize(); ++i)
         quad[i].setObject(&indices[i]);
      model.add(quad);

      /* ***************************************************************** *
       *                                                                   *
       *    O P T I M I Z E   P R O B L E M                                *
       *                                                                   *
       * ***************************************************************** */
      IloCplex cplex(model);
      cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, 1e-10);
      cplex.solve();

      /* ***************************************************************** *
       *                                                                   *
       *    Q U E R Y   S O L U T I O N                                    *
       *                                                                   *
       * ***************************************************************** */
      IloNumArray xval(env);
      IloNumArray slack(env);
      IloNumArray qslack(env);
      IloNumArray cpi(env);
      IloNumArray rpi(env);
      IloNumArray qpi;
      cplex.getValues(x, xval);
      cplex.getSlacks(slack, linear);
      cplex.getSlacks(qslack, quad);
      cplex.getReducedCosts(cpi, x);
      cplex.getDuals(rpi, linear);
      qpi = getqconstrmultipliers(cplex, xval, quad);

      
      /* ***************************************************************** *
       *                                                                   *
       *    C H E C K   K K T   C O N D I T I O N S                        *
       *                                                                   *
       *    Here we verify that the optimal solution computed by CPLEX     *
       *    (and the qpi[] values computed above) satisfy the KKT          *
       *    conditions.                                                    *
       *                                                                   *
       * ***************************************************************** */

      // Primal feasibility: This example is about duals so we skip this test.

      // Dual feasibility: We must verify
      // - for <= constraints (linear or quadratic) the dual
      //   multiplier is non-positive.
      // - for >= constraints (linear or quadratic) the dual
      //   multiplier is non-negative.
      for (IloInt i = 0; i < linear.getSize(); ++i) {
         if ( linear[i].getLB() <= -IloInfinity ) {
            // <= constraint
            if ( rpi[i] > ZEROTOL ) {
               cerr << "Dual feasibility test failed for <= row " << i
                    << ": " << rpi[i] << endl;
               result = -1;
            }
         }
         else if ( linear[i].getUB() >= IloInfinity ) {
            // >= constraint
            if ( rpi[i] < -ZEROTOL ) {
               cerr << "Dual feasibility test failed for >= row " << i
                    << ":" << rpi[i] << endl;
               result = -1;
            }
         }
         else {
            // nothing to do for equality constraints
         }
      }
      for (IloInt q = 0; q < quad.getSize(); ++q) {
         if ( quad[q].getLB() <= -IloInfinity ) {
            // <= constraint
            if ( qpi[q] > ZEROTOL ) {
               cerr << "Dual feasibility test failed for <= quad " << q
                    << ": " << qpi[q] << endl;
               result = -1;
            }
         }
         else if ( quad[q].getUB() >= IloInfinity ) {
            // >= constraint
            if ( qpi[q] < -ZEROTOL ) {
               cerr << "Dual feasibility test failed for >= quad " << q
                    << ":" << qpi[q] << endl;
               result = -1;
            }
         }
         else {
            // nothing to do for equality constraints
         }
      }

      // Complementary slackness.
      // For any constraint the product of primal slack and dual multiplier
      // must be 0.
      for (IloInt i = 0; i < linear.getSize(); ++i) {
         if ( fabs (linear[i].getUB() - linear[i].getLB()) > ZEROTOL &&
              fabs (slack[i] * rpi[i]) > ZEROTOL )
         {
            cerr << "Complementary slackness test failed for row " << i
                 << ": " << fabs (slack[i] * rpi[i]) << endl;
            result = -1;
         }
      }
      for (IloInt q = 0; q < quad.getSize(); ++q) {
         if ( fabs (quad[q].getUB() - quad[q].getLB()) > ZEROTOL &&
              fabs (qslack[q] * qpi[q]) > ZEROTOL )
         {
            cerr << "Complementary slackness test failed for quad " << q
                 << ":" << fabs (qslack[q] * qpi[q]) << endl;
            result = -1;
         }
      }
      for (IloInt j = 0; j < x.getSize(); ++j) {
         if ( x[j].getUB() < IloInfinity ) {
            double const slk = x[j].getUB() - xval[j];
            double const dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0;
            if ( fabs (slk * dual) > ZEROTOL ) {
               cerr << "Complementary slackness test failed for ub " << j
                    << ": " << fabs (slk * dual) << endl;
               result = -1;
            }
         }
         if ( x[j].getLB() > -IloInfinity ) {
            double const slk = xval[j] - x[j].getLB();
            double const dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0;
            if ( fabs (slk * dual) > ZEROTOL ) {
               cerr << "Complementary slackness test failed for lb " << j
                    << ": " << fabs (slk * dual) << endl;
               result = -1;
            }
         }
      }

      // Stationarity.
      // The difference between objective function and gradient at optimal
      // solution multiplied by dual multipliers must be 0, i.e., for the
      // optimal solution x
      // 0 == c
      //      - sum(r in rows)  r'(x)*rpi[r]
      //      - sum(q in quads) q'(x)*qpi[q]
      //      - sum(c in cols)  b'(x)*cpi[c]
      // where r' and q' are the derivatives of a row or quadratic constraint,
      // x is the optimal solution and rpi[r] and qpi[q] are the dual
      // multipliers for row r and quadratic constraint q.
      // b' is the derivative of a bound constraint and cpi[c] the dual bound
      // multiplier for column c.
      IloNumArray kktsum(env, x.getSize());

      // Objective function.
      for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
         kktsum[idx(it.getVar())] = it.getCoef();

      // Linear constraints.
      // The derivative of a linear constraint ax - b (<)= 0 is just a.
      for (IloInt i = 0; i < linear.getSize(); ++i) {
         for (IloExpr::LinearIterator it = linear[i].getLinearIterator();
              it.ok(); ++it)
            kktsum[idx(it.getVar())] -= rpi[i] * it.getCoef();
      }

      // Quadratic constraints.
      // The derivative of a constraint xQx + ax - b <= 0 is
      // Qx + Q'x + a.
      for (IloInt q = 0; q < quad.getSize(); ++q) {
         for (IloExpr::LinearIterator it = quad[q].getLinearIterator();
              it.ok(); ++it)
            kktsum[idx(it.getVar())] -= qpi[q] * it.getCoef();

         for (IloExpr::QuadIterator it = quad[q].getQuadIterator();
              it.ok(); ++it)
         {
            kktsum[idx(it.getVar1())] -= qpi[q] * xval[idx(it.getVar2())] * it.getCoef();
            kktsum[idx(it.getVar2())] -= qpi[q] * xval[idx(it.getVar1())] * it.getCoef();
         }
      }

      // Bounds.
      // The derivative for lower bounds is -1 and that for upper bounds
      // is 1.
      // CPLEX already returns dj with the appropriate sign so there is
      // no need to distinguish between different bound types here.
      for (IloInt j = 0; j < x.getSize(); ++j)
         kktsum[j] -= cpi[j];

      for (IloInt j = 0; j < kktsum.getSize(); ++j) {
         if ( fabs (kktsum[j]) > ZEROTOL ) {
            cerr << "Stationarity test failed at index " << j
                 << ": " << kktsum[j] << endl;
            result = -1;
         }
      }

      if ( result == 0) {
         // KKT conditions satisfied. Dump out the optimal solutions and
         // the dual values.
         streamsize oprec = cout.precision(3);
         ios_base::fmtflags oflags = cout.setf(ios::fixed | ios::showpos);
         cout << "Optimal solution satisfies KKT conditions." << endl;
         cout << "   x[] = " << xval << endl;
         cout << " cpi[] = " << cpi << endl;
         cout << " rpi[] = " << rpi << endl;
         cout << " qpi[] = " << qpi << endl;
         cout.precision(oprec);
         cout.flags(oflags);
      }
   }
   catch (IloException& e) {
      cerr << "Concert exception caught: " << e << endl;
      result = -1;
   }
   catch (...) {
      cerr << "Unknown exception caught" << endl;
      result = -1;
   }

   env.end();

   return result;
}  // END main
Пример #12
0
bool ACPI::replace_child(const char *sig, const acpi_sdt *replacement, acpi_sdt *const parent, const unsigned ptrsize)
{
	uint64_t newp = 0, childp;

	assert_checksum(replacement, replacement->len);
	memcpy(&newp, &replacement, sizeof(replacement));
	unsigned i;

	for (i = 0; i + sizeof(*parent) < parent->len; i += ptrsize) {
		childp = 0;
		memcpy(&childp, &parent->data[i], ptrsize);

		if (childp > 0xffffffffULL) {
			printf("Error: Child pointer at %d (%p) outside 32-bit range (0x%" PRIx64 ")",
			       i, &parent->data[i], childp);
			continue;
		}

		acpi_sdt *table;
		memcpy(&table, &childp, sizeof(table));
		assert_checksum(table, table->len);

		// DSDT is special-cased
		if (table->sig.l == STR_DW_H("FACP") && !strncmp(sig, "DSDT", 4)) {
			struct acpi_fadt *fadt = (struct acpi_fadt *)&table->data;
			fadt->Dsdt = (uint32_t)replacement;
			if (ptrsize == 8)
				fadt->X_Dsdt = (uint64_t)replacement;
			table->checksum = 0;
			table->checksum = checksum((const char *)table, table->len);
			return 1;
		}

		if (table->sig.l == STR_DW_H(sig)) {
			memcpy(&parent->data[i], &newp, ptrsize);
			// check if writing succeeded
			if (memcmp(&parent->data[i], &newp, ptrsize))
				goto again;

			parent->checksum += checksum((const char *)parent, parent->len);
			return 1;
		}
	}

	// handled by caller
	if (slack(parent) < ptrsize)
		return 0;

	// append entry to end of table
	memcpy(&parent->data[i], &newp, ptrsize);

	// check if writing succeeded
	if (memcmp(&parent->data[i], &newp, ptrsize))
		goto again;

	parent->len += ptrsize;
	xassert(parent->len < RSDT_MAX);
	parent->checksum += checksum((const char *)parent, parent->len);
	return 1;

again:
	if (!bios_shadowed) {
		shadow_bios();
		return replace_child(sig, replacement, parent, ptrsize);
	}

	fatal("ACPI tables immutable when replacing child at 0x%p", &parent->data[i]);
}