Exemple #1
0
    /** 
     * Create a function from an expression.
     * @param expr :: The input expression
     * @param parentAttributes :: An output map filled with the attribute name & values of the parent function
     * @return A pointer to the created function
     */
    IFunction_sptr FunctionFactoryImpl::createSimple(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const
    {
      if (expr.name() == "=" && expr.size() > 1)
      {
        return createFunction(expr.terms()[1].name());
      }

      if (expr.name() != "," || expr.size() == 0)
      {
        inputError(expr.str());
      }

      const std::vector<Expression>& terms = expr.terms();
      std::vector<Expression>::const_iterator term = terms.begin();

      if (term->name() != "=") inputError(expr.str());
      if (term->terms()[0].name() != "name" && term->terms()[0].name() != "composite")
      {
        throw std::invalid_argument("Function name must be defined before its parameters");
      }
      std::string fnName = term->terms()[1].name();

      IFunction_sptr fun = createFunction(fnName);
      for(++term;term!=terms.end();++term)
      {// loop over function's parameters/attributes
        if (term->name() != "=") inputError(expr.str());
        std::string parName = term->terms()[0].name();
        std::string parValue = term->terms()[1].str();
        if (fun->hasAttribute(parName))
        {// set attribute
          if (parValue.size() > 1 && parValue[0] == '"')
          {// remove the double quotes
            parValue = parValue.substr(1,parValue.size()-2);
          }
          IFunction::Attribute att = fun->getAttribute(parName);
          att.fromString(parValue);
          fun->setAttribute(parName,att);
        }
        else if (parName.size() >= 10 && parName.substr(0,10) == "constraint")
        {// or it can be a list of constraints
          addConstraints(fun,(*term)[1]);
        }
        else if (parName == "ties")
        {
          addTies(fun,(*term)[1]);
        }
        else if (!parName.empty() && parName[0] == '$')
        {
          parName.erase(0,1);
          parentAttributes[parName] = parValue;
        }
        else
        {// set initial parameter value
          fun->setParameter(parName,atof(parValue.c_str()));
        }
      }// for term

      fun->applyTies();
      return fun;
    }
Exemple #2
0
    /**
      * Create a fitting function from an expression.
      * @param expr :: The input expression made by parsing the input string to createFitFunction(const std::string& input)
      */
    IFitFunction* FunctionFactoryImpl::createFitFunction(const Expression& expr) const
    {
      const Expression& e = expr.bracketsRemoved();

      std::string fnName = e.name();

      IFitFunction* fun = createUnwrapped(fnName);
      if (!fun)
      {
        throw std::runtime_error("Cannot create function "+fnName);
      }
      fun->initialize();

      const std::vector<Expression>& terms = e.terms();
      std::vector<Expression>::const_iterator term = terms.begin();

      for(;term!=terms.end();++term)
      {// loop over function's parameters/attributes
        if (term->name() == "=")
        {
          std::string parName = term->terms()[0].name();
          std::string parValue = term->terms()[1].str();
          if (fun->hasAttribute(parName))
          {// set attribute
            if (parValue.size() > 1 && parValue[0] == '"')
            {// remove the double quotes
              parValue = parValue.substr(1,parValue.size()-2);
            }
            IFitFunction::Attribute att = fun->getAttribute(parName);
            att.fromString(parValue);
            fun->setAttribute(parName,att);
          }
          else if (parName.size() >= 10 && parName.substr(0,10) == "constraint")
          {// or it can be a list of constraints
            addConstraints(fun,(*term)[1]);
          }
          else if (parName == "ties")
          {
            addTies(fun,(*term)[1]);
          }
          else
          {// set initial parameter value
            fun->setParameter(parName,atof(parValue.c_str()));
          }
        }
        else // if the term isn't a name=value pair it could be a member function of a composite function
        {
          throw Kernel::Exception::NotImplementedError("Composite functions are not implemented yet for IFitFunction");
          //CompositeFunction* cfun = dynamic_cast<CompositeFunction*>(fun);
          //if (!cfun)
          //{
          //  throw std::runtime_error("Cannot add a function to a non-composite function "+fnName);
          //}
          //IFitFunction* mem = createFitFunction(*term);
          //cfun->addFunction(mem);
        }
      }// for term

      return fun;
    }
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion
(
    const dictionary& dict,
    const dictionary& stateDict
)
:
    motionState_(stateDict),
    motionState0_(),
    restraints_(),
    constraints_(),
    tConstraints_(tensor::I),
    rConstraints_(tensor::I),
    initialCentreOfMass_
    (
        dict.lookupOrDefault
        (
            "initialCentreOfMass",
            vector(dict.lookup("centreOfMass"))
        )
    ),
    initialCentreOfRotation_(initialCentreOfMass_),
    initialQ_
    (
        dict.lookupOrDefault
        (
            "initialOrientation",
            dict.lookupOrDefault("orientation", tensor::I)
        )
    ),
    mass_(readScalar(dict.lookup("mass"))),
    momentOfInertia_(dict.lookup("momentOfInertia")),
    aRelax_(dict.lookupOrDefault<scalar>("accelerationRelaxation", 1.0)),
    aDamp_(dict.lookupOrDefault<scalar>("accelerationDamping", 1.0)),
    report_(dict.lookupOrDefault<Switch>("report", false)),
    solver_(sixDoFSolver::New(dict.subDict("solver"), *this))
{
    addRestraints(dict);

    // Set constraints and initial centre of rotation
    // if different to the centre of mass
    addConstraints(dict);

    // If the centres of mass and rotation are different ...
    vector R(initialCentreOfMass_ - initialCentreOfRotation_);
    if (magSqr(R) > VSMALL)
    {
        // ... correct the moment of inertia tensor using parallel axes theorem
        momentOfInertia_ += mass_*diag(I*magSqr(R) - sqr(R));

        // ... and if the centre of rotation is not specified for motion state
        // update it
        if (!stateDict.found("centreOfRotation"))
        {
            motionState_.centreOfRotation() = initialCentreOfRotation_;
        }
    }

    // Save the old-time motion state
    motionState0_ = motionState_;
}
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion(const dictionary& dict)
    :
    motionState_(dict),
    restraints_(),
    restraintNames_(),
    constraints_(),
    constraintNames_(),
    maxConstraintIterations_(0),
    initialCentreOfMass_
    (
       dict.lookupOrDefault("initialCentreOfMass", centreOfMass())
    ),
    initialQ_
    (
       dict.lookupOrDefault("initialOrientation", Q())
    ),
    momentOfInertia_(dict.lookup("momentOfInertia")),
    mass_(readScalar(dict.lookup("mass"))),
    cDamp_(dict.lookupOrDefault<scalar>("accelerationDampingCoeff", 0.0)),
    aLim_(dict.lookupOrDefault<scalar>("accelerationLimit", VGREAT)),
    report_(dict.lookupOrDefault<Switch>("report", false))
{
    addRestraints(dict);

    addConstraints(dict);
}
void HtmlHeaderMetadataItemVisitor::visitTable(Table& /*table*/)
{
    emptyTitles();
    addSummary();
    addConstraints();
    addIndices();
    addTriggers();
    addPrivileges();
    addDependencies();
    addDDL();
}
static Matrix optimizeWithDerivative(float& bestCost, const NeuralNetwork* network,
	const Matrix& initialData, unsigned int neuron)
{
	auto input     = network->convertToBlockSparseForLayerInput(network->front(), initialData);
	auto reference = network->convertToBlockSparseForLayerOutput(network->back(),
		generateReferenceForNeuron(network, neuron));
	
	auto data = network->createBackPropagation();
	
	data->setInput(&input);
	data->setReferenceOutput(&reference);
	
	auto bestSoFar = input;
	     bestCost  = data->computeInputCost();
	
	std::string solverType = util::KnobDatabase::getKnobValue(
		"NeuronVisualizer::SolverType", "GradientDescentSolver");

	auto solver = optimizer::GeneralDifferentiableSolverFactory::create(solverType);
	
	assert(solver != nullptr);

	addConstraints(solver);
	
	util::log("NeuronVisualizer") << " Initial inputs are   : " << initialData.toString();
	util::log("NeuronVisualizer") << " Initial reference is : " << generateReferenceForNeuron(network, neuron).toString();
	util::log("NeuronVisualizer") << " Initial output is    : " << network->runInputs(initialData).toString();
	util::log("NeuronVisualizer") << " Initial cost is      : " << bestCost << "\n";
	
	try
	{
		CostAndGradientFunction costAndGradient(data, bestCost, 0.000002f);
	
		bestCost = solver->solve(bestSoFar, costAndGradient);
	}
	catch(...)
	{
		util::log("NeuronVisualizer") << "  solver produced an error.\n";
		delete solver;
		delete data;
		throw;
	}
	
	delete solver;
	delete data;
	
	util::log("NeuronVisualizer") << "  solver produced new cost: "
		<< bestCost << ".\n";
	util::log("NeuronVisualizer") << "  final input is : " << bestSoFar.toString();
	util::log("NeuronVisualizer") << "  final output is : " << network->runInputs(bestSoFar).toString();
	return bestSoFar.toMatrix();
}
Exemple #7
0
main(int argc, char* argv[])
{
  typedef GOFactory < FT > Fact;
  typedef WTraverse < Fact > Traverse;
  typedef BNBSeqSolver < Traverse > Solver;
  int n = N;
  FT z[n];
  F f(n);
  GOInitialData<FT> id;
  SegVecDecomp<Fact> decomp;
  LipzGradDiscarder<FT> dscg;
  dscg.setName("Objective");
  
  
  SimpleConstraintChecker<FT> scheck;
  Fact fact;
  
  init(n, &f, id);
  fact.setInitialData(&id);
  addConstraints(n, scheck, fact, id);
  fact.setConstraintChecker(&scheck);
  
  dscg.setEps(EPS);
  dscg.setInitialData(&id);
//  dscg.getDebugOptions() |= LipzGradDiscarder<FT>::DebugOptions::PRINT_BOUNDS;
  dscg.setObjective(&f);
  dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::CHECK_GRAD;
  dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::CHECK_GRAD_COMP;
  dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::UPDATE_RECORD;
  dscg.getOptions() |= LipzGradDiscarder<FT>::Options::DO_PRIMARY_BALL_CUT;

  fact.addDiscarder(&dscg);
  fact.addDiscarder(&decomp);
  //fact.getDebugOptions() |= Fact::DebugOptions::DO_DEBUG;
  Solver solver(&fact);
  solver.setDebugOptions(
                         Solver::Options::PRINT_RESULTING_STAT 
//        | Solver::Options::PRINT_STATE
                        );
  //solver.Traverse::setDebugOptions(Traverse::Options::PRINT_STEP);
//   solver.setDebugOptions(Solver::Options::PRINT_RESULTING_STAT | Solver::Options::PRINT_INITIAL_VAL);
  //solver.setRecord(n - 1);
  solver.solve();  
  if(solver.getSolutionContainer()->empty())
    printf("Empty container\n");
  printf("Minimum = %s\n", solver.getSolutionContainer()->top().toString().c_str());
}
//-----------------------------------------------------------------------
void Triangulator::triangulate(const Shape& shape, std::vector<int>& output)
{
	// Do the Delaunay triangulation
	PointList pl = shape.getPoints();
	DelaunayTriangleBuffer dtb;
	delaunay(pl, dtb);
	
	addConstraints(shape, dtb);
	
	//Outputs index buffer	
	for (DelaunayTriangleBuffer::iterator it = dtb.begin(); it!=dtb.end();it++)
	{
		output.push_back(it->i[0]);
		output.push_back(it->i[1]);
		output.push_back(it->i[2]);
	}
}
Exemple #9
0
/**
 * Create and connect actions
 */
void FunctionBrowser::createActions()
{
  m_actionAddFunction = new QAction("Add function",this);
  connect(m_actionAddFunction,SIGNAL(triggered()),this,SLOT(addFunction()));

  m_actionRemoveFunction = new QAction("Remove function",this);
  connect(m_actionRemoveFunction,SIGNAL(triggered()),this,SLOT(removeFunction()));

  m_actionFixParameter = new QAction("Fix",this);
  connect(m_actionFixParameter,SIGNAL(triggered()),this,SLOT(fixParameter()));

  m_actionRemoveTie = new QAction("Remove tie",this);
  connect(m_actionRemoveTie,SIGNAL(triggered()),this,SLOT(removeTie()));

  m_actionAddTie = new QAction("Add tie",this);
  connect(m_actionAddTie,SIGNAL(triggered()),this,SLOT(addTie()));

  m_actionFromClipboard = new QAction("Copy from clipboard",this);
  connect(m_actionFromClipboard,SIGNAL(triggered()),this,SLOT(copyFromClipboard()));

  m_actionToClipboard = new QAction("Copy to clipboard",this);
  connect(m_actionToClipboard,SIGNAL(triggered()),this,SLOT(copyToClipboard()));

  m_actionConstraints = new QAction("Custom",this);
  connect(m_actionConstraints,SIGNAL(triggered()),this,SLOT(addConstraints()));

  m_actionConstraints10 = new QAction("10%",this);
  connect(m_actionConstraints10,SIGNAL(triggered()),this,SLOT(addConstraints10()));

  m_actionConstraints50 = new QAction("50%",this);
  connect(m_actionConstraints50,SIGNAL(triggered()),this,SLOT(addConstraints50()));

  m_actionRemoveConstraints = new QAction("Remove constraints",this);
  connect(m_actionRemoveConstraints,SIGNAL(triggered()),this,SLOT(removeConstraints()));

  m_actionRemoveConstraint = new QAction("Remove",this);
  connect(m_actionRemoveConstraint,SIGNAL(triggered()),this,SLOT(removeConstraint()));
}
Exemple #10
0
    /** 
     * Create a function from an expression.
     * @param expr :: The input expression
     * @return A pointer to the created function
     */
    IFitFunction* FunctionFactoryImpl::createSimple(const Expression& expr)const
    {
      if (expr.name() == "=" && expr.size() > 1)
      {
        return createFunction(expr.terms()[1].name());
      }

      if (expr.name() != "," || expr.size() == 0)
      {
        inputError(expr.str());
      }

      const std::vector<Expression>& terms = expr.terms();
      std::vector<Expression>::const_iterator term = terms.begin();

      if (term->name() != "=") inputError(expr.str());
      if (term->terms()[0].name() != "name" && term->terms()[0].name() != "composite")
      {
        throw std::invalid_argument("Function name must be defined before its parameters");
      }
      std::string fnName = term->terms()[1].name();

      IFitFunction* fun = createFunction(fnName);
      std::string wsName,wsParam;
      for(++term;term!=terms.end();++term)
      {// loop over function's parameters/attributes
        if (term->name() != "=") inputError(expr.str());
        std::string parName = term->terms()[0].name();
        std::string parValue = term->terms()[1].str();
        if (fun->hasAttribute(parName))
        {// set attribute
          if (parValue.size() > 1 && parValue[0] == '"')
          {// remove the double quotes
            parValue = parValue.substr(1,parValue.size()-2);
          }
          IFitFunction::Attribute att = fun->getAttribute(parName);
          att.fromString(parValue);
          fun->setAttribute(parName,att);
        }
        else if (parName.size() >= 10 && parName.substr(0,10) == "constraint")
        {// or it can be a list of constraints
          addConstraints(fun,(*term)[1]);
        }
        else if (parName == "ties")
        {
          addTies(fun,(*term)[1]);
        }
        else if (parName == "Workspace")
        {
          wsName = parValue;
        }
        else if (parName == "WSParam")
        {
          wsParam = parValue;
        }
        else
        {// set initial parameter value
          fun->setParameter(parName,atof(parValue.c_str()));
        }
      }// for term

      if (!wsName.empty())
      {
        Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName);
        fun->setWorkspace(ws,wsParam);
      }

      return fun;
    }
