rescuer-task 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rescuer-packer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: rescuer-task
3
+ Version: 0.1.0
4
+ Summary: Special MILP format using by rescuer packer project
5
+ Author-email: "Vasily Stolbov a.k.a Kotomord" <vasily.v.stolbov@gmail.com>
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: ortools
10
+ Requires-Dist: pytest
11
+ Dynamic: license-file
12
+
13
+ # rescuer-task
14
+
15
+ Data classes for special MILP format
16
+
17
+ Class RescuerTask contains fields:
18
+ - cont_bounds: upper and lower bonds on continuous variables. Can be null if there are no bonds.
19
+ - rescuer_groups: sizes of groups of binary variables aka rescuers. The sum of variables in a group equals the size of the group minus one.
20
+ - inequalities: list of inequalities
21
+
22
+ Class Inequality contains 4 fields:
23
+ - conts: pairs “continuous variable number”-”continuous variable coefficient”
24
+ - constant_term: constant term of the left side of inequality
25
+ - right_coef: multiplier of the right side of inequality
26
+ - rescuers: list of rescuers
27
+
28
+ If rescuers is null or empty, the inequality is interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=0”, otherwise it’s interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=right_coef* sum of rescuers from field rescuers”, where right_coef should be chosen in such a way that if at least one of the rescuers has the value of 1, the inequality is satisfied.
29
+
30
+ ROADMAP.md contains future plans for the library’s improvements.
@@ -0,0 +1,18 @@
1
+ # rescuer-task
2
+
3
+ Data classes for special MILP format
4
+
5
+ Class RescuerTask contains fields:
6
+ - cont_bounds: upper and lower bonds on continuous variables. Can be null if there are no bonds.
7
+ - rescuer_groups: sizes of groups of binary variables aka rescuers. The sum of variables in a group equals the size of the group minus one.
8
+ - inequalities: list of inequalities
9
+
10
+ Class Inequality contains 4 fields:
11
+ - conts: pairs “continuous variable number”-”continuous variable coefficient”
12
+ - constant_term: constant term of the left side of inequality
13
+ - right_coef: multiplier of the right side of inequality
14
+ - rescuers: list of rescuers
15
+
16
+ If rescuers is null or empty, the inequality is interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=0”, otherwise it’s interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=right_coef* sum of rescuers from field rescuers”, where right_coef should be chosen in such a way that if at least one of the rescuers has the value of 1, the inequality is satisfied.
17
+
18
+ ROADMAP.md contains future plans for the library’s improvements.
@@ -0,0 +1,13 @@
1
+ [build-system]
2
+ requires = ["setuptools>=80.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+
6
+ [project]
7
+ name = "rescuer-task"
8
+ version = "0.1.0"
9
+ description = "Special MILP format using by rescuer packer project"
10
+ requires-python = ">=3.8"
11
+ readme = "README.md"
12
+ authors = [{name = "Vasily Stolbov a.k.a Kotomord", email = "vasily.v.stolbov@gmail.com"}]
13
+ dependencies = ["ortools", "pytest"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,84 @@
1
+ from typing import List
2
+
3
+ from ortools.linear_solver.pywraplp import Solver
4
+
5
+ from rescuer_task.task import RescuerTask, Inequality
6
+
7
+
8
+ def as_milp_task(solver: Solver, task: RescuerTask):
9
+ def int_var(var_name):
10
+ return solver.IntVar(0, 1, var_name)
11
+
12
+ return _build_task(solver, task, int_var)
13
+
14
+ def as_lp_task(solver: Solver, task: RescuerTask):
15
+ def int_var(var_name):
16
+ return solver.NumVar(0, 1, var_name)
17
+ return _build_task(solver, task, int_var)
18
+
19
+ def as_lp_task_with_point(solver: Solver, task: RescuerTask, point: List[bool], validate_point: bool = False):
20
+ if validate_point:
21
+ _check_point_validity(task, point)
22
+ cont_vars = _build_cont_vars(solver, task)
23
+ def skip(ineq: Inequality):
24
+ if ineq.rescuers is not None:
25
+ for t in ineq.rescuers:
26
+ if point[t]:
27
+ return True
28
+ return False
29
+ for inequality in task.inequalities:
30
+ if skip(inequality):
31
+ continue
32
+ solver.Add(_build_left(inequality, cont_vars) <= 0)
33
+
34
+ def _build_task(solver: Solver, task: RescuerTask, int_var):
35
+ cont_vars = _build_cont_vars(solver, task)
36
+ rescuers = []
37
+ r_pos = 0
38
+ for c in task.rescuer_groups:
39
+ rescuer_group = []
40
+ for i in range(c):
41
+ rescuer_group.append(int_var('r_' + str(r_pos)))
42
+ r_pos += 1
43
+ solver.Add(solver.Sum(rescuer_group) == c - 1)
44
+ rescuers.extend(rescuer_group)
45
+ for inequality in task.inequalities:
46
+ solver.Add(_build_left(inequality, cont_vars) <= _build_right(inequality, rescuers))
47
+
48
+ return cont_vars, rescuers
49
+
50
+
51
+ def _build_cont_vars(solver: Solver, task: RescuerTask):
52
+ cont_count = len(task.cont_bounds)
53
+ cont_vars = []
54
+ inf = solver.Infinity()
55
+
56
+ def num_var(var_name, bounds):
57
+ lb = bounds[0] if bounds[0] is not None else -inf
58
+ ub = bounds[1] if bounds[1] is not None else inf
59
+ return solver.NumVar(lb, ub, var_name)
60
+
61
+ for i in range(cont_count):
62
+ cont_vars.append(num_var('cont_' + str(i), task.cont_bounds[i]))
63
+ return cont_vars
64
+
65
+
66
+ def _build_left(inequality: Inequality, cont_vars):
67
+ ans = inequality.constant_term
68
+ if inequality.conts is not None:
69
+ for k, v in inequality.conts.items():
70
+ ans += cont_vars[k]*v
71
+ return ans
72
+
73
+ def _build_right(inequality: Inequality, rescuers):
74
+ if inequality.rescuers is None:
75
+ return 0
76
+ if len(inequality.rescuers) == 0:
77
+ return 0
78
+ ans = 0
79
+ for r in inequality.rescuers:
80
+ ans += rescuers[r]
81
+ return ans * inequality.right_coef
82
+
83
+ def _check_point_validity(task: RescuerTask, point: List[int]):
84
+ pass #TODO
@@ -0,0 +1,16 @@
1
+ from typing import Dict, List
2
+
3
+
4
+ class Inequality:
5
+ def __init__(self, conts: Dict[int, float]|None, constant_term: float, right_coef: float, rescuers: List[int] | None):
6
+ self.conts = conts
7
+ self.constant_term = constant_term
8
+ self.right_coef = right_coef
9
+ self.rescuers = rescuers
10
+
11
+
12
+ class RescuerTask:
13
+ def __init__(self):
14
+ self.inequalities: List[Inequality] = []
15
+ self.rescuer_groups: List[int] = []
16
+ self.cont_bounds: List[List[float]] = []
@@ -0,0 +1,5 @@
1
+ from .task import RescuerTask
2
+
3
+
4
+ def validate(task: RescuerTask, optimize: bool = False):
5
+ pass #TODO
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: rescuer-task
3
+ Version: 0.1.0
4
+ Summary: Special MILP format using by rescuer packer project
5
+ Author-email: "Vasily Stolbov a.k.a Kotomord" <vasily.v.stolbov@gmail.com>
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: ortools
10
+ Requires-Dist: pytest
11
+ Dynamic: license-file
12
+
13
+ # rescuer-task
14
+
15
+ Data classes for special MILP format
16
+
17
+ Class RescuerTask contains fields:
18
+ - cont_bounds: upper and lower bonds on continuous variables. Can be null if there are no bonds.
19
+ - rescuer_groups: sizes of groups of binary variables aka rescuers. The sum of variables in a group equals the size of the group minus one.
20
+ - inequalities: list of inequalities
21
+
22
+ Class Inequality contains 4 fields:
23
+ - conts: pairs “continuous variable number”-”continuous variable coefficient”
24
+ - constant_term: constant term of the left side of inequality
25
+ - right_coef: multiplier of the right side of inequality
26
+ - rescuers: list of rescuers
27
+
28
+ If rescuers is null or empty, the inequality is interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=0”, otherwise it’s interpreted as “the sum of values of continuous variable with coefficients and the constant term of the left side of inequality <=right_coef* sum of rescuers from field rescuers”, where right_coef should be chosen in such a way that if at least one of the rescuers has the value of 1, the inequality is satisfied.
29
+
30
+ ROADMAP.md contains future plans for the library’s improvements.
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ rescuer_task/__init__.py
5
+ rescuer_task/solvers.py
6
+ rescuer_task/task.py
7
+ rescuer_task/vaildator.py
8
+ rescuer_task.egg-info/PKG-INFO
9
+ rescuer_task.egg-info/SOURCES.txt
10
+ rescuer_task.egg-info/dependency_links.txt
11
+ rescuer_task.egg-info/requires.txt
12
+ rescuer_task.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ ortools
2
+ pytest
@@ -0,0 +1 @@
1
+ rescuer_task
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+