// Old implementation of first derivative of basis functions DenseVector BSplineBasis1D::evaluateFirstDerivative(double x) const { DenseVector values; values.setZero(numBasisFunctions()); supportHack(x); std::vector<int> supportedBasisFunctions = indexSupportedBasisfunctions(x); for(int i : supportedBasisFunctions) { // Differentiate basis function // Equation 3.35 in Lyche & Moerken (2011) double b1 = deBoorCox(x, i, degree-1); double b2 = deBoorCox(x, i+1, degree-1); double t11 = knots.at(i); double t12 = knots.at(i+degree); double t21 = knots.at(i+1); double t22 = knots.at(i+degree+1); (t12 == t11) ? b1 = 0 : b1 = b1/(t12-t11); (t22 == t21) ? b2 = 0 : b2 = b2/(t22-t21); values(i) = degree*(b1 - b2); } return values; }
DenseVector BilinearRelaxationTest::bilinearFunction(DenseVector x) { assert(x.rows() == 2); DenseVector y; y.setZero(1); y(0) = x(0)*x(1); return y; }
DenseVector Michalewicz::michalewiczFunction(DenseVector x) { assert(x.rows() == 2); double pi = atan(1)*4; DenseVector y; y.setZero(1); y(0) = -sin(x(0))*pow(sin(x(0)*x(0)/pi), 20) -sin(x(1))*pow(sin(2*x(1)*x(1)/pi), 20); return y; }
void POP03::runProblem() { // Problem 3 (Nataraj) // cout << "\n\nSolving problem P03..." << endl; int dim = 4; // x1,x2,l1,l2 std::vector<double> costs = {1, 0, 0, 0}; std::vector<double> lb = {-10,-10,0,-1000}; std::vector<double> ub = {10,10,100,1000}; std::vector<double> z0(dim,0); std::vector<VariablePtr> vars; for (int i = 0; i < dim; i++) { auto var = std::make_shared<Variable>(costs.at(i), lb.at(i), ub.at(i)); vars.push_back(var); } ConstraintSetPtr cs = std::make_shared<ConstraintSet>(); { // x1^2 = l1 VariablePtr var = vars.at(0); std::vector<double> thislb = {var->getLowerBound()}; std::vector<double> thisub = {var->getUpperBound()}; std::vector<unsigned int> deg = {2}; DenseVector c(3); c.setZero(); c(0) = 0; c(1) = 0; c(2) = 1; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs.transpose(), knots, deg); std::vector<VariablePtr> cvars = {var, vars.at(2)}; ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // x1^3 = l1 VariablePtr var = vars.at(0); std::vector<double> thislb = {var->getLowerBound()}; std::vector<double> thisub = {var->getUpperBound()}; std::vector<unsigned int> deg = {3}; DenseVector c(4); c.setZero(); c(0) = 0; c(1) = 0; c(2) = 0; c(3) = 1; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs.transpose(), knots, deg); std::vector<VariablePtr> cvars = {var, vars.at(3)}; ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // x2 - l1 <= 0, x2 - l2 <= 0 DenseMatrix A(2,3); A.setZero(); A(0,0) = -1; A(0,1) = 1; A(1,0) = 1; A(1,1) = 2; A(1,2) = -1; DenseVector b; b.setZero(2); b(1) = -1e-5; std::vector<VariablePtr> cvars = { vars.at(1), vars.at(2), vars.at(3) }; ConstraintPtr lincon = std::make_shared<ConstraintLinear>(cvars, A, b, false); cs->add(lincon); } BB::BranchAndBound bnb(cs); Timer timer; timer.start(); SolverResult res = bnb.optimize(); timer.stop(); cout << "Time: " << timer.getMilliSeconds() << " (ms)" << endl; if (res.status == SolverStatus::OPTIMAL) fopt_found = res.objectiveValue; }
void BilinearRelaxationTest::runProblem() { std::vector<double> cost, lb, ub, z0; cost.push_back(0); cost.push_back(0); cost.push_back(1); lb.push_back(-1.); lb.push_back(-1.); lb.push_back(-INF); ub.push_back(1); ub.push_back(2.5); ub.push_back(INF); z0.push_back(1); z0.push_back(-0.5); z0.push_back(-0.5); std::vector<VariablePtr> vars; for (unsigned int i = 0; i < 3; i++) { auto var = std::make_shared<Variable>(cost.at(i), lb.at(i), ub.at(i)); var->setValue(z0.at(i)); vars.push_back(var); } // Constraints ConstraintSetPtr constraints = std::make_shared<ConstraintSet>(); ConstraintPtr myBilinearConstraint = std::make_shared<ConstraintBilinear>(vars,1,0,0); constraints->add(myBilinearConstraint); DataTable data; double dx = 0.5; for (double x1 = lb.at(0); x1 <= ub.at(0); x1+=dx) { for (double x2 = lb.at(1); x2 <= ub.at(1); x2+=dx) { std::vector<double> x; x.push_back(x1); x.push_back(x2); DenseVector xd; xd.setZero(2); xd(0) = x1; xd(1) = x2; DenseVector yd = bilinearFunction(xd); data.addSample(x,yd(0)); } } ConstraintSetPtr constraints2 = std::make_shared<ConstraintSet>(); BSpline bs = BSpline::Builder(data).degree(3).build(); ConstraintPtr cbspline = std::make_shared<ConstraintBSpline>(vars, bs, true); constraints2->add(cbspline); // Test accuracy of B-spline // DenseVector (*foo)(DenseVector); // foo = &bilinearFunction; // BSpline* bs = new BSpline(*data, 3); // bool testpassed = bs->testBspline(foo); // if (testpassed) // { // cout << "B-spline is very accurate:)" << endl; // } // else // { // cout << "B-spline is NOT very accurate:(" << endl; // } BB::BranchAndBound solver(constraints); //SolverIpopt solver(constraints); SolverResult res = solver.optimize(); cout << res << endl; zopt_found = res.primalVariables; fopt_found = res.objectiveValue; }
void POP06::runProblem() { // Problem 6 (Nataraj) // 5 2-D B-splines int dim = 4+2; // x1,x2,x3,x4,l1,l2 std::vector<double> costs = {0, 0, 0, 0, 1, 0}; std::vector<double> lb = {1,0.625,47.5,90,-INF,-INF}; std::vector<double> ub = {1.1375,1,52.5,112,INF,INF}; std::vector<double> z0(dim,0); // x1,x2,x3,x4,l1,l2,l3,l4,l5 // std::vector<double> lb = {1,0.625,47.5,90,-INF,-INF,-INF,-INF,-INF}; // std::vector<double> ub = {1.1375,1,52.5,112,INF,INF,INF,INF,INF}; std::vector<VariablePtr> vars; for (int i = 0; i < dim; i++) { auto var = std::make_shared<Variable>(costs.at(i), lb.at(i), ub.at(i)); vars.push_back(var); } ConstraintSetPtr cs = std::make_shared<ConstraintSet>(); { // obj = l1 std::vector<VariablePtr> cvars = { vars.at(0), vars.at(1), vars.at(2), vars.at(3), vars.at(4) }; std::vector<double> thislb = { cvars.at(0)->getLowerBound(), cvars.at(1)->getLowerBound(), cvars.at(2)->getLowerBound(), cvars.at(3)->getLowerBound() }; std::vector<double> thisub = { cvars.at(0)->getUpperBound(), cvars.at(1)->getUpperBound(), cvars.at(2)->getUpperBound(), cvars.at(3)->getUpperBound() }; std::vector<unsigned int> deg = {2,1,2,1}; // Poly coeffs DenseVector c(4); c.setZero(); c(0) = 0.6224; c(1) = 1.7781; c(2) = 3.1661; c(3) = 19.84; // Poly exponents DenseMatrix E(4,4); E.setZero(); E(0,2) = 1; E(0,3) = 1; E(1,1) = 1; E(1,2) = 2; E(2,0) = 2; E(2,3) = 1; E(3,0) = 2; E(3,2) = 1; DenseMatrix coeffs = getBSplineBasisCoefficients(c, E, thislb, thisub); std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs, knots, deg); ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); //DenseMatrix cpoints = bs.getControlPoints(); //cout << cpoints << endl; } { // noncon = l2 std::vector<VariablePtr> cvars = { vars.at(2), vars.at(3), vars.at(5) }; std::vector<double> thislb = { cvars.at(0)->getLowerBound(), cvars.at(1)->getLowerBound() }; std::vector<double> thisub = { cvars.at(0)->getUpperBound(), cvars.at(1)->getUpperBound() }; std::vector<unsigned int> deg = {3,1}; // Poly coeffs DenseVector c(2); c.setZero(); c(0) = -1; c(1) = -(4.0/3.0); // Poly exponents DenseMatrix E(2,2); E.setZero(); E(0,0) = 2; E(0,1) = 1; E(1,0) = 3; DenseMatrix coeffs = getBSplineBasisCoefficients(c, E, thislb, thisub); std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs, knots, deg); ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // Linear constraints of auxiliary variables DenseMatrix A(4,6); A.setZero(); A(0,0) = -1; A(0,2) = 0.0193; A(1,1) = -1; A(1,2) = 0.00954; A(2,5) = 1; A(3,3) = 1; DenseVector b; b.setZero(4); b(2) = -750.1728/3.14159265359; b(3) = 240; ConstraintPtr lincon = std::make_shared<ConstraintLinear>(vars, A, b, false); cs->add(lincon); } BB::BranchAndBound bnb(cs); Timer timer; timer.start(); SolverResult res = bnb.optimize(); timer.stop(); cout << "Time: " << timer.getMilliSeconds() << " (ms)" << endl; cout << "Time: " << timer.getMicroSeconds() << " (us)" << endl; //1 0.625 47.5 90 6395.50783 -345958.333 if (res.status == SolverStatus::OPTIMAL) fopt_found = res.objectiveValue; }
void POP10::runProblem() { // Problem 10 (Nataraj), QP // Five 1-D B-splines cout << "\n\nSolving problem P10..." << endl; int dim = 6+5; // x1,..,x5,y,l1,...,l5 // x1,x2,x3,x4,l1,l2,l3 std::vector<double> costs = {0,0,0,0,0,-10,1,1,1,1,1}; std::vector<double> lb = {0,0,0,0,0,0,-INF,-INF,-INF,-INF,-INF}; std::vector<double> ub = {1,1,1,1,1,INF,INF,INF,INF,INF,INF}; std::vector<double> z0(dim,0); std::vector<VariablePtr> vars; for (int i = 0; i < dim; i++) { auto var = std::make_shared<Variable>(costs.at(i), lb.at(i), ub.at(i)); vars.push_back(var); } ConstraintSetPtr cs = std::make_shared<ConstraintSet>(); std::vector<double> a = {-10.5,-7.5,-3.5,-2.5,-1.5}; // Add one B-spline for each variable for (int i = 0; i < 5; i++) { std::vector<VariablePtr> cvars = { vars.at(i), vars.at(i+6) }; std::vector<double> thislb = {cvars.at(0)->getLowerBound()}; std::vector<double> thisub = {cvars.at(0)->getUpperBound()}; std::vector<unsigned int> deg = {2}; // Poly coeffs DenseVector c(3); c.setZero(); c(0) = 0; c(1) = a.at(i); c(2) = -0.5; // -50 or -0.5 (Floudas' problem has -50) DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs.transpose(), knots, deg); ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // Linear constraints std::vector<VariablePtr> cvars = { vars.at(0), vars.at(1), vars.at(2), vars.at(3), vars.at(4), vars.at(5) }; DenseMatrix A = DenseMatrix::Zero(2,6); A(0,0) = 6; A(0,1) = 3; A(0,2) = 3; A(0,3) = 2; A(0,4) = 1; A(1,0) = 10; A(1,2) = 10; A(1,5) = 1; DenseVector b; b.setZero(2); b(0) = 6.5; b(1) = 20; ConstraintPtr lincon = std::make_shared<ConstraintLinear>(cvars, A, b, false); cs->add(lincon); } BB::BranchAndBound bnb(cs); Timer timer; timer.start(); SolverResult res = bnb.optimize(); timer.stop(); cout << "Time: " << timer.getMilliSeconds() << " (ms)" << endl; cout << "Time: " << timer.getMicroSeconds() << " (us)" << endl; if (res.status == SolverStatus::OPTIMAL) fopt_found = res.objectiveValue; }
void POP01::runProblem() { // Problem 1 (Nataraj) // cout << "\n\nSolving problem P01..." << endl; int dim = 4; // x1,x2,l1,l2 std::vector<double> costs = {-1, -1, 0, 0}; std::vector<double> lb = {0,0,-INF,-INF}; std::vector<double> ub = {3,4,INF,INF}; //std::vector<double> z0(dim,0); std::vector<VariablePtr> vars; for (int i = 0; i < dim; i++) { auto var = std::make_shared<Variable>(costs.at(i), lb.at(i), ub.at(i)); vars.push_back(var); } ConstraintSetPtr cs = std::make_shared<ConstraintSet>(); { // 2*x1^4 - 8*x1^3 + 8*x1^2 + 2 std::vector<VariablePtr> cvars = {vars.at(0), vars.at(2)}; std::vector<double> thislb = {cvars.at(0)->getLowerBound()}; std::vector<double> thisub = {cvars.at(0)->getUpperBound()}; std::vector<unsigned int> deg = {4}; DenseVector c(5); c.setZero(); c(0) = 2; c(1) = 0; c(2) = 8; c(3) = -8; c(4) = 2; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs, knots, deg); ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // 4*x1^4 - 32*x1^3 + 88*x1^2 - 96*x1 + 36 std::vector<VariablePtr> cvars = {vars.at(0), vars.at(3)}; std::vector<double> thislb = {cvars.at(0)->getLowerBound()}; std::vector<double> thisub = {cvars.at(0)->getUpperBound()}; std::vector<unsigned int> deg = {4}; DenseVector c(5); c.setZero(); c(0) = 36; c(1) = -96; c(2) = 88; c(3) = -32; c(4) = 4; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs, knots, deg); ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // x2 - l1 <= 0, x2 - l2 <= 0 std::vector<VariablePtr> cvars = { vars.at(1), vars.at(2), vars.at(3) }; DenseMatrix A(2,3); A.setZero(); A(0,0) = 1; A(0,1) = -1; A(1,0) = 1; A(1,2) = -1; DenseVector b; b.setZero(2); ConstraintPtr lincon = std::make_shared<ConstraintLinear>(cvars, A, b, false); cs->add(lincon); } BB::BranchAndBound solver(cs); Timer timer; timer.start(); SolverResult res = solver.optimize(); timer.stop(); cout << res << endl; cout << res.primalVariables << endl; cout << "Time: " << timer.getMilliSeconds() << " (ms)" << endl; if (res.status == SolverStatus::OPTIMAL) fopt_found = res.objectiveValue; }