kap 0.2.0__tar.gz → 0.2.2__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.
- {kap-0.2.0 → kap-0.2.2}/PKG-INFO +23 -4
- {kap-0.2.0 → kap-0.2.2}/README.md +17 -2
- kap-0.2.2/kap/_version.py +1 -0
- {kap-0.2.0 → kap-0.2.2}/kap/assignment.py +24 -12
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/PKG-INFO +23 -4
- {kap-0.2.0 → kap-0.2.2}/setup.cfg +3 -0
- kap-0.2.0/kap/_version.py +0 -1
- {kap-0.2.0 → kap-0.2.2}/LICENSE.txt +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap/__init__.py +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap/_types.py +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/SOURCES.txt +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/dependency_links.txt +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/not-zip-safe +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/requires.txt +0 -0
- {kap-0.2.0 → kap-0.2.2}/kap.egg-info/top_level.txt +0 -0
- {kap-0.2.0 → kap-0.2.2}/setup.py +0 -0
{kap-0.2.0 → kap-0.2.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: kap
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Gabrovšek's Multiple Hungarian method for solving k-Assignment Problem.
|
|
5
5
|
Home-page: https://github.com/inspiros/kap
|
|
6
6
|
Author: Hoang-Nhat Tran (inspiros)
|
|
@@ -20,16 +20,20 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
26
|
Classifier: Operating System :: OS Independent
|
|
24
27
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
25
28
|
Requires-Python: >=3.7
|
|
26
29
|
Description-Content-Type: text/markdown
|
|
27
30
|
License-File: LICENSE.txt
|
|
28
31
|
Requires-Dist: numpy
|
|
32
|
+
Dynamic: license-file
|
|
29
33
|
|
|
30
34
|
``kap``: $k$-Assignment Problem Solver
|
|
31
35
|
======
|
|
32
|
-
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt)
|
|
36
|
+
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt) [](https://zenodo.org/doi/10.5281/zenodo.10449790)
|
|
33
37
|
|
|
34
38
|
This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for solving the **$k$-Assignment Problem**
|
|
35
39
|
(or **$k$-Partite Graph Matching Problem**), described in [this paper](https://www.mdpi.com/2227-7390/8/11/2050).
|
|
@@ -43,7 +47,7 @@ This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for
|
|
|
43
47
|
It is also traditionally referred to as **Multidimensional Assignment Problem**.
|
|
44
48
|
|
|
45
49
|
<p align="center">
|
|
46
|
-
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.
|
|
50
|
+
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.svg" width="300">
|
|
47
51
|
</p>
|
|
48
52
|
|
|
49
53
|
Formally, we seek a $k$-assignment of a given $k$-partite weighted graph $G = (V, E, \omega)$ with the minimum weight:
|
|
@@ -177,6 +181,21 @@ print("Total cost:", sum(matching_result.matching_costs))
|
|
|
177
181
|
|
|
178
182
|
These code blocks are extracted from [examples](examples).
|
|
179
183
|
|
|
184
|
+
## Citation
|
|
185
|
+
|
|
186
|
+
```bibtex
|
|
187
|
+
@software{inspiros_2024_10449791,
|
|
188
|
+
author = {Hoang-Nhat Tran},
|
|
189
|
+
title = {inspiros/kap: v0.2.1},
|
|
190
|
+
month = jan,
|
|
191
|
+
year = 2024,
|
|
192
|
+
publisher = {Zenodo},
|
|
193
|
+
version = {v0.2.1},
|
|
194
|
+
doi = {10.5281/zenodo.10449791},
|
|
195
|
+
url = {https://doi.org/10.5281/zenodo.10449791}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
180
199
|
## License
|
|
181
200
|
|
|
182
201
|
MIT licensed. See [LICENSE.txt](LICENSE.txt).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
``kap``: $k$-Assignment Problem Solver
|
|
2
2
|
======
|
|
3
|
-
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt)
|
|
3
|
+
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt) [](https://zenodo.org/doi/10.5281/zenodo.10449790)
|
|
4
4
|
|
|
5
5
|
This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for solving the **$k$-Assignment Problem**
|
|
6
6
|
(or **$k$-Partite Graph Matching Problem**), described in [this paper](https://www.mdpi.com/2227-7390/8/11/2050).
|
|
@@ -14,7 +14,7 @@ This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for
|
|
|
14
14
|
It is also traditionally referred to as **Multidimensional Assignment Problem**.
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.
|
|
17
|
+
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.svg" width="300">
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
Formally, we seek a $k$-assignment of a given $k$-partite weighted graph $G = (V, E, \omega)$ with the minimum weight:
|
|
@@ -148,6 +148,21 @@ print("Total cost:", sum(matching_result.matching_costs))
|
|
|
148
148
|
|
|
149
149
|
These code blocks are extracted from [examples](examples).
|
|
150
150
|
|
|
151
|
+
## Citation
|
|
152
|
+
|
|
153
|
+
```bibtex
|
|
154
|
+
@software{inspiros_2024_10449791,
|
|
155
|
+
author = {Hoang-Nhat Tran},
|
|
156
|
+
title = {inspiros/kap: v0.2.1},
|
|
157
|
+
month = jan,
|
|
158
|
+
year = 2024,
|
|
159
|
+
publisher = {Zenodo},
|
|
160
|
+
version = {v0.2.1},
|
|
161
|
+
doi = {10.5281/zenodo.10449791},
|
|
162
|
+
url = {https://doi.org/10.5281/zenodo.10449791}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
151
166
|
## License
|
|
152
167
|
|
|
153
168
|
MIT licensed. See [LICENSE.txt](LICENSE.txt).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2.2'
|
|
@@ -182,7 +182,7 @@ class KPartiteGraph:
|
|
|
182
182
|
cost_ij[:, n_matches_12 + n_free_1:] = cost_i2[:, free_2]
|
|
183
183
|
quotient_cost_matrices.append(cost_ij)
|
|
184
184
|
else:
|
|
185
|
-
quotient_cost_matrices.append(self[i, j].
|
|
185
|
+
quotient_cost_matrices.append(self[i, j].copy())
|
|
186
186
|
|
|
187
187
|
quotient_node_indices = KPartiteNamedNodeList()
|
|
188
188
|
for i in range(self.n_partites - 1):
|
|
@@ -486,7 +486,8 @@ def _Em_loop(G: KPartiteGraph,
|
|
|
486
486
|
first_partite_pair: Tuple[int, int],
|
|
487
487
|
maximize: bool = False,
|
|
488
488
|
max_iter: int = 100,
|
|
489
|
-
backend: str = "scipy"
|
|
489
|
+
backend: str = "scipy",
|
|
490
|
+
random_state: np.random.RandomState = np.random.RandomState()) -> Tuple[KPartiteGraph, float]:
|
|
490
491
|
best_Gq = G_init
|
|
491
492
|
best_score = G_init.vertices_cost()
|
|
492
493
|
best_vertices = G_init.vertices()
|
|
@@ -495,8 +496,8 @@ def _Em_loop(G: KPartiteGraph,
|
|
|
495
496
|
# undeterministic steepest descent
|
|
496
497
|
for iteration in range(max_iter):
|
|
497
498
|
improvement_achieved = False
|
|
498
|
-
for p1, p2 in
|
|
499
|
-
|
|
499
|
+
for p1, p2 in random_state.permutation(list(filter(lambda _: _ != best_first_partites_pair,
|
|
500
|
+
itertools.combinations(range(G.n_partites), r=2)))):
|
|
500
501
|
fixed_vertices = list(filter(lambda _: (_[0][0], _[1][0]) == (p1, p2), best_vertices))
|
|
501
502
|
M = [[_[0][1], _[1][1]] for _ in fixed_vertices]
|
|
502
503
|
Gq = G.quotient(p1, p2, M)
|
|
@@ -521,11 +522,14 @@ def solve_Em(G: KPartiteGraph,
|
|
|
521
522
|
maximize: bool = False,
|
|
522
523
|
max_iter: int = 100,
|
|
523
524
|
n_trials: int = 1,
|
|
524
|
-
backend: str = "scipy"
|
|
525
|
+
backend: str = "scipy",
|
|
526
|
+
random_state: Optional[Union[np.random.RandomState, int]] = None) -> KPartiteGraph:
|
|
525
527
|
if max_iter <= 0:
|
|
526
528
|
raise ValueError(f"max_iter must be a positive integer. Got {max_iter}.")
|
|
527
529
|
if n_trials <= 0:
|
|
528
530
|
raise ValueError(f"n_trials must be a positive integer. Got {n_trials}.")
|
|
531
|
+
if not isinstance(random_state, np.random.RandomState):
|
|
532
|
+
random_state = np.random.RandomState(random_state)
|
|
529
533
|
|
|
530
534
|
# init with Bm
|
|
531
535
|
Gq, choices = solve_Bm(G, maximize,
|
|
@@ -537,7 +541,7 @@ def solve_Em(G: KPartiteGraph,
|
|
|
537
541
|
|
|
538
542
|
for ti in range(n_trials):
|
|
539
543
|
Gq, score = _Em_loop(G, Gq, best_first_partites_pair, maximize, max_iter,
|
|
540
|
-
backend=backend)
|
|
544
|
+
backend=backend, random_state=random_state)
|
|
541
545
|
if (score < best_score and not maximize) or (score > best_score and maximize):
|
|
542
546
|
best_Gq = Gq
|
|
543
547
|
best_score = score
|
|
@@ -548,9 +552,12 @@ def solve_Em(G: KPartiteGraph,
|
|
|
548
552
|
def solve_Fm(G: KPartiteGraph,
|
|
549
553
|
maximize: bool = False,
|
|
550
554
|
max_iter: int = 100,
|
|
551
|
-
backend: str = "scipy"
|
|
555
|
+
backend: str = "scipy",
|
|
556
|
+
random_state: Optional[Union[np.random.RandomState, int]] = None) -> KPartiteGraph:
|
|
552
557
|
if max_iter <= 0:
|
|
553
558
|
raise ValueError(f"max_iter must be a positive integer. Got {max_iter}.")
|
|
559
|
+
if not isinstance(random_state, np.random.RandomState):
|
|
560
|
+
random_state = np.random.RandomState(random_state)
|
|
554
561
|
|
|
555
562
|
# init with Bm
|
|
556
563
|
Gq, choices = solve_Bm(G, maximize,
|
|
@@ -566,7 +573,7 @@ def solve_Fm(G: KPartiteGraph,
|
|
|
566
573
|
for iteration in range(max_iter):
|
|
567
574
|
improvement_achieved = False
|
|
568
575
|
|
|
569
|
-
rand_ind =
|
|
576
|
+
rand_ind = random_state.randint(0, len(best_Gq_list))
|
|
570
577
|
best_Gq = best_Gq_list[rand_ind]
|
|
571
578
|
best_edges = best_edges_list[rand_ind]
|
|
572
579
|
best_first_partites_pair = best_first_partites_pair_list[rand_ind]
|
|
@@ -597,7 +604,7 @@ def solve_Fm(G: KPartiteGraph,
|
|
|
597
604
|
if not improvement_achieved:
|
|
598
605
|
break
|
|
599
606
|
if len(best_Gq_list):
|
|
600
|
-
rand_ind =
|
|
607
|
+
rand_ind = random_state.randint(0, len(best_Gq_list))
|
|
601
608
|
best_Gq = best_Gq_list[rand_ind]
|
|
602
609
|
return best_Gq
|
|
603
610
|
|
|
@@ -608,7 +615,8 @@ def k_assignment(cost_matrices: Sequence[Array2DLike],
|
|
|
608
615
|
n_trials: int = 1,
|
|
609
616
|
maximize: bool = False,
|
|
610
617
|
return_free: bool = False,
|
|
611
|
-
backend: str = "scipy"
|
|
618
|
+
backend: str = "scipy",
|
|
619
|
+
random_state: Optional[Union[np.random.RandomState, int]] = None) -> AssignmentResult:
|
|
612
620
|
r"""
|
|
613
621
|
Solve the k-Assignment Problem using Gabrovšek's multiple Hungarian methods,
|
|
614
622
|
described in ref. [1]_. This function call the Linear Assignment Problem solver
|
|
@@ -630,6 +638,10 @@ def k_assignment(cost_matrices: Sequence[Array2DLike],
|
|
|
630
638
|
backend (str): The backend used to solve the linear assignment problem.
|
|
631
639
|
Supported backends are "scipy", "lap", "lapjv", "lapsolver", "munkres".
|
|
632
640
|
Defaults to "scipy".
|
|
641
|
+
random_state (RandomState, int, optional): Controls the pseudo random
|
|
642
|
+
number generation for shuffling or choosing random partites pair in
|
|
643
|
+
Em and Fm algorithms. Pass an int for reproducible output across
|
|
644
|
+
multiple function calls. Defaults to None.
|
|
633
645
|
|
|
634
646
|
Returns:
|
|
635
647
|
matching_results: A namedtuple of ``matches``, ``matching_costs``,
|
|
@@ -688,11 +700,11 @@ def k_assignment(cost_matrices: Sequence[Array2DLike],
|
|
|
688
700
|
return Gq.reconstruct(return_free=return_free)
|
|
689
701
|
elif algo == "e":
|
|
690
702
|
Gq = solve_Em(G, maximize, max_iter, n_trials,
|
|
691
|
-
backend=backend)
|
|
703
|
+
backend=backend, random_state=random_state)
|
|
692
704
|
return Gq.reconstruct(return_free=return_free)
|
|
693
705
|
elif algo == "f":
|
|
694
706
|
Gq = solve_Fm(G, maximize, max_iter,
|
|
695
|
-
backend=backend)
|
|
707
|
+
backend=backend, random_state=random_state)
|
|
696
708
|
return Gq.reconstruct(return_free=return_free)
|
|
697
709
|
else:
|
|
698
710
|
raise ValueError("algo must be either Am | Bm | Cm | Dm | Em | Fm "
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: kap
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Gabrovšek's Multiple Hungarian method for solving k-Assignment Problem.
|
|
5
5
|
Home-page: https://github.com/inspiros/kap
|
|
6
6
|
Author: Hoang-Nhat Tran (inspiros)
|
|
@@ -20,16 +20,20 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
26
|
Classifier: Operating System :: OS Independent
|
|
24
27
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
25
28
|
Requires-Python: >=3.7
|
|
26
29
|
Description-Content-Type: text/markdown
|
|
27
30
|
License-File: LICENSE.txt
|
|
28
31
|
Requires-Dist: numpy
|
|
32
|
+
Dynamic: license-file
|
|
29
33
|
|
|
30
34
|
``kap``: $k$-Assignment Problem Solver
|
|
31
35
|
======
|
|
32
|
-
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt)
|
|
36
|
+
[](https://github.com/inspiros/kap/actions) [](https://pypi.org/project/kap) [](https://pepy.tech/project/kap) [](https://github.com/inspiros/kap/blob/master/LICENSE.txt) [](https://zenodo.org/doi/10.5281/zenodo.10449790)
|
|
33
37
|
|
|
34
38
|
This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for solving the **$k$-Assignment Problem**
|
|
35
39
|
(or **$k$-Partite Graph Matching Problem**), described in [this paper](https://www.mdpi.com/2227-7390/8/11/2050).
|
|
@@ -43,7 +47,7 @@ This project implements **Boštjan Gabrovšek**'s Multiple Hungarian Methods for
|
|
|
43
47
|
It is also traditionally referred to as **Multidimensional Assignment Problem**.
|
|
44
48
|
|
|
45
49
|
<p align="center">
|
|
46
|
-
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.
|
|
50
|
+
<img src="https://raw.githubusercontent.com/inspiros/kap/master/resources/tripartite_matching_example.svg" width="300">
|
|
47
51
|
</p>
|
|
48
52
|
|
|
49
53
|
Formally, we seek a $k$-assignment of a given $k$-partite weighted graph $G = (V, E, \omega)$ with the minimum weight:
|
|
@@ -177,6 +181,21 @@ print("Total cost:", sum(matching_result.matching_costs))
|
|
|
177
181
|
|
|
178
182
|
These code blocks are extracted from [examples](examples).
|
|
179
183
|
|
|
184
|
+
## Citation
|
|
185
|
+
|
|
186
|
+
```bibtex
|
|
187
|
+
@software{inspiros_2024_10449791,
|
|
188
|
+
author = {Hoang-Nhat Tran},
|
|
189
|
+
title = {inspiros/kap: v0.2.1},
|
|
190
|
+
month = jan,
|
|
191
|
+
year = 2024,
|
|
192
|
+
publisher = {Zenodo},
|
|
193
|
+
version = {v0.2.1},
|
|
194
|
+
doi = {10.5281/zenodo.10449791},
|
|
195
|
+
url = {https://doi.org/10.5281/zenodo.10449791}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
180
199
|
## License
|
|
181
200
|
|
|
182
201
|
MIT licensed. See [LICENSE.txt](LICENSE.txt).
|
|
@@ -24,6 +24,9 @@ classifiers =
|
|
|
24
24
|
Programming Language :: Python :: 3.9
|
|
25
25
|
Programming Language :: Python :: 3.10
|
|
26
26
|
Programming Language :: Python :: 3.11
|
|
27
|
+
Programming Language :: Python :: 3.12
|
|
28
|
+
Programming Language :: Python :: 3.13
|
|
29
|
+
Programming Language :: Python :: 3.14
|
|
27
30
|
Operating System :: OS Independent
|
|
28
31
|
Topic :: Scientific/Engineering :: Mathematics
|
|
29
32
|
keywords = k-assignment, k-partite-matching, linear-assignment, bi-partite-matching, hungarian
|
kap-0.2.0/kap/_version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.2.0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kap-0.2.0 → kap-0.2.2}/setup.py
RENAMED
|
File without changes
|