eqc-models 0.10.2__tar.gz → 0.11.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.
- {eqc_models-0.10.2/eqc_models.egg-info → eqc_models-0.11.0}/PKG-INFO +3 -2
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/__init__.py +3 -1
- eqc_models-0.11.0/eqc_models/base/results.py +94 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/combinatorics/setcover.py +34 -17
- eqc_models-0.11.0/eqc_models/sequence/scheduling.py +29 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0/eqc_models.egg-info}/PKG-INFO +3 -2
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models.egg-info/SOURCES.txt +3 -0
- eqc_models-0.11.0/scripts/results_example.py +31 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testsetcovermodel.py +3 -3
- {eqc_models-0.10.2 → eqc_models-0.11.0}/.gitlab-ci.yml +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/LICENSE.txt +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/MANIFEST.in +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/README.md +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/compile_extensions.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/Makefile +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/basic.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/css/badge_only.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/css/theme.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/custom.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/file.png +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/minus.png +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/plus.png +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/pygments.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/build/html/_static/white_logo.png +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/make.bat +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/_static/custom.css +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/_static/white_logo.png +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/conf.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/dependencies.rst +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/eqc_models.rst +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/index.rst +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/modules.rst +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/docs/source/usage.rst +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/algorithms/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/algorithms/base.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/algorithms/penaltymultiplier.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/allocation/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/allocation/allocation.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/allocation/portbase.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/allocation/portmomentum.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/assignment/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/assignment/qap.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/assignment/setpartition.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/base.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/constraints.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/operators.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/polyeval.c +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/polyeval.pyx +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/polynomial.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/base/quadratic.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/combinatorics/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/combinatorics/setpartition.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/decoding.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/base.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/hypergraph.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/maxcut.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/maxkcut.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/graph/partition.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/classifierbase.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/classifierqboost.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/classifierqsvm.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/clustering.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/clusteringbase.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/cvqboost_hamiltonian.pyx +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/cvqboost_hamiltonian_c_func.c +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/cvqboost_hamiltonian_c_func.h +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/decomposition.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/forecast.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/forecastbase.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/regressor.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/regressorbase.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/ml/reservoir.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/sequence/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/sequence/tsp.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/solvers/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/solvers/qciclient.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/utilities/__init__.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/utilities/fileio.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/utilities/polynomial.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models/utilities/qplib.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models.egg-info/dependency_links.txt +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models.egg-info/requires.txt +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/eqc_models.egg-info/top_level.txt +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/pyproject.toml +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/binary_job_example.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/c6h6_graph_clustering.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/clustering.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/continuous_job_example.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/duality_example.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/graph_clustering.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/graph_partitioning.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/hamiltonian_to_polynomial.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/hypergraph.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/integer_job_example.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/karate_graph_clustering.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/lin_reg_dirac3.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/mackey_glass_cell_production_series.csv +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/pca_iris_dirac3.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/port_opt_dirac3.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/qboost_iris_dirac3.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/qplib_benchmark_config.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/qplib_reader.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/qplib_runner.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/qsvm_iris_dirac3.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/reservoir_forecast.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/rundoctests.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/scripts/utils.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/setup.cfg +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/doctest_base.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testallocationmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testconstraint.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testcvqboost.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testeqcdirectsolver.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testgraphpartitionmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testhypergraphmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testmaxcutmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testpolynomialmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testqapmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testqciclientsolver.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testquadraticmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testsetpartitionmodel.py +0 -0
- {eqc_models-0.10.2 → eqc_models-0.11.0}/test/testtsp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: eqc-models
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Optimization and ML modeling package targeting EQC devices
|
|
5
5
|
Author: Quantum Computing Inc.
|
|
6
6
|
Author-email: support@quantumcomputinginc.com
|
|
@@ -22,6 +22,7 @@ Provides-Extra: dev
|
|
|
22
22
|
Requires-Dist: pytest<8,>=7.1.0; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
24
24
|
Requires-Dist: sphinx_rtd_theme<2,>=1.3.0; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
# EQC Models
|
|
27
28
|
|
|
@@ -65,8 +65,10 @@ from .quadratic import (ConstrainedQuadraticModel, QuadraticModel)
|
|
|
65
65
|
from .polynomial import (PolynomialModel, ConstrainedPolynomialModel)
|
|
66
66
|
from .base import (ModelSolver, EqcModel)
|
|
67
67
|
from .operators import (QUBO, Polynomial)
|
|
68
|
+
from .results import SolutionResults
|
|
68
69
|
|
|
69
70
|
__all__ = ["ConstraintsMixIn", "ConstraintModel", "ConstrainedQuadraticModel",
|
|
70
71
|
"QuadraticModel", "PolynomialModel", "ConstrainedPolynomialModel",
|
|
71
72
|
"InequalitiesMixin", "InequalityConstraintModel",
|
|
72
|
-
"EqcModel", "ModelSolver", "QUBO", "Polynomial"
|
|
73
|
+
"EqcModel", "ModelSolver", "QUBO", "Polynomial",
|
|
74
|
+
"SolutionResults"]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import warnings
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
@dataclasses.dataclass
|
|
6
|
+
class SolutionResults:
|
|
7
|
+
"""
|
|
8
|
+
The class is meant to provide a uniform interface to results, no matter
|
|
9
|
+
the method of running the job.
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
solutions : np.ndarray
|
|
14
|
+
energies : np.ndarray
|
|
15
|
+
counts : np.array
|
|
16
|
+
objectives : np.ndarray
|
|
17
|
+
run_time : np.ndarray
|
|
18
|
+
preprocessing_time : np.ndarray
|
|
19
|
+
postprocessing_time : np.ndarray
|
|
20
|
+
penalties : np.ndarray = None
|
|
21
|
+
device : str = None
|
|
22
|
+
time_units : str = "ns"
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def device_time(self):
|
|
26
|
+
pre = self.preprocessing_time
|
|
27
|
+
runtime = np.sum(self.run_time)
|
|
28
|
+
post = np.sum(self.postprocessing_time)
|
|
29
|
+
return pre + runtime + post
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def total_samples(self):
|
|
33
|
+
return np.sum(self.counts)
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def best_energy(self):
|
|
37
|
+
return np.min(self.energies)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def determine_device_type(cls, device_config):
|
|
41
|
+
"""
|
|
42
|
+
Use the device config object from a cloud response
|
|
43
|
+
to get the device info. It will have a device and job type
|
|
44
|
+
identifiers in it.
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
devices = [k for k in device_config.keys()]
|
|
48
|
+
# only one device type is supported at a time
|
|
49
|
+
return devices[0]
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_cloud_response(cls, model, response, solver):
|
|
53
|
+
""" Fill in the details from the cloud """
|
|
54
|
+
|
|
55
|
+
solutions = np.array(response["results"]["solutions"])
|
|
56
|
+
energies = np.array(response["results"]["energies"])
|
|
57
|
+
if hasattr(model, "evaluateObjective"):
|
|
58
|
+
objectives = np.zeros((solutions.shape[0],), dtype=np.float32)
|
|
59
|
+
for i in range(solutions.shape[0]):
|
|
60
|
+
try:
|
|
61
|
+
objective = model.evaluateObjective(solutions[i])
|
|
62
|
+
except NotImplementedError:
|
|
63
|
+
warnings.warn(f"Cannot set objective value in results for {model.__class__}")
|
|
64
|
+
objectives = None
|
|
65
|
+
break
|
|
66
|
+
objectives[i] = objective
|
|
67
|
+
else:
|
|
68
|
+
objectives = None
|
|
69
|
+
if hasattr(model, "evaluatePenalties"):
|
|
70
|
+
penalties = np.zeros((solutions.shape[0],), dtype=np.float32)
|
|
71
|
+
for i in range(solutions.shape[0]):
|
|
72
|
+
penalties[i] = model.evaluatePenalty(solution[i]) + model.offset
|
|
73
|
+
else:
|
|
74
|
+
penalties = None
|
|
75
|
+
counts = np.array(response["results"]["counts"])
|
|
76
|
+
# interrogate to determine the device type
|
|
77
|
+
try:
|
|
78
|
+
device_type = cls.determine_device_type(response["job_info"]["job_submission"]["device_config"])
|
|
79
|
+
except KeyError:
|
|
80
|
+
print(response.keys())
|
|
81
|
+
raise
|
|
82
|
+
job_id = response["job_info"]["job_id"]
|
|
83
|
+
metrics = solver.client.get_job_metrics(job_id=job_id)
|
|
84
|
+
metrics = metrics["job_metrics"]
|
|
85
|
+
time_ns = metrics["time_ns"]
|
|
86
|
+
device = time_ns["device"][device_type]
|
|
87
|
+
runtime = device["samples"]["runtime"]
|
|
88
|
+
post = device["samples"]["postprocessing_time"]
|
|
89
|
+
pre = device["samples"]["preprocessing_time"]
|
|
90
|
+
results = SolutionResults(solutions, energies, counts, objectives,
|
|
91
|
+
runtime, pre, post, penalties=penalties,
|
|
92
|
+
device=device_type, time_units="ns")
|
|
93
|
+
|
|
94
|
+
return results
|
|
@@ -41,41 +41,57 @@ class SetCoverModel(ConstrainedQuadraticModel):
|
|
|
41
41
|
>>> X = [set(['A', 'B']), set(['B', 'C']), set(['C'])]
|
|
42
42
|
>>> weights = [2, 2, 1]
|
|
43
43
|
>>> model = SetCoverModel(X, weights)
|
|
44
|
-
>>> model.penalty_multiplier =
|
|
44
|
+
>>> model.penalty_multiplier = 8
|
|
45
|
+
>>> lhs, rhs = model.constraints
|
|
46
|
+
>>> lhs
|
|
47
|
+
array([[ 1, 0, 0, 0, 0],
|
|
48
|
+
[ 1, 1, 0, -1, 0],
|
|
49
|
+
[ 0, 1, 1, 0, -1]])
|
|
45
50
|
>>> from eqc_models.solvers import Dirac3IntegerCloudSolver
|
|
46
51
|
>>> solver = Dirac3IntegerCloudSolver()
|
|
47
52
|
>>> response = solver.solve(model, relaxation_schedule=1, num_samples=5) #doctest: +ELLIPSIS
|
|
48
53
|
20...
|
|
49
54
|
>>> solutions = response["results"]["solutions"]
|
|
50
55
|
>>> solutions[0]
|
|
51
|
-
[1, 0, 1, 0, 0
|
|
52
|
-
>>> model.decode(solutions[0])
|
|
53
|
-
|
|
56
|
+
[1, 0, 1, 0, 0]
|
|
57
|
+
>>> selections = model.decode(solutions[0])
|
|
58
|
+
>>> assert {'B', 'A'} in selections
|
|
59
|
+
>>> assert {'C'} in selections
|
|
60
|
+
>>> assert len(selections) == 2
|
|
54
61
|
|
|
55
62
|
"""
|
|
56
63
|
|
|
57
64
|
def __init__(self, subsets, weights):
|
|
58
65
|
# ensure that X is ordered
|
|
59
|
-
self.
|
|
60
|
-
self.
|
|
66
|
+
self.S = S = list(subsets)
|
|
67
|
+
self.universal_set = U = set()
|
|
61
68
|
|
|
62
69
|
for x in subsets:
|
|
63
|
-
|
|
70
|
+
U.update(x)
|
|
64
71
|
# elements is sorted to maintain consistent output
|
|
65
|
-
elements = [a for a in
|
|
72
|
+
elements = [a for a in U]
|
|
66
73
|
elements.sort()
|
|
67
74
|
# constraints
|
|
68
75
|
A = []
|
|
69
76
|
b = []
|
|
70
|
-
variables = [f'x_{i}' for i in range(len(
|
|
77
|
+
variables = [f'x_{i}' for i in range(len(S))]
|
|
71
78
|
pos = 0
|
|
79
|
+
num_slacks = 0
|
|
80
|
+
slack_ub = []
|
|
72
81
|
for a in elements:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
num_sets = sum([1 if a in S[i] else 0 for i in range(len(S))])
|
|
83
|
+
assert num_sets >= 1, "Invalid subsets, check the universal set"
|
|
84
|
+
if num_sets > 1:
|
|
85
|
+
num_slacks += 1
|
|
86
|
+
slack_ub.append(num_sets-1)
|
|
87
|
+
for i, a in enumerate(elements):
|
|
88
|
+
constraint = [1 if a in S[j] else 0 for j in range(len(S))]
|
|
89
|
+
slacks = [0 for i in range(num_slacks)]
|
|
90
|
+
if slack_ub[i] > 0:
|
|
91
|
+
variables.append(f"s_{pos}")
|
|
92
|
+
slacks[pos] = -1
|
|
93
|
+
pos += 1
|
|
77
94
|
A.append(constraint + slacks)
|
|
78
|
-
pos += 1
|
|
79
95
|
b.append(1)
|
|
80
96
|
n = len(variables)
|
|
81
97
|
J = np.zeros((n, n))
|
|
@@ -84,11 +100,12 @@ class SetCoverModel(ConstrainedQuadraticModel):
|
|
|
84
100
|
# call the superclass constructor with the objective and constraints
|
|
85
101
|
super(SetCoverModel, self).__init__(h, J, np.array(A), np.array(b))
|
|
86
102
|
# set upper bound on the variables to be 1 for x_i and the length of X minus 1 for the slacks
|
|
87
|
-
|
|
103
|
+
slack_ub = [val for val in slack_ub if val > 0]
|
|
104
|
+
self.upper_bound = np.array([1 for i in range(len(weights))] + slack_ub)
|
|
88
105
|
|
|
89
106
|
def decode(self, solution) -> List:
|
|
90
107
|
xbar = []
|
|
91
|
-
for i in range(len(self.
|
|
108
|
+
for i in range(len(self.S)):
|
|
92
109
|
if solution[i] > 0.5:
|
|
93
|
-
xbar.append(self.
|
|
110
|
+
xbar.append(self.S[i])
|
|
94
111
|
return xbar
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from eqc_models.base.quadratic import ConstrainedQuadraticModel
|
|
3
|
+
from eqc_models.base.constraints import InequalitiesMixin
|
|
4
|
+
|
|
5
|
+
class CrewSchedulingModel(ConstrainedQuadraticModel):
|
|
6
|
+
"""
|
|
7
|
+
Crew scheduling model
|
|
8
|
+
|
|
9
|
+
Parameters
|
|
10
|
+
------------
|
|
11
|
+
|
|
12
|
+
crews : List
|
|
13
|
+
tasks : List
|
|
14
|
+
|
|
15
|
+
>>> crews = [{"name": "Maintenance Crew 1", "skills": ["A", "F"]},
|
|
16
|
+
... {"name": "Baggage Crew 1", "skills": ["B"]},
|
|
17
|
+
... {"name": "Maintenance Crew 2", "skills": ["A", "F"]}]
|
|
18
|
+
>>> tasks = [{"name": "Refuel", "skill_need": "F"},
|
|
19
|
+
... {"name": "Baggage", "skill_need": "B"}]
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, crews, tasks):
|
|
24
|
+
self.crews = crews
|
|
25
|
+
self.tasks = tasks
|
|
26
|
+
|
|
27
|
+
def decode(self, solution) -> np.ndarray:
|
|
28
|
+
""" Translate the solution into a list of tasks for each crew """
|
|
29
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: eqc-models
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Optimization and ML modeling package targeting EQC devices
|
|
5
5
|
Author: Quantum Computing Inc.
|
|
6
6
|
Author-email: support@quantumcomputinginc.com
|
|
@@ -22,6 +22,7 @@ Provides-Extra: dev
|
|
|
22
22
|
Requires-Dist: pytest<8,>=7.1.0; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
24
24
|
Requires-Dist: sphinx_rtd_theme<2,>=1.3.0; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
# EQC Models
|
|
27
28
|
|
|
@@ -48,6 +48,7 @@ eqc_models/base/polyeval.c
|
|
|
48
48
|
eqc_models/base/polyeval.pyx
|
|
49
49
|
eqc_models/base/polynomial.py
|
|
50
50
|
eqc_models/base/quadratic.py
|
|
51
|
+
eqc_models/base/results.py
|
|
51
52
|
eqc_models/combinatorics/__init__.py
|
|
52
53
|
eqc_models/combinatorics/setcover.py
|
|
53
54
|
eqc_models/combinatorics/setpartition.py
|
|
@@ -73,6 +74,7 @@ eqc_models/ml/regressor.py
|
|
|
73
74
|
eqc_models/ml/regressorbase.py
|
|
74
75
|
eqc_models/ml/reservoir.py
|
|
75
76
|
eqc_models/sequence/__init__.py
|
|
77
|
+
eqc_models/sequence/scheduling.py
|
|
76
78
|
eqc_models/sequence/tsp.py
|
|
77
79
|
eqc_models/solvers/__init__.py
|
|
78
80
|
eqc_models/solvers/qciclient.py
|
|
@@ -101,6 +103,7 @@ scripts/qplib_reader.py
|
|
|
101
103
|
scripts/qplib_runner.py
|
|
102
104
|
scripts/qsvm_iris_dirac3.py
|
|
103
105
|
scripts/reservoir_forecast.py
|
|
106
|
+
scripts/results_example.py
|
|
104
107
|
scripts/rundoctests.py
|
|
105
108
|
scripts/utils.py
|
|
106
109
|
test/doctest_base.py
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from eqc_models.solvers import Dirac3ContinuousCloudSolver
|
|
2
|
+
from eqc_models.base import PolynomialModel
|
|
3
|
+
from eqc_models.base import SolutionResults
|
|
4
|
+
|
|
5
|
+
def solve_polynomial(polynomial_coefficients, polynomial_indices, upper_bound, solver, **kwargs):
|
|
6
|
+
|
|
7
|
+
model = PolynomialModel(polynomial_coefficients, polynomial_indices)
|
|
8
|
+
model.upper_bound = ub
|
|
9
|
+
|
|
10
|
+
response = solver.solve(model, **kwargs)
|
|
11
|
+
|
|
12
|
+
results = SolutionResults.from_cloud_response(model, response, solver)
|
|
13
|
+
|
|
14
|
+
return results
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
import os.path
|
|
18
|
+
import json
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
coefficients = np.array([-1, -1, 1])
|
|
22
|
+
indices = np.array([[1, 1], [2, 2], [1, 2]])
|
|
23
|
+
ub = [1, 1]
|
|
24
|
+
solver = Dirac3ContinuousCloudSolver()
|
|
25
|
+
results = solve_polynomial(coefficients, indices, ub, solver, num_samples=2, relaxation_schedule=1, sum_constraint=1)
|
|
26
|
+
|
|
27
|
+
print("Job results:")
|
|
28
|
+
print("Solution energies:", results.energies)
|
|
29
|
+
print("Solutions:", results.solutions)
|
|
30
|
+
print("Total device time:", results.device_time)
|
|
31
|
+
print("Average device time:", results.device_time / results.total_samples)
|
|
@@ -15,11 +15,11 @@ class SetCoverTestCase(TestCase):
|
|
|
15
15
|
|
|
16
16
|
def testConstraints(self):
|
|
17
17
|
lhs, rhs = self.model.constraints
|
|
18
|
-
assert lhs.shape == (3,
|
|
18
|
+
assert lhs.shape == (3, 5)
|
|
19
19
|
assert rhs.shape == (3,)
|
|
20
|
-
assert (lhs == [[1, 0, 0,
|
|
20
|
+
assert (lhs == [[1, 0, 0, 0, 0],[1, 1, 0, -1, 0],[0, 1, 1, 0, -1]]).all()
|
|
21
21
|
assert (rhs == [1, 1, 1]).all()
|
|
22
22
|
|
|
23
23
|
def testObjective(self):
|
|
24
24
|
objective = self.model.linear_objective
|
|
25
|
-
assert (objective == [2, 2, 1, 0, 0
|
|
25
|
+
assert (objective == [2, 2, 1, 0, 0]).all()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|