Skip to content

Commit cf66fe2

Browse files
Refactor variable value retrieval to use get_values
Replaces calls to the deprecated get_variable_values method with get_values throughout the codebase for consistency and future compatibility. Adds a deprecation warning to get_variable_values in SolverWrapper, and updates related documentation and comments. This change modernizes variable retrieval and prepares for the eventual removal of the old method.
1 parent f6daaec commit cf66fe2

10 files changed

+36
-49
lines changed

examples/inexact_flow_solver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def get_solution(self):
130130
return self._solution
131131

132132
solution_weights_dict = self.solver.get_variable_values("w", [int])
133+
# solution_weights_dict = self.solver.get_values(self.path_weights_vars)
133134
self._solution = {
134135
"paths": self.get_solution_paths(),
135136
"weights": [solution_weights_dict[i] for i in range(self.k)],

flowpaths/abstractpathmodeldag.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,10 +678,7 @@ def get_solution_paths(self) -> list:
678678
return self.external_solution_paths
679679

680680
if self.edge_vars_sol == {}:
681-
self.edge_vars_sol = self.solver.get_variable_values(
682-
"edge", [str, str, int],
683-
binary_values=True,
684-
)
681+
self.edge_vars_sol = self.solver.get_values(self.edge_vars, binary_values=True)
685682

686683
paths = []
687684
for i in range(self.k):
@@ -732,7 +729,7 @@ def verify_edge_position(self):
732729

733730
paths = self.get_solution_paths()
734731

735-
edge_position_sol = self.solver.get_variable_values("position", [str, str, int])
732+
edge_position_sol = self.solver.get_values(self.edge_position_vars)
736733

737734
for path_index, path in enumerate(paths):
738735
current_edge_position = 0
@@ -752,7 +749,7 @@ def verify_path_length(self):
752749

753750
paths = self.get_solution_paths()
754751

755-
path_length_sol = self.solver.get_variable_values("path_length", [int])
752+
path_length_sol = self.solver.get_values(self.path_length_vars)
756753

757754
for path_index, path in enumerate(paths):
758755
if len(path) > 0:

flowpaths/abstractwalkmodeldigraph.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,6 @@ def get_solution_walks(self) -> list:
679679
self.edge_vars_sol = self.solver.get_values(self.edge_vars)
680680
# utils.logger.debug(f"{__name__}: Getting solution walks with self.edge_vars_sol = {self.edge_vars_sol}")
681681

682-
# self.distance_vars_sol = self.solver.get_variable_values("distance", [str, int])
683-
# utils.logger.debug(f"{__name__}: Getting solution walks with distances = {self.distance_vars_sol}")
684-
685-
# self.edge_selected_sol = self.solver.get_variable_values("selected_edge", [str, str, int])
686-
# utils.logger.debug(f"{__name__}: Getting solution walks with edge selected = {self.edge_selected_sol}")
687-
688682
walks = []
689683
for i in range(self.k):
690684
# Build residual graph for this layer with edge multiplicities

flowpaths/kflowdecomp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ def get_solution(self, remove_empty_paths=False):
431431
if self._solution is None:
432432

433433
self.check_is_solved()
434-
weights_sol_dict = self.solver.get_variable_values("w", [int])
434+
weights_sol_dict = self.solver.get_values(self.path_weights_vars)
435435
self.path_weights_sol = [
436436
(
437437
round(weights_sol_dict[i])

flowpaths/kleastabserrors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def get_solution(self, remove_empty_paths=True):
425425

426426
self.check_is_solved()
427427

428-
weights_sol_dict = self.solver.get_variable_values("weights", [int])
428+
weights_sol_dict = self.solver.get_values(self.path_weights_vars)
429429
self.path_weights_sol = [
430430
(
431431
round(weights_sol_dict[i])
@@ -434,7 +434,7 @@ def get_solution(self, remove_empty_paths=True):
434434
)
435435
for i in range(self.k)
436436
]
437-
self.edge_errors_sol = self.solver.get_variable_values("ee", [str, str])
437+
self.edge_errors_sol = self.solver.get_values(self.edge_errors_vars)
438438
for (u,v) in self.edge_indexes_basic:
439439
self.edge_errors_sol[(u,v)] = round(self.edge_errors_sol[(u,v)]) if self.weight_type == int else float(self.edge_errors_sol[(u,v)])
440440

flowpaths/kminpatherror.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ def get_solution(self, remove_empty_paths=True):
538538

539539
self.check_is_solved()
540540

541-
weights_sol_dict = self.solver.get_variable_values("weights", [int])
541+
weights_sol_dict = self.solver.get_values(self.path_weights_vars)
542542
self.path_weights_sol = [
543543
(
544544
round(weights_sol_dict[i])
@@ -547,7 +547,7 @@ def get_solution(self, remove_empty_paths=True):
547547
)
548548
for i in range(self.k)
549549
]
550-
slacks_sol_dict = self.solver.get_variable_values("slack", [int])
550+
slacks_sol_dict = self.solver.get_values(self.path_slacks_vars)
551551
self.path_slacks_sol = [
552552
(
553553
round(slacks_sol_dict[i])
@@ -572,7 +572,7 @@ def get_solution(self, remove_empty_paths=True):
572572
}
573573

574574
if len(self.path_length_factors) > 0:
575-
slacks_scaled_sol_dict = self.solver.get_variable_values("scaled_slack", index_types=[int])
575+
slacks_scaled_sol_dict = self.solver.get_values(self.scaled_slack_vars)
576576
self.path_slacks_scaled_sol = [slacks_scaled_sol_dict[i] for i in range(self.k)]
577577

578578
self._solution["scaled_slacks"] = self.path_slacks_scaled_sol
@@ -658,10 +658,10 @@ def is_valid_solution(self, tolerance=0.001):
658658

659659
# Checking that the error scale factor is correctly encoded
660660
if len(self.path_length_factors) > 0:
661-
path_length_sol = self.solver.get_variable_values("path_length", [int])
662-
slack_sol = self.solver.get_variable_values("slack", [int])
663-
path_slack_scaled_sol = self.solver.get_variable_values("path_slack_scaled", [int])
664-
scaled_slack_sol = self.solver.get_variable_values("scaled_slack", [int])
661+
path_length_sol = self.solver.get_values(self.path_length_vars)
662+
slack_sol = self.solver.get_values(self.path_slacks_vars)
663+
path_slack_scaled_sol = self.solver.get_values(self.slack_factors_vars)
664+
scaled_slack_sol = self.solver.get_values(self.scaled_slack_vars)
665665

666666
for i in range(self.k):
667667
# Checking which interval the path length is in,
@@ -682,16 +682,6 @@ def is_valid_solution(self, tolerance=0.001):
682682
if not self.verify_path_length():
683683
return False
684684

685-
# var_dict = {var: val for var, val in zip(self.solver.get_all_variable_names(),self.solver.get_all_variable_values())}
686-
# print(var_dict)
687-
# self.solver.write_model("kminpatherror.lp")
688-
689-
# gamma_sol = self.solver.get_variable_values("gamma", [str, str, int])
690-
# pi_sol = self.solver.get_variable_values("pi", [str, str, int])
691-
692-
# print("pi_sol", pi_sol)
693-
# print("gamma_sol", gamma_sol)
694-
695685
return True
696686

697687
def get_objective_value(self):

flowpaths/minerrorflow.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,15 +461,15 @@ def get_solution(self):
461461

462462
self._check_is_solved()
463463

464-
edge_sol_dict = self.solver.get_variable_values("edge_vars", [str, str])
464+
edge_sol_dict = self.solver.get_values(self.edge_vars)
465465
for edge in edge_sol_dict.keys():
466466
self.edge_sol[edge] = (
467467
round(edge_sol_dict[edge])
468468
if self.weight_type == int
469469
else float(edge_sol_dict[edge])
470470
)
471-
472-
edge_error_sol_dict = self.solver.get_variable_values("edge_error_vars", [str, str])
471+
472+
edge_error_sol_dict = self.solver.get_values(self.edge_error_vars)
473473
error = sum(edge_error_sol_dict.values())
474474

475475
corrected_graph = deepcopy(self.original_graph_copy)

flowpaths/mingenset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ def solve(self):
323323
self.solver.optimize()
324324

325325
if self.solver.get_model_status() == "kOptimal":
326-
genset_sol = self.solver.get_variable_values("gen_set", [int])
326+
genset_sol = self.solver.get_values(self.genset_vars)
327327
self._solution = sorted(self.weight_type(genset_sol[i]) for i in range(k))
328328
self._is_solved = True
329329
self.solve_statistics = {

flowpaths/minsetcover.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def solve(self) -> bool:
9999

100100
self.solver.optimize()
101101
if self.solver.get_model_status() == "kOptimal":
102-
subset_cover_sol = self.solver.get_variable_values("subset", [int])
102+
subset_cover_sol = self.solver.get_values(self.subset_vars)
103103
self._solution = [i for i in range(len(self.subsets)) if subset_cover_sol[i] == 1]
104104
self._is_solved = True
105105
self.solve_statistics = {

flowpaths/utils/solverwrapper.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import math
99
import flowpaths.utils as utils
1010
import numpy as np
11+
import warnings
1112

1213
class SolverWrapper:
1314
"""Unified MILP/LP modelling convenience layer for HiGHS and Gurobi.
@@ -256,15 +257,6 @@ def add_variables(self, indexes, name_prefix: str, lb=0, ub=1, var_type="integer
256257
Mapping from provided index to underlying solver variable objects
257258
(HiGHS returns an internal structure; Gurobi returns a dict).
258259
259-
Notes
260-
-----
261-
- Avoid ambiguous prefixes across different variable groups. For example,
262-
prefer prefixes like "x("/"x[" or "x_" that unambiguously delimit the
263-
name from indices, rather than bare "x" if you also use "x_long".
264-
- Retrieval via ``get_variable_values`` matches only exact structured
265-
forms ``prefix(...)`` or ``prefix[...]`` and a legacy single numeric
266-
suffix ``prefix<idx>`` (or ``prefix_<idx>``). Overlapping prefixes are
267-
safe under these rules, but ambiguous ad-hoc naming may still collide.
268260
"""
269261

270262
# No internal tracking of prefixes; caller must avoid collisions.
@@ -682,10 +674,15 @@ def parse_var_name(self, string, name_prefix):
682674

683675
return components
684676

677+
685678
def get_variable_values(
686679
self, name_prefix, index_types: list, binary_values: bool = False
687680
) -> dict:
688681
"""
682+
!!! warning "Deprecated"
683+
684+
Use `get_values(...)` instead.
685+
689686
Retrieve the values of variables belonging to a given prefix.
690687
691688
This method matches variables using one of these forms for the given
@@ -709,14 +706,22 @@ def get_variable_values(
709706
710707
Returns:
711708
values: A dictionary where the keys are the indices of the variables (as tuples or
712-
single values) and the values are the corresponding variable values.
713-
If index_types is empty, then the unique key is 0 and the value is the variable value.
709+
single values) and the values are the corresponding variable values.
710+
If index_types is empty, then the unique key is 0 and the value is the variable value.
714711
715712
Raises:
716713
Exception: If the length of `index_types` does not match the number of indices
717-
in a variable name.
714+
in a variable name.
718715
Exception: If `binary_values` is True and a variable value (rounded) is not binary.
719716
"""
717+
# Emit a deprecation warning (hidden by default unless enabled by filters)
718+
warnings.warn(
719+
"SolverWrapper.get_variable_values is deprecated and will be removed in a future release. "
720+
"Use SolverWrapper.get_values(...) instead.",
721+
DeprecationWarning,
722+
stacklevel=2,
723+
)
724+
720725
varNames = self.get_all_variable_names()
721726
varValues = self.get_all_variable_values()
722727

0 commit comments

Comments
 (0)