Class ExpressionsBasedModel

java.lang.Object
org.ojalgo.optimisation.ExpressionsBasedModel
All Implemented Interfaces:
Optimisation, Optimisation.Model

public final class ExpressionsBasedModel extends Object implements Optimisation.Model

Lets you construct optimisation problems by combining (mathematical) expressions in terms of variables. Each expression or variable can be a constraint and/or contribute to the objective function. An expression or variable is turned into a constraint by setting a lower and/or upper limit. Use ModelEntity.lower(Comparable), ModelEntity.upper(Comparable) or ModelEntity.level(Comparable). An expression or variable is made part of (contributing to) the objective function by setting a contribution weight. Use ModelEntity.weight(Comparable).

You may think of variables as simple (the simplest possible) expressions, and of expressions as weighted combinations of variables. They are both model entities and it is as such they can be turned into constraints and set to contribute to the objective function. Alternatively you may choose to disregard the fact that variables are model entities and simply treat them as index values. In this case everything (constraints and objective) needs to be defined using expressions.

Basic instructions:

  1. Define (create) a set of variables. Set contribution weights and lower/upper limits as needed.
  2. Create a model using that set of variables.
  3. Add expressions to the model. The model is the expression factory. Set contribution weights and lower/upper limits as needed.
  4. Solve your problem using either minimise() or maximise()

When using this class you do not need to worry about which solver will actually be used. The docs of the various solvers describe requirements on input formats and similar. This is handled for you and should absolutely NOT be considered here! Compared to using the various solvers directly this class actually does something for you:

  1. You can model your problems without worrying about specific solver requirements.
  2. It knows which solver to use.
  3. It knows how to use that solver.
  4. It has a presolver that tries to simplify the problem before invoking a solver (sometimes it turns out there is no need to invoke a solver at all).
  5. When/if needed it scales problem parameters, before creating solver specific data structures, to minimise numerical problems in the solvers.
  6. It's the only way to access the integer solver.