Exemple #11
0
    /** 
     * Create a composite function from an expression.
     * @param expr :: The input expression
     * @return A pointer to the created function
     */
    CompositeFunction* FunctionFactoryImpl::createComposite(const Expression& expr)const
    {
      if (expr.name() != ";") inputError(expr.str());

      if (expr.size() == 0)
      {
        return 0;
      }

      const std::vector<Expression>& terms = expr.terms();
      std::vector<Expression>::const_iterator it = terms.begin();
      const Expression& term = it->bracketsRemoved();

      CompositeFunction* cfun = 0;
      std::string wsName,wsParam;
      if (term.name() == "=")
      {
        if (term.terms()[0].name() == "composite")
        {
          cfun = dynamic_cast<CompositeFunction*>(createFunction(term.terms()[1].name()));
          if (!cfun) inputError(expr.str());
          ++it;
        }
        else if (term.terms()[0].name() == "name")
        {
          cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW"));
          if (!cfun) inputError(expr.str());
        }
        else
        {
          inputError(expr.str());
        }
      }
      else if (term.name() == ",")
      {
        std::vector<Expression>::const_iterator firstTerm = term.terms().begin();
        if (firstTerm->name() == "=")
        {
          if (firstTerm->terms()[0].name() == "composite")
          {
            cfun = dynamic_cast<CompositeFunction*>(createSimple(term));
            if (!cfun) inputError(expr.str());
            ++it;
          }
          else if (firstTerm->terms()[0].name() == "name")
          {
            cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW"));
            if (!cfun) inputError(expr.str());
          }
          else
          {
            inputError(expr.str());
          }
        }
      }
      else if (term.name() == ";")
      {
        cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW"));
        if (!cfun) inputError(expr.str());
      }
      else
      {
        inputError(expr.str());
      }

      for(;it!=terms.end();++it)
      {
        const Expression& term = it->bracketsRemoved();
        IFitFunction* fun = NULL;
        if (term.name() == ";")
        {
          fun = createComposite(term);
          if (!fun) continue;
        }
        else
        {
          std::string parName = term[0].name();
          std::string parValue = term[1].str();
          if (term[0].name().size() >= 10 && term[0].name().substr(0,10) == "constraint")
          {
            addConstraints(cfun,term[1]);
            continue;
          }
          else if (term[0].name() == "ties")
          {
            addTies(cfun,term[1]);
            continue;
          }
          else if (parName == "Workspace")
          {
            wsName = parValue;
          }
          else if (parName == "WSParam")
          {
            wsParam = parValue;
          }
          else
          {
            fun = createSimple(term);
          }
        }
        cfun->addFunction(fun);
      }

      if (!wsName.empty())
      {
        Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName);
        cfun->setWorkspace(ws,wsParam);
      }

      return cfun;
    }
Exemple #12
0
LPP* MorpionLPP::getLPP()
{
    setComment(gameId());

    // each possible move is a structural variable
    // our goal is to maximize sum over all variables

    for (const Move& m: b.getMoveList()) {        
        std::string v_name = to_string(m);

        setVariableBounds(v_name, 0.0, 1.0);
        getObjective().push_back(std::pair<std::string, double>(v_name, 1.0));
        
        // Constraint for exact problems.
        //
        //   mv_ variables are either 0 or 1 (i.e. the move is either played or not)

        if (getFlag("exact") || getFlag("binary_moves")) {
            setVariableBoolean(v_name, true);
        }
    }

    // each segment gives us constraints:
    // (1) if the segment is placed in the starting position
    //    (a) sum of weights of moves that place this segment <= 0
    //    (b) 1 - sum of weights of moves that remove this segment >= 0
    //        i.e. sum of weights of moves that remove this segment <= 1
    // (2) if the segment is not placed in the starting position
    //    (a) sum of weights of moves that place this segment <= 1
    //    (b) sum of weights of moves that place this segment
    //          - sum of weights of moves that remove this segment >= 0
            
    for (const Segment& s: b.getSegmentList()) {
        int x = s.first.x;
        int y = s.first.y;
        int d = s.second;

        std::string constr_name = "segment_" + to_string(x) + "_" + to_string(y) + "_" + to_string(d);

        if (b.hasDot(Dot(x,y))) {
            // (1a)
            {
                Constraint constr;
        
                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                constr.setName("r1a_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(0.0);
                addConstraint(constr);
            }
            // (1b)
            {
                Constraint constr;
        
                for (Move& rm: b.getMovesRemovingSegment(s)) {
                    constr.addVariable(to_string(rm), 1.0);
                }
                constr.setName("r1b_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(1.0);
                addConstraint(constr);
            }                        
        } else {
            // (2a)
            {
                Constraint constr;
        
                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                constr.setName("r2a_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(1.0);
                addConstraint(constr);
            }
            // (2b)
            {
                Constraint constr;

                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                for (Move& rm: b.getMovesRemovingSegment(s)) {
                    constr.addVariable(to_string(rm), -1.0);
                }
                constr.setName("r2b_" + constr_name);
                constr.setType(Constraint::GT);
                constr.setBound(0.0);      
                    
                addConstraint(constr);          
            }
        }        
    }

    // EXTRA CONSTRAINTS:
    //
    // for each move m:
    //   for each dot d required by m:
    //     for each move n placing d that is consistent with m:
    //       weight_m <= sum of weights of n's

    if (getFlag("extra")) {
        for (const Move& m: b.getMoveList()) {
            std::string constr_name = "_" + to_string(m);
        
            for (const Dot& d: m.requiredDots(b.getVariant())) {
                if (b.hasDot(d)) continue;
                
                Constraint constr;
                
                for (const Move& n: b.getMovesPlacingSegment(Segment(d,0))) {
                    if (m.consistentWith(n,b.getVariant())) {
                        constr.addVariable(to_string(n), -1.0);
                    }
                }
                constr.addVariable(to_string(m), 1.0);
                
                constr.setName("extra_" + to_string(d) + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(0.0);
                
                addConstraint(constr);
            }
        }
    }
    
    // Disallow cycles of length 3 from the solution.
    // Improves fuzzy solutions
    
    if (getFlag("short-cycles")) {         
        for (const Segment& s: b.getSegmentList()) {
        
            int d = s.second;
            
            if (d % 2 == 1) continue;
            
            addConstraints(createCycleConstraints(s, d + 2, d + 5));
            addConstraints(createCycleConstraints(s, d + 6, d + 1));                
        }            
    }
    
    // Constraints for acyclic problems (explanation makes sense for exact problems):
    //
    // OBSOLETE
    //
    // 1. Each move mv_* has accompanying order variable order_*
    // 2. Move that is not picked has always order 0, 
    //    move that is picked has order between 1 and 675
    // 
    // It is accomplished with the condition:
    //      mv_ <= order_ <= 675 * mv_
    //
    // 3. Assume that mv_1 removes segment s and mv_2 places segment s (mv_1 != mv_2). 
    //    Then
    //      order_1 + (1 - mv_1) * 1000 >= order_2 + 1
    //
    //    The (1-mv_1)*1000 term assures that the condition is not enforced
    //      for moves that are not picked (i.e. have mv_1 = 0)
            
    if (getFlag("acyclic")) {
        throw std::string("not implemented");
    }

    // Constraints for symmetric problems.
    //
    // Moves that are symmetric by central symmetry
    //   with center at ref + (1.5,1.5) have to have equal weights
    
    if (getFlag("symmetric")) {
        for (const Move&m: b.getMoveList()) {
            Move sm = b.centerSymmetry(m);
            
            Constraint c;
            
            c.addVariable(to_string(m), 1.0);
            c.addVariable(to_string(sm), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("sym_" + to_string(m));
            
            addConstraint(c);
        }
    }

    // dot-acyclic - better implementation of acyclic problems

    // dots that are not placed have dot_ variable equal to 0
    // this is important for --hull option
    // use this not only for dot-acyclic problems
    
    for (const Dot& d: b.getDotList())
    {
        if (b.hasDot(d)) continue;
        
        Constraint c;
        
        c.setName("dotmove_" + to_string(d));
        
        c.addVariable("dot_" + to_string(d), 1.0);
        
        for (const Move& m: b.getMovesPlacingDot(d)) {
            c.addVariable(to_string(m), -b.bound());
        }
        c.setType(Constraint::LT);
        c.setBound(0.0);
        addConstraint(c);                    
    }
    
    if (getFlag("dot-acyclic")) {
        for (int x = 0; x < b.getWidth(); x++) {
            for (int y= 0; y < b.getHeight(); y++) {
                if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue;
                
                setVariableBounds("dot_" + to_string(Dot(x,y)), 0, b.bound());

                if (getFlag("symmetric")) {
                    Constraint c;
                    
                    if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue;
                    
                    c.setName("dotsym_");
                    c.addVariable("dot_" + to_string(Dot(x,y)), 1.0);
                    c.addVariable("dot_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0);
                    c.setType(Constraint::EQ);
                    c.setBound(0.0);
                    addConstraint(c);
                }                
            }
        }
        
        for (const Move& m: b.getMoveList()) {
            for (const Dot& rq: m.requiredDots(b.getVariant())) {
                if (b.hasDot(rq)) continue;
                
                Constraint c;
                
                // dot_placed >= dot_required + 1 - (1 - m) * bound
                // i.e. dot_placed - dot_required - bound * m >= 1 - bound
                
                c.setName("dot_");
                c.addVariable("dot_" + to_string(m.placedDot()), 1.0);
                c.addVariable("dot_" + to_string(rq), -1.0);
                c.addVariable(to_string(m), -b.bound());
                c.setBound(1 - b.bound());
                c.setType(Constraint::GT);
                
                addConstraint(c);
            }
        }      
    }

    // Constraints that enforce that the board (if it is rectangle) is 
    // the convex hull of the solution
    if (getFlag("rhull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));        
    }
    
    // Constraints that enforce that the board (if it is octagon) is 
    // the convex hull of the solution

    if (getFlag("hull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // lower right side
        addConstraint(getSideConstraint(1,-1,false));
        // upper left side
        addConstraint(getSideConstraint(1,-1,true));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));
        // lower left side
        addConstraint(getSideConstraint(1,1,false));
        // upper right side
        addConstraint(getSideConstraint(1,1,true));
    }
            
    return this;
}
Exemple #13
0
/**
 * Create a composite function from an expression.
 * @param expr :: The input expression
 * @param parentAttributes :: An output map filled with the attribute name &
 * values of the parent function
 * @return A pointer to the created function
 */
CompositeFunction_sptr FunctionFactoryImpl::createComposite(
    const Expression &expr,
    std::map<std::string, std::string> &parentAttributes) const {
  if (expr.name() != ";")
    inputError(expr.str());

  if (expr.size() == 0) {
    return CompositeFunction_sptr();
  }

  const std::vector<Expression> &terms = expr.terms();
  auto it = terms.cbegin();
  const Expression &term = it->bracketsRemoved();

  CompositeFunction_sptr cfun;
  if (term.name() == "=") {
    if (term.terms()[0].name() == "composite") {
      cfun = boost::dynamic_pointer_cast<CompositeFunction>(
          createFunction(term.terms()[1].name()));
      if (!cfun)
        inputError(expr.str());
      ++it;
    } else if (term.terms()[0].name() == "name") {
      cfun = boost::dynamic_pointer_cast<CompositeFunction>(
          createFunction("CompositeFunction"));
      if (!cfun)
        inputError(expr.str());
    } else {
      inputError(expr.str());
    }
  } else if (term.name() == ",") {
    auto firstTerm = term.terms().cbegin();
    if (firstTerm->name() == "=") {
      if (firstTerm->terms()[0].name() == "composite") {
        cfun = boost::dynamic_pointer_cast<CompositeFunction>(
            createSimple(term, parentAttributes));
        if (!cfun)
          inputError(expr.str());
        ++it;
      } else if (firstTerm->terms()[0].name() == "name") {
        cfun = boost::dynamic_pointer_cast<CompositeFunction>(
            createFunction("CompositeFunction"));
        if (!cfun)
          inputError(expr.str());
      } else {
        inputError(expr.str());
      }
    }
  } else if (term.name() == ";") {
    cfun = boost::dynamic_pointer_cast<CompositeFunction>(
        createFunction("CompositeFunction"));
    if (!cfun)
      inputError(expr.str());
  } else {
    inputError(expr.str());
  }

  if (!cfun)
    inputError(expr.str());

  for (; it != terms.end(); ++it) {
    const Expression &term = it->bracketsRemoved();
    IFunction_sptr fun;
    std::map<std::string, std::string> pAttributes;
    if (term.name() == ";") {
      fun = createComposite(term, pAttributes);
      if (!fun)
        continue;
    } else {
      std::string parName = term[0].name();
      if (parName.size() >= 10 && parName.substr(0, 10) == "constraint") {
        addConstraints(cfun, term[1]);
        continue;
      } else if (parName == "ties") {
        addTies(cfun, term[1]);
        continue;
      } else {
        fun = createSimple(term, pAttributes);
      }
    }
    cfun->addFunction(fun);
    size_t i = cfun->nFunctions() - 1;
    for (auto &pAttribute : pAttributes) {
      // Apply parent attributes of the child function to this function. If this
      // function doesn't have those attributes, they get passed up the chain to
      // this function's parent.
      if (cfun->hasLocalAttribute(pAttribute.first)) {
        cfun->setLocalAttributeValue(i, pAttribute.first, pAttribute.second);
      } else {
        parentAttributes[pAttribute.first] = pAttribute.second;
      }
    }
  }

  if (cfun) {
    cfun->applyTies();
  }
  return cfun;
}
Exemple #14
0
    /** 
     * Create a composite function from an expression.
     * @param expr :: The input expression
     * @param parentAttributes :: An output map filled with the attribute name & values of the parent function
     * @return A pointer to the created function
     */
    CompositeFunction_sptr FunctionFactoryImpl::createComposite(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const
    {
      if (expr.name() != ";") inputError(expr.str());

      if (expr.size() == 0)
      {
        return CompositeFunction_sptr();
      }

      const std::vector<Expression>& terms = expr.terms();
      std::vector<Expression>::const_iterator it = terms.begin();
      const Expression& term = it->bracketsRemoved();

      CompositeFunction_sptr cfun;
      if (term.name() == "=")
      {
        if (term.terms()[0].name() == "composite")
        {
          cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction(term.terms()[1].name()));
          if (!cfun) inputError(expr.str());
          ++it;
        }
        else if (term.terms()[0].name() == "name")
        {
          cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
          if (!cfun) inputError(expr.str());
        }
        else
        {
          inputError(expr.str());
        }
      }
      else if (term.name() == ",")
      {
        std::vector<Expression>::const_iterator firstTerm = term.terms().begin();
        if (firstTerm->name() == "=")
        {
          if (firstTerm->terms()[0].name() == "composite")
          {
            cfun = boost::dynamic_pointer_cast<CompositeFunction>(createSimple(term,parentAttributes));
            if (!cfun) inputError(expr.str());
            ++it;
          }
          else if (firstTerm->terms()[0].name() == "name")
          {
            cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
            if (!cfun) inputError(expr.str());
          }
          else
          {
            inputError(expr.str());
          }
        }
      }
      else if (term.name() == ";")
      {
        cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
        if (!cfun) inputError(expr.str());
      }
      else
      {
        inputError(expr.str());
      }

      for(;it!=terms.end();++it)
      {
        const Expression& term = it->bracketsRemoved();
        IFunction_sptr fun;
        std::map<std::string,std::string> pAttributes;
        if (term.name() == ";")
        {
          fun = createComposite(term,pAttributes);
          if (!fun) continue;
        }
        else
        {
          std::string parName = term[0].name();
          if (parName.size() >= 10 && parName.substr(0,10) == "constraint")
          {
            addConstraints(cfun,term[1]);
            continue;
          }
          else if (parName == "ties")
          {
            addTies(cfun,term[1]);
            continue;
          }
          else
          {
            fun = createSimple(term,pAttributes);
          }
        }
        cfun->addFunction(fun);
        size_t i = cfun->nFunctions() - 1;
        for(auto att = pAttributes.begin(); att != pAttributes.end(); ++att)
        {
          cfun->setLocalAttributeValue(i,att->first,att->second);
        }
      }

      cfun->applyTies();
      return cfun;
    }