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.
- rescuer_task-0.1.0/LICENSE +21 -0
- rescuer_task-0.1.0/PKG-INFO +30 -0
- rescuer_task-0.1.0/README.md +18 -0
- rescuer_task-0.1.0/pyproject.toml +13 -0
- rescuer_task-0.1.0/rescuer_task/__init__.py +1 -0
- rescuer_task-0.1.0/rescuer_task/solvers.py +84 -0
- rescuer_task-0.1.0/rescuer_task/task.py +16 -0
- rescuer_task-0.1.0/rescuer_task/vaildator.py +5 -0
- rescuer_task-0.1.0/rescuer_task.egg-info/PKG-INFO +30 -0
- rescuer_task-0.1.0/rescuer_task.egg-info/SOURCES.txt +12 -0
- rescuer_task-0.1.0/rescuer_task.egg-info/dependency_links.txt +1 -0
- rescuer_task-0.1.0/rescuer_task.egg-info/requires.txt +2 -0
- rescuer_task-0.1.0/rescuer_task.egg-info/top_level.txt +1 -0
- rescuer_task-0.1.0/setup.cfg +4 -0
|
@@ -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,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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rescuer_task
|