molfoundry.FlowModelSMT#
- class molfoundry.FlowModelSMT(dg)#
Bases:
objectAn SMT (z3) integer-flow model over a derivation graph.
A drop-in analogue of
FlowModelthat uses z3 instead of Gurobi. On construction it creates one integer firing-count variable per hyperedge (reaction) and records the per-vertex stoichiometry. The caller then declares inflow / outflow on individual vertices, optionally sets a custom objective (the default minimizes the total number of reactions), and solves.The mass-balance constraints –
produced - consumed + inflow - outflow = 0for every vertex – are added automatically the first time the model is solved, so inflow / outflow must be declared before solving.The underlying
z3.Solver(holding the constraints) is exposed viamodel, and thez3module viaz3, so extra constraints can be built directly (fm.model.add(...)); the objective is set throughset_objective().n-best enumeration finds the optimum with az3.Optimize, blocks it, and re-optimizes for the next best.Example:
from molfoundry import FlowModelSMT fm = FlowModelSMT(dg) fm.add_in_flow(dg.findVertex(a), 6, 6) fm.add_in_flow(dg.findVertex(water), 1, 1) for v in dg.vertices: fm.add_out_flow(v, 0, None) sink = dg.findVertex(product) fm.add_out_flow(sink, 1, None) # Minimize reactions while maximizing the sink outflow. fm.set_objective( fm.z3.Sum([fm.reaction_var(e) for e in dg.edges]) - 1000 * fm.out_flow_var(sink) ) for solution in fm.enumerate_solutions(100): ...
- Parameters:
dg (DG)
- property model#
The underlying
z3.Solverholding the constraints, for arbitrary customization (add constraints withfm.model.add(...)). The objective is managed separately viaset_objective().
- reaction_var(edge)#
The integer firing-count variable for
edge.
- in_flow_var(vertex)#
The inflow variable for
vertex, orNoneif none was added.
- out_flow_var(vertex)#
The outflow variable for
vertex, orNoneif none was added.
- add_in_flow(vertex, lo=0, hi=None)#
Declare an inflow (source) on
vertexbounded to[lo, hi].hi=Noneleaves the inflow unbounded above. Returns the created variable (also reachable later viain_flow_var()).
- add_out_flow(vertex, lo=0, hi=None)#
Declare an outflow (sink) on
vertexbounded to[lo, hi].hi=Noneleaves the outflow unbounded above. Returns the created variable (also reachable later viaout_flow_var()).
- set_objective(expr, sense=ObjectiveSense.MINIMIZE)#
Set the objective;
senseisObjectiveSense.MINIMIZE(the default) orObjectiveSense.MAXIMIZE.- Parameters:
expr (Any)
sense (ObjectiveSense)
- Return type:
None
- optimum(time_limit=None)#
Solve for a single optimal flow, or
Noneif the model is infeasible.- Parameters:
time_limit (float | None)
- Return type:
FlowSolution | None
- enumerate_solutions(max_num_solutions, time_limit=None)#
Enumerate up to
max_num_solutionsbest flows, best objective first.Finds the optimum with a
z3.Optimize, then blocks each solution and re-optimizes for the next best, so solutions are yielded in nondecreasing (forObjectiveSense.MINIMIZE) / nonincreasing (forObjectiveSense.MAXIMIZE) objective order.time_limit(seconds) bounds each individual solve.- Yields:
FlowSolutionobjects, best objective first.- Parameters:
- Return type:
- dispose()#
Release solver resources (a no-op for z3; provided for API parity).
- Return type:
None