Skip to content

Commit

Permalink
refactor: minimize ilpy
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Nov 4, 2023
1 parent adf70fe commit 2c15221
Show file tree
Hide file tree
Showing 16 changed files with 591 additions and 88 deletions.
8 changes: 3 additions & 5 deletions motile/constraints/constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Iterable

if TYPE_CHECKING:
import ilpy
from motile.expressions import Expression

if TYPE_CHECKING:
from motile.solver import Solver


class Constraint(ABC):
"""A base class for a constraint that can be added to a solver."""

@abstractmethod
def instantiate(
self, solver: Solver
) -> Iterable[ilpy.Constraint | ilpy.Expression]:
def instantiate(self, solver: Solver) -> Iterable[Expression]:
"""Create and return specific linear constraints for the given solver.
Args:
Expand Down
23 changes: 10 additions & 13 deletions motile/constraints/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import contextlib
from typing import TYPE_CHECKING, Union

import ilpy
from motile.expressions import Expression, Constant

from ..variables import EdgeSelected, NodeSelected, Variable
from ..variables import EdgeSelected, NodeSelected, Variables
from .constraint import Constraint

if TYPE_CHECKING:
Expand Down Expand Up @@ -76,13 +76,13 @@ def __init__(
self.eval_nodes = eval_nodes
self.eval_edges = eval_edges

def instantiate(self, solver: Solver) -> list[ilpy.Constraint]:
def instantiate(self, solver: Solver) -> list[Expression]:
# create two constraints: one to select nodes/edges, and one to exclude
select = ilpy.Constraint()
exclude = ilpy.Constraint()
select: Expression = Constant(0)
exclude: Expression = Constant(0)
n_selected = 0 # number of nodes/edges selected

to_evaluate: list[tuple[NodesOrEdges, type[Variable]]] = []
to_evaluate: list[tuple[NodesOrEdges, type[Variables]]] = []
if self.eval_nodes:
to_evaluate.append((solver.graph.nodes, NodeSelected))
if self.eval_edges:
Expand All @@ -99,17 +99,14 @@ def instantiate(self, solver: Solver) -> list[ilpy.Constraint]:
# contextlib.suppress (above) will just skip it and move on...
if eval(self._expression, None, node_or_edge):
# if the expression evaluates to True, we select the node/edge
select.set_coefficient(indicator_variables[id_], 1)
select += indicator_variables[id_]
n_selected += 1
else:
# Otherwise, we exclude it.
exclude.set_coefficient(indicator_variables[id_], 1)
exclude += indicator_variables[id_]

# finally, apply the relation and value to the constraints
select.set_relation(ilpy.Relation.Equal)
select.set_value(n_selected)

exclude.set_relation(ilpy.Relation.Equal)
exclude.set_value(0)
select = select == n_selected
exclude = exclude == 0

return [select, exclude]
2 changes: 1 addition & 1 deletion motile/constraints/max_children.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import TYPE_CHECKING, Iterable

from ilpy.expressions import Constant, Expression
from motile.expressions import Constant, Expression

from ..variables import EdgeSelected
from .constraint import Constraint
Expand Down
2 changes: 1 addition & 1 deletion motile/constraints/max_parents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import TYPE_CHECKING, Iterable

from ilpy.expressions import Constant, Expression
from motile.expressions import Constant, Expression

from ..variables import EdgeSelected
from .constraint import Constraint
Expand Down
7 changes: 2 additions & 5 deletions motile/costs/features.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

if TYPE_CHECKING:
import ilpy
from motile.expressions import Variable


class Features:
Expand Down Expand Up @@ -53,7 +50,7 @@ def _increase_features(self, num_features: int) -> None:
self._values = np.hstack((self._values, new_features))

def add_feature(
self, variable_index: int | ilpy.Variable, feature_index: int, value: float
self, variable_index: int | Variable, feature_index: int, value: float
) -> None:
"""Add a value to a feature.
Expand Down
Loading

0 comments on commit 2c15221

Please sign in to comment.