API Reference ============= The package contains two modules to model and solve problems. The :py:mod:`eut.peerless.model` is used to model the problem and :py:mod:`eut.peerless.solver` is used to solve it. Step by step ------------ Lets model the following problem taken from `here `_ .. math:: \begin{eqnarray} \min\; & \sin(y)e^{(1-\cos(x))^2} + \cos(x)e^{(1-\sin(y))^2} + (x-y)^2 \\ s.t.\; & (x+5)^2+(y+5)^2\le 25 \\ & -10 \le x \le 0 \\ & -6.5 \le y \le 0 \end{eqnarray} Create the model ^^^^^^^^^^^^^^^^ All the variables, constraints, objective and expressions must belong to a model. It will hold the representation of the problem to be solved. .. code-block:: python model = eut.peerless.model.Model("Townsend") Create the variables ^^^^^^^^^^^^^^^^^^^^ In this example we only have two variables. Notice that the first argument in the constructor is the model. The variables are added to the model at construction, you don't have to add them yourself.\ At construction time we specify the lower and upper bound too. These are extremely important and the tighter the bounds of the variables, the better the performance of most of the algorithms in *Peerless*. .. code-block:: python x = eut.peerless.model.Variable(model, "x", -10, 0) y = eut.peerless.model.Variable(model, "y", -6.5, 0) Add constraints ^^^^^^^^^^^^^^^ Constraints are created and **must be added to the model**, they are not added at construction time as variables or the objective function. Variables and expression have the comparison operators, ``<=``, ``>=`` and ``==``, overriden to facilitate the creation of constraints. .. code-block:: python model.add_constraint((x + 5)**2 + (y + 5)**2 <= 25, "ct1") Add the objective ^^^^^^^^^^^^^^^^^ The objective function is created using an expression at construction. Like variables, the model is the first argument and the objetive is set in the model once it is constructed. .. code-block:: python eut.peerless.model.Minimize(model, "objective", mdl.sin(y) * mdl.exp((1-mdl.cos(x))**2) + mdl.cos(x) * mdl.exp((1-mdl.sin(y))**2) + (x - y)**2) Solve the model ^^^^^^^^^^^^^^^ In order to solve the model we must create the parameters, and optionaly, the environment. If the environment is ommitted, *Peerless* will send the problem to Eve Utils public servers. Notice that the size of the problems that can be solved in the public service is limited and that you might encounter delays because your problem might be queued. In case of requiring more performance, contact Eve Utils to get a dedicated server dimensioned to your needs, or maybe to discuss an on premises solution. .. code-block:: python parameters = mdl.Parameters() environment = solver.Environment("your@email.com", "password") ans = solver.solve(model, parameters, environment) # Print the solution print(ans.solution) Solution and output ^^^^^^^^^^^^^^^^^^^ The value returned by the solver is an instance of :py:class:`eut.peerless.solver.OptimizationResult`. The possible statuses are defined in :py:class:`eut.abba.processor.statuses.Statuses`. In this case the output is .. highlight:: none :: $ python tests/test_townsend.py INFO:eut.peerless.solver:Sending problem to the jobstore INFO:eut.peerless.solver:..job's key is 159534646712651717ed83179cb1fcbd8aa2bb4eff7338b INFO:eut.peerless.solver:..pooling every 2 seconds INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:47|created: '' INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:48|processing: '' INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:50|executed: 'Objective: -106.76453674926478. Feasibility: 0.0. Iterations: 57. Elapsed: 0.150143996' {x: -3.130246801712496, y: -1.5821421805049385} Complete program ^^^^^^^^^^^^^^^^ .. code-block:: python import logging logging.basicConfig(level=logging.DEBUG) import eut.peerless.model as mdl import eut.peerless.solver as solver # Create the model model = mdl.Model("Townsend") # Add the variables x = mdl.Variable(model, "x", -10, 0) y = mdl.Variable(model, "y", -6.5, 0) # Add the objective function mdl.Minimize(model, "objective", mdl.sin(y) * mdl.exp((1-mdl.cos(x))**2) + mdl.cos(x) * mdl.exp((1-mdl.sin(y))**2) + (x - y)**2) # Add the constraints model.add_constraint((x + 5)**2 + (y + 5)**2 <= 25, "ct1") # Configure the parameters parameters = mdl.Parameters() # Solve the model ans = solver.solve(model, parameters) # Print the solution print(ans.solution) :mod:`eut.peerless` ------------------- .. automodule:: eut.peerless :mod:`eut.peerless.model` ------------------------- .. automodule:: eut.peerless.model .. autofunction:: eut.peerless.model.Expression .. autoclass:: eut.peerless.model.Function :members: :special-members: :exclude-members: serialize, deserialize, __init__ The following are the available functions in the library: .. autoclass:: eut.peerless.model.add .. autoclass:: eut.peerless.model.sub .. autoclass:: eut.peerless.model.mul .. autoclass:: eut.peerless.model.truediv .. autoclass:: eut.peerless.model.pow .. autoclass:: eut.peerless.model.abs .. autoclass:: eut.peerless.model.remainder .. autoclass:: eut.peerless.model.mod .. autoclass:: eut.peerless.model.sign .. autoclass:: eut.peerless.model.min .. autoclass:: eut.peerless.model.max .. autoclass:: eut.peerless.model.sin .. autoclass:: eut.peerless.model.cos .. autoclass:: eut.peerless.model.tan .. autoclass:: eut.peerless.model.sqrt .. autoclass:: eut.peerless.model.exp .. autoclass:: eut.peerless.model.log .. autoclass:: eut.peerless.model.round .. autoclass:: eut.peerless.model.ceil .. autoclass:: eut.peerless.model.floor .. autoclass:: eut.peerless.model.Model :members: :special-members: :exclude-members: __init__, __str__ .. autoclass:: eut.peerless.model.ModelMeasures .. autofunction:: eut.peerless.model.Variable .. autofunction:: eut.peerless.model.IntegerVariable .. autofunction:: eut.peerless.model.BinaryVariable .. autoclass:: eut.peerless.model.Constraint :members: :special-members: :exclude-members: serialize, deserialize, __init__, __str__ .. autofunction:: Maximize .. autofunction:: Minimize .. autoclass:: eut.peerless.model.Solution :members: :special-members: :exclude-members: serialize, deserialize, __init__, __str__ .. autoclass:: eut.peerless.model.Parameters :mod:`eut.peerless.solver` -------------------------- .. automodule:: eut.peerless.solver :members: The job service --------------- The jobs are stored in a :class:`eut.abba.processor.jobstore.JobStore`. A JobStore is registered in a :class:`eut.abba.rpc.Server`, with the server extending `xmlrpc.server.DocXMLRPCServer `_. The jobstore is self-documenting and is located at `http://eveutils.services/peerless/ `_ A `xmlrpc.client.ServerProxy `_ can be used to query the JobStore, it must be created using ``allow_none=True``. :class:`eut.abba.processor.jobstore.JobStore` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: eut.abba.processor.jobstore.JobStore :members: get_partials, get_result, get_statuses, cancelled, cancel :mod:`eut.abba.processor.statuses` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. automodule:: eut.abba.processor.statuses :members: :class:`eut.abba.rpc.Server` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: eut.abba.rpc.Server :members: