Package: pivotal-solver
No fuss Linear Programming solverfrompivotalimportminimize,maximize,Variablex=Variable("x")y=Variable("y")z=Variable("z")objective=2*x+y+3*zconstraints=(x-y==4,y+2*z==2)minimize(objective,constraints)# -> value: 11.0# -> variables: {'x': 4.0, 'y': 0.0, 'z': 1.0}maximize(objective,constraints)# -> value: 14.0# -> variables: {'x': 6.0, 'y': 2.0, 'z': 0.0}AboutPivotalis not aiming to compete with commerical solvers like Gurobi. Rather, it is aiming to simplify the process of creating and solving linear programs thanks to its very simple and intuitive API. The solver itself uses a 2-phase Simplex algorithm.InstallationPython >=3.10 is required.Install via pip:pipinstallpivotal-solverAPIVariablesVariableinstances implement__add__,__sub__and other magic methods, so you can use them directly in expressions such as2*x + 10 - y.Here are some examples of what you can do with them:x=Variable("x")y=Variable("y")z=Variable("z")2*x+10-yx+(y-z)*10-x-(x+y)sum([x,y,z])X=[Variable(f"x{i}")foriinrange(5)]sum(X)Note that variables are considered equal if they have the same name, so
for examples this expression:Variable("x")+2+Variable("x")will be treated as simply2*x+2.The first argument tominimizeandmaximizeis the objective function which must be either a single variable or a linear combination as in the example above.ConstraintsThere are three supported constraints:==(equality),>=(greater than or equal) and<=(less than or equal). You create a constraint simply by using these comparisons in expressions involvingVariableinstances. For example:x=Variable("x")y=Variable("y")z=Variable("z")x==42*x-y==z+7y>=-x+3*zx<=0There is no need to convert your constraints to the canonical form which uses only equality constraints. This is done automatically by the solver.minimizeandmaximizeexpect a list of constraints as the second argument.OutputThe return value ofminimizeandmaximizeis a 2-tuple containing the value of the objective function and a dictionary of variables and their values.The functions may raisepivotal.Infeasibleif the program is over-constrained (no solution exists) orpivotal.Unboundedif the program is under-constrained (the objective can be made arbitrarily small).frompivotalimportminimize,maximize,Variable,Infeasiblex=Variable("x")y=Variable("y")objective=2*x+yconstraints=(x+2*y==4,x+y==10)try:minimize(objective,constraints)exceptInfeasible:print("No solution")Iterations & Toleranceminimizeandmaximizetake two keyword argumentsmax_iterationsandtolerance.max_iterations(defaultmath.inf) controls the maximum number of iterations of the second phase of the Simplex algorithm. If the maximum number of iterations is reached a potentially non-optimal solution is returned.tolerance(default1e-6) controls the precision of floating point comparisons, e.g. when comparing against zero. Instead ofx == 0.0, the algorithm considers a value to be zero when it is within the given tolerance:abs(x) <= tolerance.LimitationsCurrently, all variables are assumed to be positiveTODO (Contributions welcome)✔️ Setting tolerance & max number of iterations(WIP) Arbitrary variable bounds, e.g.a <= x <= b(WIP) Support for absolute valuesMILP solver with branch & boundDevelopmentSetting upgitclonehttps://github.com/tomasr8/pivotal.gitcdpivotalpython-mvenvvenvsourcevenv/bin/activatepipinstall-e".[dev]"Running testspytest