Different solvers can be used, and ojAlgo comes with collection built in. The default built-in solvers can handle anything you can model with a couple of restrictions:

  • No quadratic constraints (The plan is that future versions should not have this limitation.)
  • If you use quadratic expressions make sure they're convex. This is most likely a requirement even with 3:d party solvers.
  • Field Details

  • Constructor Details

    • ExpressionsBasedModel

      public ExpressionsBasedModel()
    • ExpressionsBasedModel

      public ExpressionsBasedModel(Optimisation.Options optimisationOptions)
    • ExpressionsBasedModel

      ExpressionsBasedModel(ExpressionsBasedModel modelToCopy, boolean shallow, boolean prune)
  • Method Details

    • addIntegration

      public static boolean addIntegration(ExpressionsBasedModel.Integration<?> integration)
      Add an integration for a solver that will be used rather than the built-in solvers
    • addPresolver

      public static boolean addPresolver(ExpressionsBasedModel.Presolver presolver)
    • clearIntegrations

      public static void clearIntegrations()
    • clearPresolvers

      public static void clearPresolvers()
    • parse

      public static ExpressionsBasedModel parse(File file)
      Apart from the "native" EBM file format, currently only supports the MPS file format, but with some of the various extensions. In particular it is possible to parse QP models using QUADOBJ or QMATRIX file sections.
    • parse

    • removeIntegration

      public static boolean removeIntegration(ExpressionsBasedModel.Integration<?> integration)
    • removePresolver

      public static boolean removePresolver(ExpressionsBasedModel.Presolver presolver)
    • resetPresolvers

      public static void resetPresolvers()
    • addExpression

      public Expression addExpression()
    • addExpression

      public Expression addExpression(String name)
    • addSpecialOrderedSet

      public void addSpecialOrderedSet(Collection<Variable> orderedSet, int type, Expression linkedTo)
      Creates a special ordered set (SOS) presolver instance and links that to the supplied expression. When/if the presolver concludes that the SOS "constraints" are not possible the linked expression is marked as infeasible.
    • addSpecialOrderedSet

      public void addSpecialOrderedSet(Collection<Variable> orderedSet, int min, int max)
      Calling this method will create 2 things:
      1. A simple expression meassuring the sum of the (binary) variable values (the number of binary variables that are "ON"). The upper, and optionally lower, limits are set as defined by the max and min parameter values.
      2. A custom presolver (specific to this SOS) to be used by the MIP solver. This presolver help to keep track of which combinations of variable values or feasible, and is the only thing that enforces the order.
      Parameters:
      orderedSet - The set members in correct order. Each of these variables must be binary.
      min - The minimum number of binary varibales in the set that must be "ON" (Set this to 0 if there is no minimum.)
      max - The SOS type or maximum number of binary varibales in the set that may be "ON"
    • addVariable

      public Variable addVariable()
    • addVariable

      public Variable addVariable(String name)
    • bounds

      public Stream<Variable> bounds()
      Returns:
      A prefiltered stream of variables that are constraints and not fixed
    • checkSimilarity

      public boolean checkSimilarity(Expression potential)
    • constraints

      public Stream<Expression> constraints()
      Returns a prefiltered stream of expressions that are constraints and have not been markes as redundant.
    • copy

      public ExpressionsBasedModel copy()
    • copy

      public ExpressionsBasedModel copy(boolean relax)
    • copy

      public ExpressionsBasedModel copy(boolean shallow, boolean prune)
    • countExpressions

      public int countExpressions()
    • countVariables

      public int countVariables()
    • describe

      Counts variables and expressions of different categories.
    • dispose

      public void dispose()
      Description copied from interface: Optimisation.Model
      Cleanup when a model instance is no longer needed.
      Specified by:
      dispose in interface Optimisation.Model
    • getExpression

      public Expression getExpression(String name)
    • getExpressions

      public Collection<Expression> getExpressions()
    • getFixedVariables

      public Set<Structure1D.IntIndex> getFixedVariables()
    • getFreeVariables

      public List<Variable> getFreeVariables()
      Returns:
      A list of the variables that are not fixed at a specific value
    • getIntegerVariables

      public List<Variable> getIntegerVariables()
      Returns:
      A list of the variables that are not fixed at a specific value and are marked as integer variables
    • getNegativeVariables

      public List<Variable> getNegativeVariables()
      Returns:
      A list of the variables that are not fixed at a specific value and whos range include negative values
    • getOptimisationSense

      public Optimisation.Sense getOptimisationSense()
      1. The default optimisation sense is Optimisation.Sense.MIN
      2. If this model was read from a file and that file format contained information about being a minimisation or maximisation model, that info is reflected here.
      3. In general you are expected to know whether to call minimise() or maximise(). Once you have called one of those methods this method's return value will match that.
    • getPositiveVariables

      public List<Variable> getPositiveVariables()
      Returns a list of the variables that are not fixed at a specific value and whos range include positive values and/or zero
    • getVariable

      public Variable getVariable(int index)
    • getVariable

      public Variable getVariable(Structure1D.IntIndex index)
    • getVariables

      public List<Variable> getVariables()
    • getVariableValues

      public Optimisation.Result getVariableValues()
    • getVariableValues

      public Optimisation.Result getVariableValues(NumberContext validationContext)
      Null variable values are replaced with 0.0. If any variable value is null the state is set to INFEASIBLE even if zero would actually be a feasible value. The objective function value is not calculated for infeasible variable values.
    • indexOf

      public int indexOf(Variable variable)
    • indexOfFreeVariable

      public int indexOfFreeVariable(int globalIndex)
      Parameters:
      globalIndex - General, global, variable index
      Returns:
      Local index among the free variables. -1 indicates the variable is not a free variable.
    • indexOfFreeVariable

      public int indexOfFreeVariable(Structure1D.IntIndex variableIndex)
    • indexOfFreeVariable

      public int indexOfFreeVariable(Variable variable)
    • indexOfIntegerVariable

      public int indexOfIntegerVariable(int globalIndex)
      Parameters:
      globalIndex - General, global, variable index
      Returns:
      Local index among the integer variables. -1 indicates the variable is not an integer variable.
    • indexOfIntegerVariable

      public int indexOfIntegerVariable(Structure1D.IntIndex variableIndex)
    • indexOfIntegerVariable

      public int indexOfIntegerVariable(Variable variable)
    • indexOfNegativeVariable

      public int indexOfNegativeVariable(int globalIndex)
      Parameters:
      globalIndex - General, global, variable index
      Returns:
      Local index among the negative variables. -1 indicates the variable is not a negative variable.
    • indexOfNegativeVariable

      public int indexOfNegativeVariable(Structure1D.IntIndex variableIndex)
    • indexOfNegativeVariable

      public int indexOfNegativeVariable(Variable variable)
    • indexOfPositiveVariable

      public int indexOfPositiveVariable(int globalIndex)
      Parameters:
      globalIndex - General, global, variable index
      Returns:
      Local index among the positive variables. -1 indicates the variable is not a positive variable.
    • indexOfPositiveVariable

      public int indexOfPositiveVariable(Structure1D.IntIndex variableIndex)
    • indexOfPositiveVariable

      public int indexOfPositiveVariable(Variable variable)
    • isAnyConstraintQuadratic

      public boolean isAnyConstraintQuadratic()
    • isAnyExpressionQuadratic

      public boolean isAnyExpressionQuadratic()
      Objective or any constraint has quadratic part.
    • isAnyObjectiveQuadratic

      public boolean isAnyObjectiveQuadratic()
    • isAnyVariableFixed

      public boolean isAnyVariableFixed()
    • isAnyVariableInteger

      public boolean isAnyVariableInteger()
    • limitObjective

      public Expression limitObjective(BigDecimal lower, BigDecimal upper)
    • maximise

      public Optimisation.Result maximise()
      Specified by:
      maximise in interface Optimisation.Model
    • minimise

      public Optimisation.Result minimise()
      Specified by:
      minimise in interface Optimisation.Model
    • newExpression

      public Expression newExpression(String name)
    • newVariable

      public Variable newVariable(String name)
    • objective

      public Expression objective()
      This is generated on demand – you should not cache this. More specifically, modifications made to this expression will not be part of the optimisation model. You define the objective by setting the ModelEntity.weight(Comparable)/ModelEntity.weight(Comparable) on one or more variables and/or expressions.
      Returns:
      The generated/aggregated objective function
    • prepare

      public <T extends IntermediateSolver> T prepare(Function<ExpressionsBasedModel,T> factory)

      The general recommendation is to NOT call this method directly. Instead you should use/call maximise() or minimise().

      The primary use case for this method is as a callback method for solvers that iteratively modifies the model and solves at each iteration point.

      With direct usage of this method:

      • Maximisation/Minimisation is undefined (you don't know which it is)
      • The solution is not written back to the model
      • The solution is not validated by the model
    • reduce

      public ExpressionsBasedModel reduce()
      Will try to indentify constraints with equal variables set, and check if those can be combined or not. This is a relatively slow process with small chance to actually achieve somthing. Therefore it is not part of the default presolve och simplify() functionality.
      See Also:
    • relax

      public void relax()
    • relax

      public void relax(boolean soft)
      Parameters:
      soft - If true the integer variables are still identified as such, but the model is flagged as non-integer (will not use the IntegerSolver, but presolve and validation may still recognise the variables' integer property). If false the integer property of any/all variables are removed.
    • removeExpression

      public void removeExpression(String name)
    • setKnownSolution

      public void setKnownSolution(Optimisation.Result knownSolution)
    • setKnownSolution

      public void setKnownSolution(Optimisation.Result knownSolution, BiConsumer<ExpressionsBasedModel,Access1D<BigDecimal>> handler)
      For test/validation during solver development.
      Parameters:
      knownSolution - The optimal solution
      handler - What to do if validation fails
    • simplify

      public ExpressionsBasedModel simplify()
      Will perform presolve and then create a copy removing redundant constraint expressions, and pruning the remaining ones to no longer include fixed variables.
    • snapshot

      public ExpressionsBasedModel snapshot()
      Will create a shallow copy flagged as relaxed.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • validate

      public boolean validate()
      This methods validtes model construction only. All the other validate(...) method validates the solution (one way or another).
      Specified by:
      validate in interface Optimisation.Model
      Returns:
      true If eveything is ok. false The model is structurally ok, but the "value" breaks constraints - the solution is infeasible.
      See Also:
    • validate

      public boolean validate(Access1D<BigDecimal> solution)
    • validate

      public boolean validate(Access1D<BigDecimal> solution, BasicLogger appender)
    • validate

      public boolean validate(Access1D<BigDecimal> solution, NumberContext context)
    • validate

      public boolean validate(Access1D<BigDecimal> solution, NumberContext context, BasicLogger appender)
    • validate

      public boolean validate(BasicLogger appender)
    • validate

      public boolean validate(NumberContext context)
    • validate

      public boolean validate(NumberContext context, BasicLogger appender)
    • variables

      public Stream<Variable> variables()
      Returns a stream of variables that are not fixed.
    • writeTo

      public void writeTo(File file)
      Save this instance to file. The file format is ExpressionsBasedModel.FileFormat.EBM and the file name is therefore recommended to end with ".ebm".
      Parameters:
      file - The path/name of the file to write.
    • writeTo

      public void writeTo(InMemoryFile file)
    • optimise

      private Optimisation.Result optimise()
    • scanEntities

      private void scanEntities()
    • addObjectiveConstant

      void addObjectiveConstant(BigDecimal addition)
    • addReference

      void addReference(Structure1D.IntIndex index)
    • deriveAdjustmentRange

      int deriveAdjustmentRange(Expression expression)
    • expressions

      Stream<Expression> expressions()
    • getIntegration

    • getKnownSolution

      Optimisation.Result getKnownSolution()
    • getObjectiveConstant

      BigDecimal getObjectiveConstant()
    • getReferences

      Set<Structure1D.IntIndex> getReferences()
    • getValidationFailureHandler

      BiConsumer<ExpressionsBasedModel,Access1D<BigDecimal>> getValidationFailureHandler()
    • isFixed

      boolean isFixed()
    • isInfeasible

      boolean isInfeasible()
    • isInteger

      boolean isInteger(Set<Structure1D.IntIndex> variables)
    • isIntegrationSwitch

      boolean isIntegrationSwitch()
    • isReferenced

      boolean isReferenced(Variable variable)
    • isRelaxed

      boolean isRelaxed()
    • isShallowCopy

      boolean isShallowCopy()
    • isUnbounded

      boolean isUnbounded()
    • presolve

      void presolve()
    • setInfeasible

      void setInfeasible()
    • setIntegrationSwitch

      void setIntegrationSwitch(boolean value)
    • setOptimisationSense

      void setOptimisationSense(Optimisation.Sense optimisationSense)
    • toIntIndex

      Structure1D.IntIndex toIntIndex(int index)
    • toIntRowColumn

      Structure2D.IntRowColumn toIntRowColumn(int row, int column)