Solvor your optimization needs.
Project description
Solvor
Solvor your optimization needs..
What's in the box?
| Category | Solvers | Use Case |
|---|---|---|
| Linear/Integer | solve_lp, solve_milp |
Resource allocation, scheduling |
| Constraint | solve_sat, Model |
Sudoku, configuration, puzzles |
| Local Search | anneal, tabu_search |
TSP, combinatorial optimization |
| Population | evolve |
When you want nature to do the work |
| Continuous | gradient_descent, momentum, adam |
ML, curve fitting |
| Black-box | bayesian_opt |
Hyperparameter tuning, expensive functions |
| Graph | max_flow, min_cost_flow, solve_assignment |
Matching, transportation |
Quickstart
uv add solvor
from solvor import solve_lp, solve_tsp, anneal, Model
# Linear Programming
result = solve_lp(c=[1, 2], A=[[1, 1], [2, 1]], b=[4, 5])
print(result.solution) # optimal x
# TSP with tabu search
distances = [[0, 10, 15], [10, 0, 20], [15, 20, 0]]
result = solve_tsp(distances)
print(result.solution) # best tour found
# Constraint satisfaction
m = Model()
x = m.int_var(1, 9, 'x')
y = m.int_var(1, 9, 'y')
m.add(m.all_different([x, y]))
m.add(m.sum_eq([x, y], 10))
result = m.solve()
print(result.solution) # {'x': 3, 'y': 7}
Solvers
Linear & Integer Programming
solve_lp
Two-phase simplex for linear programming.
# minimize 2x + 3y subject to x + y >= 4, x <= 3
result = solve_lp(
c=[2, 3],
A=[[-1, -1], [1, 0]], # constraints as Ax <= b
b=[-4, 3]
)
solve_milp
Branch and bound for mixed-integer problems.
# same as above, but x must be integer
result = solve_milp(c=[2, 3], A=[[-1, -1], [1, 0]], b=[-4, 3], integers=[0])
Constraint Programming
solve_sat
DPLL with unit propagation and clause learning.
# (x1 OR x2) AND (NOT x1 OR x3) AND (NOT x2 OR NOT x3)
result = solve_sat([[1, 2], [-1, 3], [-2, -3]])
print(result.solution) # {1: True, 2: False, 3: True}
Model (CP-SAT)
Constraint programming via SAT encoding.
m = Model()
cells = [[m.int_var(1, 9, f'c{i}{j}') for j in range(9)] for i in range(9)]
# All different in each row
for row in cells:
m.add(m.all_different(row))
result = m.solve()
Metaheuristics
anneal
Simulated annealing - accepts worse solutions probabilistically.
result = anneal(
initial=initial_solution,
objective_fn=cost_function,
neighbors=random_neighbor,
temperature=1000,
cooling=0.9995
)
tabu_search
Maintains a "tabu list" of recent moves to escape local optima.
result = tabu_search(
initial=initial_solution,
objective_fn=cost_function,
neighbors=get_neighbors, # returns [(move, solution), ...]
cooldown=10
)
evolve
Genetic algorithm with selection, crossover, mutation.
result = evolve(
objective_fn=fitness,
population=initial_pop,
crossover=my_crossover,
mutate=my_mutate,
max_gen=100
)
Continuous Optimization
gradient_descent / momentum / adam
First-order methods for differentiable functions.
def grad_fn(x):
return [2 * x[0], 2 * x[1]] # gradient of x^2 + y^2
result = adam(grad_fn, x0=[5.0, 5.0])
print(result.solution) # [~0, ~0]
bayesian_opt
Gaussian process surrogate for expensive black-box functions.
def expensive_fn(x):
# imagine this takes 10 minutes to evaluate
return (x[0] - 0.3)**2 + (x[1] - 0.7)**2
result = bayesian_opt(expensive_fn, bounds=[(0, 1), (0, 1)], max_iter=30)
Network Flow
max_flow
Ford-Fulkerson with BFS (Edmonds-Karp).
graph = {
's': [('a', 10, 0), ('b', 5, 0)],
'a': [('b', 15, 0), ('t', 10, 0)],
'b': [('t', 10, 0)],
't': []
}
result = max_flow(graph, 's', 't')
print(result.objective) # total flow
print(result.solution) # edge flows dict
min_cost_flow / solve_assignment
Successive shortest paths for minimum cost flow.
# Assignment problem: 3 workers, 3 tasks
costs = [
[10, 5, 13],
[3, 9, 18],
[10, 6, 12]
]
result = solve_assignment(costs)
# result.solution[i] = task assigned to worker i
# result.objective = total cost
Result Format
All solvers return a consistent Result namedtuple:
Result(
solution, # best solution found
objective, # objective value
iterations, # solver iterations (pivots, generations, etc.)
evaluations, # function evaluations
status # OPTIMAL, FEASIBLE, INFEASIBLE, UNBOUNDED, MAX_ITER
)
When to use what?
| Problem | Solver |
|---|---|
| Linear constraints, continuous variables | solve_lp |
| Linear constraints, some integers | solve_milp |
| Boolean satisfiability | solve_sat |
| Discrete variables, complex constraints | Model |
| Combinatorial, good initial solution | tabu_search, anneal |
| Combinatorial, no clue where to start | evolve |
| Smooth, differentiable | adam |
| Expensive black-box | bayesian_opt |
| Assignment, matching, flow | max_flow, solve_assignment |
Philosophy
- Pure Python - no numpy, no scipy, no compiled extensions
- Readable - each solvor fits in one file you can actually read
- Consistent - same Result format, same minimize/maximize convention
- Practical - solves real problems, or AoC puzzles
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
Apache 2.0 License - free for personal and commercial use.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file solvor-0.3.2.tar.gz.
File metadata
- Download URL: solvor-0.3.2.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09103b76714974f54853075009c8a21a0beec1069e92134f3dd7381727dacb26
|
|
| MD5 |
4169e805aef0cf6f81dbe6028cccf402
|
|
| BLAKE2b-256 |
f80a5eed921efa18417430141fec1837ca440c7e44d54166dda8aba915663fde
|
Provenance
The following attestation bundles were made for solvor-0.3.2.tar.gz:
Publisher:
publish.yml on StevenBtw/solvor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
solvor-0.3.2.tar.gz -
Subject digest:
09103b76714974f54853075009c8a21a0beec1069e92134f3dd7381727dacb26 - Sigstore transparency entry: 771522102
- Sigstore integration time:
-
Permalink:
StevenBtw/solvor@2b1af2a3b1dd2ad10f30b93c7567cea5de53a9fd -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/StevenBtw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b1af2a3b1dd2ad10f30b93c7567cea5de53a9fd -
Trigger Event:
release
-
Statement type:
File details
Details for the file solvor-0.3.2-py3-none-any.whl.
File metadata
- Download URL: solvor-0.3.2-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81bdaec69a1a8c8d3cc636898130b8412a82c439488cc5edfd1b9379c0d2f6a5
|
|
| MD5 |
9e81ce0607c4c8b0660b64fcf7fc2f77
|
|
| BLAKE2b-256 |
b23898996be4d262295f6f10ad9ba867510b8689a4c3e241528862416138e6e4
|
Provenance
The following attestation bundles were made for solvor-0.3.2-py3-none-any.whl:
Publisher:
publish.yml on StevenBtw/solvor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
solvor-0.3.2-py3-none-any.whl -
Subject digest:
81bdaec69a1a8c8d3cc636898130b8412a82c439488cc5edfd1b9379c0d2f6a5 - Sigstore transparency entry: 771522103
- Sigstore integration time:
-
Permalink:
StevenBtw/solvor@2b1af2a3b1dd2ad10f30b93c7567cea5de53a9fd -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/StevenBtw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b1af2a3b1dd2ad10f30b93c7567cea5de53a9fd -
Trigger Event:
release
-
Statement type: