From 9438c14a33cf3b4c52831d4f58068aafc11cf2a3 Mon Sep 17 00:00:00 2001 From: "Dagmawi B. Tadesse" <51195080+daggbt@users.noreply.github.com> Date: Thu, 14 May 2026 16:07:06 +0000 Subject: [PATCH] Fix LP extraction for sliced matrix sums --- src/optyx/core/vectors.py | 9 +++++++++ tests/test_solver_integration.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/optyx/core/vectors.py b/src/optyx/core/vectors.py index 2f5742d..4010d0f 100644 --- a/src/optyx/core/vectors.py +++ b/src/optyx/core/vectors.py @@ -1316,6 +1316,15 @@ def _matches_default_bounds(self, variable: Variable, index: int) -> bool: ) and variable.ub == self._bound_at(self.ub, index) def _iter_variable_names(self) -> Iterator[str]: + cache = self._variable_cache + if cache is not None: + for index, variable in enumerate(cache): + if variable is not None: + yield variable.name + else: + yield self._name_at(index) + return + for index in range(self.size): yield self._name_at(index) diff --git a/tests/test_solver_integration.py b/tests/test_solver_integration.py index e8113fe..00c2873 100644 --- a/tests/test_solver_integration.py +++ b/tests/test_solver_integration.py @@ -239,6 +239,35 @@ def test_symmetric_matrix(self): # Should be symmetric assert S_vals[0, 1] == pytest.approx(S_vals[1, 0], abs=1e-6) + def test_matrix_transport_problem_with_row_and_column_sums(self): + """Matrix row and column slice sums should produce a feasible LP.""" + supply = np.array([100, 150, 200]) + demand = np.array([80, 120, 100, 150]) + costs = np.array( + [ + [4, 6, 9, 5], + [5, 3, 7, 8], + [6, 8, 4, 3], + ] + ) + + ship = MatrixVariable("ship", 3, 4, lb=0) + total_cost = sum(costs[i, j] * ship[i, j] for i in range(3) for j in range(4)) + + prob = Problem("transport").minimize(total_cost) + for i in range(3): + prob = prob.subject_to(ship[i, :].sum() <= supply[i]) + for j in range(4): + prob = prob.subject_to(ship[:, j].sum().eq(demand[j])) + + sol = prob.solve() + + assert sol.is_optimal + ship_vals = sol[ship] + np.testing.assert_allclose(ship_vals.sum(axis=1) <= supply + 1e-8, True) + np.testing.assert_allclose(ship_vals.sum(axis=0), demand, atol=1e-8) + assert sol.objective_value is not None + # ============================================================================= # Mixed Variable Types Tests