pairwise-combinatorial 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,159 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ Pipfile.lock
88
+
89
+ # poetry
90
+ poetry.lock
91
+
92
+ # pdm
93
+ .pdm.toml
94
+
95
+ # PEP 582
96
+ __pypackages__/
97
+
98
+ # Celery stuff
99
+ celerybeat-schedule
100
+ celerybeat.pid
101
+
102
+ # SageMath parsed files
103
+ *.sage.py
104
+
105
+ # Environments
106
+ .env
107
+ .venv
108
+ env/
109
+ venv/
110
+ ENV/
111
+ env.bak/
112
+ venv.bak/
113
+
114
+ # Spyder project settings
115
+ .spyderproject
116
+ .spyproject
117
+
118
+ # Rope project settings
119
+ .ropeproject
120
+
121
+ # mkdocs documentation
122
+ /site
123
+
124
+ # mypy
125
+ .mypy_cache/
126
+ .dmypy.json
127
+ dmypy.json
128
+
129
+ # Pyre type checker
130
+ .pyre/
131
+
132
+ # pytype static type analyzer
133
+ .pytype/
134
+
135
+ # Cython debug symbols
136
+ cython_debug/
137
+
138
+ # UV
139
+ uv.lock
140
+
141
+ # IDEs
142
+ .vscode/
143
+ .idea/
144
+ *.swp
145
+ *.swo
146
+ *~
147
+ .DS_Store
148
+
149
+ # Testing
150
+ .tox/
151
+ .pytest_cache/
152
+ test-env/
153
+
154
+ # PyPI
155
+ dist/
156
+ build/
157
+ *.egg-info/
158
+
159
+ PUBLISHING.md
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Daniil Olekh
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,299 @@
1
+ Metadata-Version: 2.4
2
+ Name: pairwise-combinatorial
3
+ Version: 0.1.0
4
+ Summary: Combinatorial method for pairwise comparison aggregation using Prüfer sequences with parallel processing
5
+ Project-URL: Homepage, https://github.com/scape76/pairwise-combinatorial
6
+ Project-URL: Repository, https://github.com/yourusername/pairwise-combinatorial
7
+ Project-URL: Issues, https://github.com/yourusername/pairwise-combinatorial/issues
8
+ Author-email: Daniil Olekh <danyaolekhq@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ahp,combinatorial-optimization,decision-making,pairwise-comparison,prufer-sequences
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: numpy>=2.3.4
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Pairwise Combinatorial
24
+
25
+ [English version](README.en.md)
26
+
27
+ Python бібліотека для агрегації парних порівнянь з використанням комбінаторного методу та послідовностей Прюфера. Ця реалізація забезпечує ідеальну паралелізацію для майже лінійного прискорення з декількома робочими процесами.
28
+
29
+ ## Особливості
30
+
31
+ - **Комбінаторний метод**: Агрегує матриці парних порівнянь через перерахування остовних дерев
32
+ - **Паралельна обробка**: Використовує послідовності Прюфера для ідеального розподілу роботи між процесами
33
+ - **Гнучка агрегація**: Підтримує зважене та просте середнє геометричне
34
+ - **Підтримка неповних матриць**: Обробляє неповні матриці парних порівнянь за допомогою LLSM
35
+ - **Генерація матриць**: Вбудовані утиліти для генерації тестових матриць порівнянь
36
+
37
+ ## Встановлення
38
+
39
+ Встановити за допомогою `uv`:
40
+
41
+ ```bash
42
+ uv pip install pairwise-combinatorial
43
+ ```
44
+
45
+ Або встановити з джерела:
46
+
47
+ ```bash
48
+ git clone https://github.com/danolekh/pairwise_combinatorial
49
+ cd pairwise-combinatorial
50
+ uv pip install -e .
51
+ ```
52
+
53
+ ## Швидкий старт
54
+
55
+ ```python
56
+ import numpy as np
57
+ from pairwise_combinatorial import (
58
+ combinatorial_method,
59
+ weighted_geometric_mean,
60
+ generate_comparison_matrix,
61
+ )
62
+
63
+ # Генеруємо випадкову матрицю порівнянь
64
+ n = 9 # Кількість критеріїв
65
+ A = generate_comparison_matrix(n, missing_ratio=0.0)
66
+
67
+ # Застосовуємо комбінаторний метод з паралельною обробкою
68
+ result = combinatorial_method(
69
+ A,
70
+ n_workers=10, # Кількість паралельних робочих процесів
71
+ aggregator=weighted_geometric_mean,
72
+ )
73
+
74
+ print(f"Вектор пріоритетів: {result}")
75
+ ```
76
+
77
+ ## Довідник API
78
+
79
+ ### Основні функції
80
+
81
+ #### `combinatorial_method(A, n_workers, aggregator)`
82
+
83
+ Основний комбінаторний метод з використанням послідовностей Прюфера.
84
+
85
+ **Параметри:**
86
+
87
+ - `A` (np.ndarray): Матриця парних порівнянь (n × n)
88
+ - `n_workers` (int | Callable): Кількість робочих процесів або функція, що повертає їх кількість
89
+ - За замовчуванням: `smart_worker_count` (автоматично визначає на основі розміру матриці та кількості CPU)
90
+ - `aggregator` (Callable): Функція для агрегації векторів пріоритетів
91
+ - Геометричні: `weighted_geometric_mean` (за замовчуванням), `simple_geometric_mean`
92
+ - Арифметичні: `weighted_arithmetic_mean`, `simple_arithmetic_mean`
93
+
94
+ **Повертає:**
95
+
96
+ - `np.ndarray`: Фінальний агрегований вектор пріоритетів
97
+
98
+ ### Функції агрегації
99
+
100
+ #### Геометричне середнє
101
+
102
+ #### `weighted_geometric_mean(results)`
103
+
104
+ Агрегує вектори пріоритетів за допомогою зваженого середнього геометричного.
105
+
106
+ #### `simple_geometric_mean(results)`
107
+
108
+ Агрегує вектори пріоритетів за допомогою простого середнього геометричного (рівні ваги).
109
+
110
+ #### Арифметичне середнє
111
+
112
+ #### `weighted_arithmetic_mean(results)`
113
+
114
+ Агрегує вектори пріоритетів за допомогою зваженого середнього арифметичного.
115
+
116
+ #### `simple_arithmetic_mean(results)`
117
+
118
+ Агрегує вектори пріоритетів за допомогою простого середнього арифметичного (рівні ваги).
119
+
120
+ ### Допоміжні функції
121
+
122
+ #### `generate_comparison_matrix(n, missing_ratio, generator)`
123
+
124
+ Генерує матрицю парних порівнянь.
125
+
126
+ **Параметри:**
127
+
128
+ - `n` (int): Розмірність матриці (кількість критеріїв)
129
+ - `missing_ratio` (float): Частка відсутніх порівнянь (від 0.0 до 1.0)
130
+ - `generator` (Callable): Функція, що генерує значення порівнянь
131
+ - За замовчуванням: `saaty_generator` (використовує шкалу Сааті 1-9)
132
+
133
+ **Повертає:**
134
+
135
+ - `np.ndarray`: Матриця парних порівнянь
136
+
137
+ #### `is_full(A)`
138
+
139
+ Перевіряє, чи матриця порівнянь не має відсутніх значень.
140
+
141
+ #### `is_connected(A)`
142
+
143
+ Перевіряє, чи граф матриці порівнянь є зв'язним.
144
+
145
+ #### `calculate_consistency_ratio(A, w)`
146
+
147
+ Обчислює коефіцієнт узгодженості (CR) для матриці парних порівнянь.
148
+
149
+ #### `llsm_incomplete(A)`
150
+
151
+ Заповнює неповні матриці за допомогою методу логарифмічних найменших квадратів.
152
+
153
+ ### Вибір кількості робочих процесів
154
+
155
+ #### `smart_worker_count(n)`
156
+
157
+ Інтелектуально визначає кількість робочих процесів на основі розміру матриці та кількості CPU.
158
+
159
+ #### `auto_detect_workers()`
160
+
161
+ Автоматично визначає кількість робочих процесів лише на основі кількості CPU.
162
+
163
+ ## Приклади
164
+
165
+ ### Приклад з повною матрицею
166
+
167
+ ```python
168
+ import numpy as np
169
+ from pairwise_combinatorial import combinatorial_method, weighted_geometric_mean
170
+
171
+ # Створюємо просту матрицю порівнянь 4x4
172
+ A = np.array([
173
+ [1.0, 3.0, 5.0, 7.0],
174
+ [1/3, 1.0, 2.0, 4.0],
175
+ [1/5, 1/2, 1.0, 2.0],
176
+ [1/7, 1/4, 1/2, 1.0]
177
+ ])
178
+
179
+ # Обчислюємо вектор пріоритетів
180
+ weights = combinatorial_method(A, n_workers=4)
181
+ print(f"Ваги: {weights}")
182
+ ```
183
+
184
+ ### Приклад з неповною матрицею
185
+
186
+ ```python
187
+ import numpy as np
188
+ from pairwise_combinatorial import (
189
+ combinatorial_method,
190
+ generate_comparison_matrix,
191
+ is_connected,
192
+ )
193
+
194
+ # Генеруємо матрицю з 30% відсутніх значень
195
+ A = generate_comparison_matrix(n=6, missing_ratio=0.3)
196
+
197
+ if is_connected(A):
198
+ # Застосовуємо комбінаторний метод
199
+ weights = combinatorial_method(A, n_workers=4)
200
+ print(f"Ваги: {weights}")
201
+ else:
202
+ print("Матриця не є зв'язною!")
203
+ ```
204
+
205
+ ### Власна агрегація
206
+
207
+ ```python
208
+ from pairwise_combinatorial import (
209
+ combinatorial_method,
210
+ simple_geometric_mean,
211
+ weighted_arithmetic_mean,
212
+ simple_arithmetic_mean,
213
+ )
214
+
215
+ # Використовуємо просте середнє геометричне
216
+ weights = combinatorial_method(
217
+ A,
218
+ n_workers=8,
219
+ aggregator=simple_geometric_mean
220
+ )
221
+
222
+ # Використовуємо зважене середнє арифметичне
223
+ weights = combinatorial_method(
224
+ A,
225
+ n_workers=8,
226
+ aggregator=weighted_arithmetic_mean
227
+ )
228
+
229
+ # Використовуємо просте середнє арифметичне
230
+ weights = combinatorial_method(
231
+ A,
232
+ n_workers=8,
233
+ aggregator=simple_arithmetic_mean
234
+ )
235
+ ```
236
+
237
+ ### Перевірка узгодженості
238
+
239
+ ```python
240
+ from pairwise_combinatorial import (
241
+ combinatorial_method,
242
+ calculate_consistency_ratio,
243
+ generate_comparison_matrix,
244
+ )
245
+
246
+ A = generate_comparison_matrix(n=5)
247
+ weights = combinatorial_method(A)
248
+
249
+ cr = calculate_consistency_ratio(A, weights)
250
+ print(f"Коефіцієнт узгодженості: {cr:.4f}")
251
+
252
+ if cr < 0.10:
253
+ print("Матриця має прийнятну узгодженість (за критерієм Сааті)")
254
+ else:
255
+ print("Узгодженість матриці викликає сумніви")
256
+ ```
257
+
258
+ ## Продуктивність
259
+
260
+ Бібліотека використовує послідовності Прюфера для ідеальної паралелізації:
261
+
262
+ - **Розмір матриці n=5**: ~125 остовних дерев, < 1 секунди
263
+ - **Розмір матриці n=7**: ~16,807 остовних дерев, ~1 секунда
264
+ - **Розмір матриці n=8**: ~262,144 остовних дерев, ~10 секунд (8 робочих процесів)
265
+ - **Розмір матриці n=9**: ~4,782,969 остовних дерев, ~3 хвилини (10 робочих процесів)
266
+
267
+ Продуктивність масштабується майже лінійно з кількістю робочих процесів до кількості критеріїв (n).
268
+
269
+ ## Деталі алгоритму
270
+
271
+ Комбінаторний метод:
272
+
273
+ 1. Перераховує всі остовні дерева за допомогою послідовностей Прюфера
274
+ 2. Для кожного дерева будує ідеально узгоджену МПП (ICPCM)
275
+ 3. Обчислює вектори пріоритетів з кожної ICPCM
276
+ 4. Агрегує всі вектори пріоритетів за допомогою середнього геометричного
277
+
278
+ Послідовності Прюфера забезпечують ідеальну паралелізацію через розподіл префіксів послідовностей між робочими процесами.
279
+
280
+ ## Ліцензія
281
+
282
+ MIT
283
+
284
+ ## Внесок
285
+
286
+ Внески вітаються! Будь ласка, не соромтеся відправляти Pull Request.
287
+
288
+ ## Цитування
289
+
290
+ Якщо ви використовуєте цю бібліотеку у своїх дослідженнях, будь ласка, процитуйте:
291
+
292
+ ```
293
+ @software{pairwise_combinatorial,
294
+ title = {Pairwise Combinatorial: Паралельний комбінаторний метод для агрегації парних порівнянь},
295
+ author = {Your Name},
296
+ year = {2024},
297
+ url = {https://github.com/danolekh/pairwise_combinatorial}
298
+ }
299
+ ```