pyoptima 0.0.1__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.
pyoptima-0.0.1/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 PyOptima Contributors
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.
22
+
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ recursive-include pyoptima *.py
5
+ recursive-include examples *.json *.py *.md
6
+
@@ -0,0 +1,404 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyoptima
3
+ Version: 0.0.1
4
+ Summary: A Python package for declarative optimization that accepts configuration files and performs optimizations using various solvers (CBC, GUROBI, GLPK)
5
+ Author-email: semantic developers <na@example.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/auscheng/pyoptima
8
+ Project-URL: Documentation, https://github.com/auscheng/pyoptima#readme
9
+ Project-URL: Repository, https://github.com/auscheng/pyoptima
10
+ Project-URL: Issues, https://github.com/auscheng/pyoptima/issues
11
+ Keywords: optimization,python,linear-programming,solver,declarative
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: pydantic>=2.0.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
24
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
25
+ Requires-Dist: black>=23.0.0; extra == "dev"
26
+ Requires-Dist: isort>=5.12.0; extra == "dev"
27
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
28
+ Requires-Dist: build>=0.10.0; extra == "dev"
29
+ Requires-Dist: twine>=4.0.0; extra == "dev"
30
+ Provides-Extra: cbc
31
+ Requires-Dist: pulp>=2.7.0; extra == "cbc"
32
+ Provides-Extra: gurobi
33
+ Requires-Dist: gurobipy>=11.0.0; extra == "gurobi"
34
+ Provides-Extra: glpk
35
+ Requires-Dist: pulp>=2.7.0; extra == "glpk"
36
+ Provides-Extra: all
37
+ Requires-Dist: pulp>=2.7.0; extra == "all"
38
+ Requires-Dist: gurobipy>=11.0.0; extra == "all"
39
+ Dynamic: license-file
40
+
41
+ # PyOptima
42
+
43
+ > **Declarative Optimization Service - Accept configuration files and perform optimizations**
44
+
45
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
48
+
49
+ **PyOptima** is a Python package for declarative optimization that accepts configuration files and performs optimizations using various solvers (CBC, GUROBI, GLPK). It provides a simple, declarative interface for defining optimization problems without writing solver-specific code.
50
+
51
+ ## Features
52
+
53
+ - 🚀 **Declarative Configuration** - Define optimization problems using JSON configuration files
54
+ - 🔧 **Multiple Solvers** - Support for CBC, GUROBI, and GLPK solvers
55
+ - 📋 **Type Safety** - Full type hints and Pydantic v2 compatibility
56
+ - 🎯 **Easy to Use** - Simple API for running optimizations
57
+ - 🔄 **Swappable Solvers** - Easily switch between different solvers via configuration
58
+
59
+ ## Installation
60
+
61
+ ### Core Library
62
+
63
+ ```bash
64
+ pip install pyoptima
65
+ ```
66
+
67
+ ### With Solver Support
68
+
69
+ ```bash
70
+ # For CBC and GLPK (using PuLP)
71
+ pip install pyoptima[cbc]
72
+ pip install pyoptima[glpk]
73
+
74
+ # For Gurobi (requires Gurobi license)
75
+ pip install pyoptima[gurobi]
76
+
77
+ # Install all solvers
78
+ pip install pyoptima[all]
79
+ ```
80
+
81
+ ## Quick Start
82
+
83
+ ### 1. Create a Configuration File
84
+
85
+ Create a JSON file (e.g., `portfolio.json`) with your optimization problem:
86
+
87
+ ```json
88
+ {
89
+ "meta": {
90
+ "job_id": "portfolio-rebalance-001",
91
+ "solver": "CBC",
92
+ "time_limit_seconds": 30
93
+ },
94
+ "variables": [
95
+ { "id": "w_aapl", "type": "Continuous", "lb": 0, "ub": 0.5 },
96
+ { "id": "w_msft", "type": "Continuous", "lb": 0, "ub": 0.5 }
97
+ ],
98
+ "objective": {
99
+ "direction": "Maximize",
100
+ "terms": [
101
+ { "var": "w_aapl", "coef": 0.12 },
102
+ { "var": "w_msft", "coef": 0.15 }
103
+ ]
104
+ },
105
+ "constraints": [
106
+ {
107
+ "id": "budget_limit",
108
+ "upper_bound": 1.0,
109
+ "terms": [
110
+ { "var": "w_aapl", "coef": 1 },
111
+ { "var": "w_msft", "coef": 1 }
112
+ ]
113
+ }
114
+ ]
115
+ }
116
+ ```
117
+
118
+ ### 2. Run Optimization
119
+
120
+ #### Using CLI
121
+
122
+ ```bash
123
+ pyoptima optimize portfolio.json
124
+ ```
125
+
126
+ With output file:
127
+
128
+ ```bash
129
+ pyoptima optimize portfolio.json --output results.json --pretty
130
+ ```
131
+
132
+ #### Using Python API
133
+
134
+ ```python
135
+ from pyoptima import OptimizationEngine
136
+
137
+ # Create engine
138
+ engine = OptimizationEngine()
139
+
140
+ # Run optimization
141
+ result = engine.optimize_from_file("portfolio.json")
142
+
143
+ # Check results
144
+ if result.is_optimal():
145
+ print(f"Optimal objective value: {result.objective_value}")
146
+ print(f"Variable values: {result.variables}")
147
+ else:
148
+ print(f"Optimization status: {result.status}")
149
+ ```
150
+
151
+ ## Configuration Format
152
+
153
+ ### Meta
154
+
155
+ Metadata for the optimization job:
156
+
157
+ ```json
158
+ {
159
+ "meta": {
160
+ "job_id": "unique-job-id",
161
+ "solver": "CBC", // "CBC", "GUROBI", or "GLPK"
162
+ "time_limit_seconds": 30 // Optional
163
+ }
164
+ }
165
+ ```
166
+
167
+ ### Variables
168
+
169
+ Define optimization variables:
170
+
171
+ ```json
172
+ {
173
+ "variables": [
174
+ {
175
+ "id": "w_aapl",
176
+ "type": "Continuous", // "Continuous", "Binary", or "Integer"
177
+ "lb": 0, // Optional lower bound
178
+ "ub": 0.5 // Optional upper bound
179
+ },
180
+ {
181
+ "id": "shift_john_1",
182
+ "type": "Binary" // Binary variables don't need bounds
183
+ }
184
+ ]
185
+ }
186
+ ```
187
+
188
+ ### Objective
189
+
190
+ Define the objective function:
191
+
192
+ ```json
193
+ {
194
+ "objective": {
195
+ "direction": "Maximize", // "Maximize" or "Minimize"
196
+ "terms": [
197
+ { "var": "w_aapl", "coef": 0.12 },
198
+ { "var": "shift_john_1", "coef": -10 }
199
+ ]
200
+ }
201
+ }
202
+ ```
203
+
204
+ ### Constraints
205
+
206
+ Define constraints:
207
+
208
+ ```json
209
+ {
210
+ "constraints": [
211
+ {
212
+ "id": "budget_limit",
213
+ "lower_bound": null, // Optional
214
+ "upper_bound": 1.0, // Optional
215
+ "terms": [
216
+ { "var": "w_aapl", "coef": 1 },
217
+ { "var": "w_msft", "coef": 1 }
218
+ ]
219
+ },
220
+ {
221
+ "id": "min_nurses",
222
+ "lower_bound": 2.0,
223
+ "upper_bound": null,
224
+ "terms": [
225
+ { "var": "shift_john_1", "coef": 1 },
226
+ { "var": "shift_jane_1", "coef": 1 }
227
+ ]
228
+ }
229
+ ]
230
+ }
231
+ ```
232
+
233
+ ## Examples
234
+
235
+ ### Portfolio Optimization
236
+
237
+ ```json
238
+ {
239
+ "meta": {
240
+ "job_id": "portfolio-001",
241
+ "solver": "CBC"
242
+ },
243
+ "variables": [
244
+ { "id": "w_aapl", "type": "Continuous", "lb": 0, "ub": 0.4 },
245
+ { "id": "w_msft", "type": "Continuous", "lb": 0, "ub": 0.4 },
246
+ { "id": "w_goog", "type": "Continuous", "lb": 0, "ub": 0.4 }
247
+ ],
248
+ "objective": {
249
+ "direction": "Maximize",
250
+ "terms": [
251
+ { "var": "w_aapl", "coef": 0.12 },
252
+ { "var": "w_msft", "coef": 0.15 },
253
+ { "var": "w_goog", "coef": 0.18 }
254
+ ]
255
+ },
256
+ "constraints": [
257
+ {
258
+ "id": "budget",
259
+ "upper_bound": 1.0,
260
+ "terms": [
261
+ { "var": "w_aapl", "coef": 1 },
262
+ { "var": "w_msft", "coef": 1 },
263
+ { "var": "w_goog", "coef": 1 }
264
+ ]
265
+ }
266
+ ]
267
+ }
268
+ ```
269
+
270
+ ### Nurse Scheduling
271
+
272
+ ```json
273
+ {
274
+ "meta": {
275
+ "job_id": "nurse-scheduling-001",
276
+ "solver": "CBC"
277
+ },
278
+ "variables": [
279
+ { "id": "shift_john_1", "type": "Binary" },
280
+ { "id": "shift_john_2", "type": "Binary" },
281
+ { "id": "shift_jane_1", "type": "Binary" },
282
+ { "id": "shift_jane_2", "type": "Binary" }
283
+ ],
284
+ "objective": {
285
+ "direction": "Minimize",
286
+ "terms": [
287
+ { "var": "shift_john_1", "coef": 1 },
288
+ { "var": "shift_john_2", "coef": 1 },
289
+ { "var": "shift_jane_1", "coef": 1 },
290
+ { "var": "shift_jane_2", "coef": 1 }
291
+ ]
292
+ },
293
+ "constraints": [
294
+ {
295
+ "id": "min_nurses_shift1",
296
+ "lower_bound": 2.0,
297
+ "terms": [
298
+ { "var": "shift_john_1", "coef": 1 },
299
+ { "var": "shift_jane_1", "coef": 1 }
300
+ ]
301
+ },
302
+ {
303
+ "id": "min_nurses_shift2",
304
+ "lower_bound": 2.0,
305
+ "terms": [
306
+ { "var": "shift_john_2", "coef": 1 },
307
+ { "var": "shift_jane_2", "coef": 1 }
308
+ ]
309
+ }
310
+ ]
311
+ }
312
+ ```
313
+
314
+ ## API Reference
315
+
316
+ ### OptimizationEngine
317
+
318
+ Main engine for running optimizations.
319
+
320
+ ```python
321
+ from pyoptima import OptimizationEngine
322
+
323
+ engine = OptimizationEngine()
324
+
325
+ # From file
326
+ result = engine.optimize_from_file("config.json")
327
+
328
+ # From config object
329
+ from pyoptima import parse_config_file
330
+ config = parse_config_file("config.json")
331
+ result = engine.optimize(config)
332
+ ```
333
+
334
+ ### OptimizationResult
335
+
336
+ Result object containing optimization results.
337
+
338
+ ```python
339
+ result.is_optimal() # Check if solution is optimal
340
+ result.objective_value # Objective function value
341
+ result.variables # Dictionary of variable values
342
+ result.status # Status string
343
+ result.to_dict() # Convert to dictionary
344
+ ```
345
+
346
+ ## Supported Solvers
347
+
348
+ ### CBC (COIN-OR Branch and Cut)
349
+
350
+ - **Installation**: `pip install pyoptima[cbc]`
351
+ - **Requirements**: PuLP library
352
+ - **Best for**: General-purpose linear and integer programming
353
+
354
+ ### Gurobi
355
+
356
+ - **Installation**: `pip install pyoptima[gurobi]`
357
+ - **Requirements**: Gurobi license (academic or commercial)
358
+ - **Best for**: Large-scale optimization problems
359
+
360
+ ### GLPK (GNU Linear Programming Kit)
361
+
362
+ - **Installation**: `pip install pyoptima[glpk]`
363
+ - **Requirements**: PuLP library
364
+ - **Best for**: Open-source alternative to commercial solvers
365
+
366
+ ## Development Setup
367
+
368
+ ### Quick Setup
369
+
370
+ ```bash
371
+ # Clone repository
372
+ cd pyoptima
373
+
374
+ # Install in development mode
375
+ pip install -e ".[dev,all]"
376
+
377
+ # Run tests
378
+ pytest
379
+ ```
380
+
381
+ ## Requirements
382
+
383
+ - Python 3.10+
384
+ - Pydantic >= 2.0.0
385
+ - Solver-specific dependencies (see installation section)
386
+
387
+ ## License
388
+
389
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
390
+
391
+ ## Contributing
392
+
393
+ Contributions are welcome! Please feel free to submit a Pull Request.
394
+
395
+ 1. Fork the repository
396
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
397
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
398
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
399
+ 5. Open a Pull Request
400
+
401
+ ---
402
+
403
+ **Made with ❤️ for the Python optimization community**
404
+