luna-quantum 1.0.8rc2__cp314-cp314-manylinux_2_34_x86_64.whl
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.
Potentially problematic release.
This version of luna-quantum might be problematic. Click here for more details.
- luna_quantum/__init__.py +121 -0
- luna_quantum/__init__.pyi +85 -0
- luna_quantum/_core.cpython-314-x86_64-linux-gnu.so +0 -0
- luna_quantum/_core.pyi +4185 -0
- luna_quantum/algorithms/__init__.py +1 -0
- luna_quantum/aqm_overwrites/__init__.py +3 -0
- luna_quantum/aqm_overwrites/model.py +184 -0
- luna_quantum/backends/__init__.py +1 -0
- luna_quantum/client/__init__.py +0 -0
- luna_quantum/client/controllers/__init__.py +4 -0
- luna_quantum/client/controllers/luna_http_client.py +37 -0
- luna_quantum/client/controllers/luna_platform_client.py +256 -0
- luna_quantum/client/controllers/luna_q.py +67 -0
- luna_quantum/client/controllers/luna_solve.py +129 -0
- luna_quantum/client/error/__init__.py +0 -0
- luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
- luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
- luna_quantum/client/error/luna_error.py +2 -0
- luna_quantum/client/error/luna_server_error.py +20 -0
- luna_quantum/client/error/timeout_error.py +12 -0
- luna_quantum/client/error/transformation_error.py +18 -0
- luna_quantum/client/error/utils/__init__.py +0 -0
- luna_quantum/client/error/utils/http_error_utils.py +112 -0
- luna_quantum/client/interfaces/__init__.py +4 -0
- luna_quantum/client/interfaces/clients/__init__.py +25 -0
- luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
- luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
- luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
- luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
- luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
- luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
- luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
- luna_quantum/client/interfaces/services/__init__.py +0 -0
- luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
- luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
- luna_quantum/client/interfaces/services/service_i.py +56 -0
- luna_quantum/client/rest_client/__init__.py +15 -0
- luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
- luna_quantum/client/rest_client/info_rest_client.py +74 -0
- luna_quantum/client/rest_client/model_rest_client.py +216 -0
- luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
- luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
- luna_quantum/client/rest_client/users_rest_client.py +35 -0
- luna_quantum/client/schemas/__init__.py +26 -0
- luna_quantum/client/schemas/circuit.py +48 -0
- luna_quantum/client/schemas/create/__init__.py +15 -0
- luna_quantum/client/schemas/create/circuit.py +30 -0
- luna_quantum/client/schemas/create/optimization.py +39 -0
- luna_quantum/client/schemas/create/qpu_token.py +22 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
- luna_quantum/client/schemas/create/qubo.py +19 -0
- luna_quantum/client/schemas/create/solve_job_create.py +43 -0
- luna_quantum/client/schemas/enums/__init__.py +0 -0
- luna_quantum/client/schemas/enums/call_style.py +13 -0
- luna_quantum/client/schemas/enums/circuit.py +42 -0
- luna_quantum/client/schemas/enums/model_format.py +11 -0
- luna_quantum/client/schemas/enums/problem.py +50 -0
- luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
- luna_quantum/client/schemas/enums/sense.py +8 -0
- luna_quantum/client/schemas/enums/status.py +40 -0
- luna_quantum/client/schemas/enums/timeframe.py +11 -0
- luna_quantum/client/schemas/error_message.py +14 -0
- luna_quantum/client/schemas/model_metadata.py +35 -0
- luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
- luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
- luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
- luna_quantum/client/schemas/representation.py +19 -0
- luna_quantum/client/schemas/solution.py +106 -0
- luna_quantum/client/schemas/solve_job.py +50 -0
- luna_quantum/client/schemas/solver_info.py +11 -0
- luna_quantum/client/schemas/user.py +11 -0
- luna_quantum/client/schemas/wrappers/__init__.py +5 -0
- luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
- luna_quantum/client/utils/__init__.py +0 -0
- luna_quantum/client/utils/qpu_token_utils.py +147 -0
- luna_quantum/config.py +11 -0
- luna_quantum/decorators.py +248 -0
- luna_quantum/errors.py +34 -0
- luna_quantum/errors.pyi +287 -0
- luna_quantum/exceptions/__init__.py +0 -0
- luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
- luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
- luna_quantum/factories/__init__.py +4 -0
- luna_quantum/factories/luna_solve_client_factory.py +100 -0
- luna_quantum/factories/usecase_factory.py +457 -0
- luna_quantum/py.typed +0 -0
- luna_quantum/solve/__init__.py +13 -0
- luna_quantum/solve/default_token.py +304 -0
- luna_quantum/solve/domain/__init__.py +0 -0
- luna_quantum/solve/domain/abstract/__init__.py +4 -0
- luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
- luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
- luna_quantum/solve/domain/model_metadata.py +56 -0
- luna_quantum/solve/domain/solve_job.py +196 -0
- luna_quantum/solve/errors/__init__.py +0 -0
- luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
- luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
- luna_quantum/solve/errors/solve_base_error.py +5 -0
- luna_quantum/solve/errors/token_missing_error.py +11 -0
- luna_quantum/solve/interfaces/__init__.py +0 -0
- luna_quantum/solve/interfaces/algorithm_i.py +49 -0
- luna_quantum/solve/interfaces/backend_i.py +28 -0
- luna_quantum/solve/interfaces/usecases/__init__.py +55 -0
- luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
- luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
- luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
- luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
- luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
- luna_quantum/solve/parameters/__init__.py +0 -0
- luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
- luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
- luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
- luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
- luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
- luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
- luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
- luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +26 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/config.py +80 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/flex_qaoa.py +226 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +99 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/pipeline.py +87 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +102 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
- luna_quantum/solve/parameters/backends/__init__.py +22 -0
- luna_quantum/solve/parameters/backends/aqarios.py +17 -0
- luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
- luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
- luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
- luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
- luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
- luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
- luna_quantum/solve/parameters/backends/dwave.py +17 -0
- luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
- luna_quantum/solve/parameters/backends/fda.py +17 -0
- luna_quantum/solve/parameters/backends/ibm.py +138 -0
- luna_quantum/solve/parameters/backends/qctrl.py +103 -0
- luna_quantum/solve/parameters/backends/zib.py +17 -0
- luna_quantum/solve/parameters/constants.py +11 -0
- luna_quantum/solve/parameters/mixins/__init__.py +0 -0
- luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
- luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
- luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
- luna_quantum/solve/use_cases/__init__.py +119 -0
- luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
- luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
- luna_quantum/solve/use_cases/base.py +7 -0
- luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
- luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
- luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
- luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
- luna_quantum/solve/use_cases/exact_cover.py +51 -0
- luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
- luna_quantum/solve/use_cases/graph_coloring.py +42 -0
- luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
- luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
- luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
- luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
- luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
- luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
- luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
- luna_quantum/solve/use_cases/linear_regression.py +60 -0
- luna_quantum/solve/use_cases/lmwcs.py +84 -0
- luna_quantum/solve/use_cases/longest_path.py +50 -0
- luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
- luna_quantum/solve/use_cases/max2sat.py +54 -0
- luna_quantum/solve/use_cases/max3sat.py +55 -0
- luna_quantum/solve/use_cases/max_clique.py +60 -0
- luna_quantum/solve/use_cases/max_cut.py +48 -0
- luna_quantum/solve/use_cases/max_independent_set.py +37 -0
- luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
- luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
- luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
- luna_quantum/solve/use_cases/number_partitioning.py +32 -0
- luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
- luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
- luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
- luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
- luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
- luna_quantum/solve/use_cases/sensor_placement.py +58 -0
- luna_quantum/solve/use_cases/set_cover.py +56 -0
- luna_quantum/solve/use_cases/set_packing.py +54 -0
- luna_quantum/solve/use_cases/set_partitioning.py +52 -0
- luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
- luna_quantum/solve/use_cases/subset_sum.py +37 -0
- luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
- luna_quantum/solve/use_cases/traffic_flow.py +35 -0
- luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
- luna_quantum/solve/use_cases/type_aliases.py +9 -0
- luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
- luna_quantum/solve/usecases/__init__.py +45 -0
- luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
- luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
- luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
- luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
- luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
- luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
- luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
- luna_quantum/solve/usecases/model_save_usecase.py +63 -0
- luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
- luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
- luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
- luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
- luna_quantum/solve/usecases/solve_job_get_result_usecase.py +95 -0
- luna_quantum/transformations.py +18 -0
- luna_quantum/transformations.pyi +371 -0
- luna_quantum/translator.py +23 -0
- luna_quantum/translator.pyi +869 -0
- luna_quantum/util/__init__.py +0 -0
- luna_quantum/util/active_waiting.py +79 -0
- luna_quantum/util/class_patcher.py +164 -0
- luna_quantum/util/debug_info.py +52 -0
- luna_quantum/util/log_utils.py +187 -0
- luna_quantum/util/pretty_base.py +67 -0
- luna_quantum/util/pydantic_utils.py +38 -0
- luna_quantum/utils.py +3 -0
- luna_quantum/utils.pyi +67 -0
- luna_quantum-1.0.8rc2.dist-info/METADATA +36 -0
- luna_quantum-1.0.8rc2.dist-info/RECORD +264 -0
- luna_quantum-1.0.8rc2.dist-info/WHEEL +4 -0
- luna_quantum-1.0.8rc2.dist-info/licenses/LICENSE +176 -0
- luna_quantum-1.0.8rc2.dist-info/licenses/NOTICE +13 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LinearRegression(UseCase):
|
|
9
|
+
r"""
|
|
10
|
+
# Linear Regression.
|
|
11
|
+
|
|
12
|
+
Description
|
|
13
|
+
-----------
|
|
14
|
+
|
|
15
|
+
In statistics, linear regression is a linear approach to modelling the relationship
|
|
16
|
+
between a real-valued dependent variable and one or more real-valued independent
|
|
17
|
+
variables.
|
|
18
|
+
|
|
19
|
+
Q-Bit Interpretation
|
|
20
|
+
--------------------
|
|
21
|
+
|
|
22
|
+
For interpretation, the qubit vector has to be cut into (n_features + 1) sublists of
|
|
23
|
+
length K (specified below). The sum of each of the product of each of these sublists
|
|
24
|
+
and the precision vector gives an estimated feature weight.
|
|
25
|
+
|
|
26
|
+
Links
|
|
27
|
+
-----
|
|
28
|
+
|
|
29
|
+
[Wikipedia](https://en.wikipedia.org/wiki/Linear_regression)
|
|
30
|
+
|
|
31
|
+
[Transformation](https://doi.org/10.1038/s41598-021-89461-4)
|
|
32
|
+
|
|
33
|
+
Attributes
|
|
34
|
+
----------
|
|
35
|
+
### X: List[List[float]]
|
|
36
|
+
\n Training data set in form of a nested list.
|
|
37
|
+
\n All inner lists have to be of the same length.
|
|
38
|
+
\n (e.g. 3 data points with 2 features:
|
|
39
|
+
\n _[[1.1, 4.23], [0.1, -2.4], [-2.3, 1.11]]_ )
|
|
40
|
+
|
|
41
|
+
### Y: List[int]
|
|
42
|
+
\n Regression labels of the training data set.
|
|
43
|
+
\n (e.g. for 3 data points:
|
|
44
|
+
\n _[1.2, -3.4, 2.41]_ )
|
|
45
|
+
|
|
46
|
+
### K: int
|
|
47
|
+
\n Length of the precision vector.
|
|
48
|
+
\n As the problem outputs are supposed to be real values but the qubo only gives
|
|
49
|
+
a binary vector, we need a precision vector, consisting of powers of 2, to
|
|
50
|
+
simulate real values. This parameter determines the length of this vector.
|
|
51
|
+
\n (e.g. for K = 6, the precision vector is _[-2, -1, -0.5, 0.5, 1, 2]_)
|
|
52
|
+
\n This parameter also determines the size of the qubo matrix together with the
|
|
53
|
+
number of features _d_:
|
|
54
|
+
\n _size = (d + 1) * K_
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
name: Literal["LR"] = "LR"
|
|
58
|
+
X: list[list[float]]
|
|
59
|
+
Y: list[float]
|
|
60
|
+
K: int = 24
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from luna_quantum.solve.use_cases.type_aliases import NestedDictGraph
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LabeledMaxWeightedCommonSubgraph(UseCase):
|
|
14
|
+
r"""
|
|
15
|
+
# Labeled Maximum Weighted Common Subgraph.
|
|
16
|
+
|
|
17
|
+
Description
|
|
18
|
+
-----------
|
|
19
|
+
|
|
20
|
+
The Labeled Maximum Weighted Common Subgraph (LMWCS) problem finds, given two graphs
|
|
21
|
+
_G1_ and _G2_, the largest subgraph of _G1_ that is isomorphic to a subgraph of
|
|
22
|
+
_G2_. A weight is associated with each possible mapping between a node in _G1_ and a
|
|
23
|
+
node in _G2_ to model a difference in importance for different mappings between
|
|
24
|
+
nodes in the first graph and the second graph. The vertex pairs with assigned value
|
|
25
|
+
_1_ form the common subgraph. Besides the constraint on the mappings which follow
|
|
26
|
+
from requiring bijectivity, one can also define user-defined constraints.
|
|
27
|
+
|
|
28
|
+
Notes
|
|
29
|
+
-----
|
|
30
|
+
There is an error in definition of _C_ (bijectivity constraint): condition one
|
|
31
|
+
should be: _((i == m)_ or _(j == n))_ and not _((i == j)_ and _(j == n))_.
|
|
32
|
+
|
|
33
|
+
We need to map the binary vector elements _b_{i, j}_, where _i_ and _j_ describe a
|
|
34
|
+
node in the graphs 1 and 2 respectively, to an entry in a
|
|
35
|
+
_(graph1.order() * graph2.order())_ dimensional vector. Here, we say that the
|
|
36
|
+
element _b_{i, j}_ is mapped to the _(i * graph2.order() + j)_th entry of the
|
|
37
|
+
vector.
|
|
38
|
+
|
|
39
|
+
Generally, we have to fulfill _a_{(i, j), (m, n)} > min(w_{i, j}, w_{m, n})_ with
|
|
40
|
+
_w_ being the weights for the pairs _(i, j)_. Here, we choose _a > max(weights)_ as
|
|
41
|
+
if _a_ fulfills this condition for all _a_{(i, j), (m, n)}_.
|
|
42
|
+
|
|
43
|
+
Q-Bit Interpretation
|
|
44
|
+
--------------------
|
|
45
|
+
|
|
46
|
+
The tuple _(i, j)_ is part of the mapping iff. qubit _i * graph2.order() + j_ is 1.
|
|
47
|
+
|
|
48
|
+
Links
|
|
49
|
+
-----
|
|
50
|
+
|
|
51
|
+
[Transformation](https://arxiv.org/pdf/1601.06693.pdf)
|
|
52
|
+
|
|
53
|
+
Attributes
|
|
54
|
+
----------
|
|
55
|
+
### graph1: Dict[int, Dict[int, Dict[str, float]]]
|
|
56
|
+
\n First problem graph for the lmwcs problem in form of nested dictionaries.
|
|
57
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
58
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
59
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
60
|
+
|
|
61
|
+
### graph2: Dict[int, Dict[int, Dict[str, float]]]
|
|
62
|
+
\n Second problem graph for the lmwcs problem in form of nested dictionaries.
|
|
63
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
64
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
65
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
66
|
+
|
|
67
|
+
### weigths: List[float]
|
|
68
|
+
\n Weights for all pairs _(i, j)_ in _graph1.nodes x graph2.nodes_.
|
|
69
|
+
|
|
70
|
+
### a: float
|
|
71
|
+
\n Penalty for mapping violating bijectivity or user constraints.
|
|
72
|
+
|
|
73
|
+
### user_constraints: List[Tuple[Tuple[int, int], Tuple[int, int]]]
|
|
74
|
+
\n User given constraints on the vertex mapping.
|
|
75
|
+
\n _((i, j), (m, n))_ being part of the user constraints means that _(i, j)_ and
|
|
76
|
+
_(m, n)_ must not be part of the mapping at the same time.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
name: Literal["LMWCS"] = "LMWCS"
|
|
80
|
+
graph1: NestedDictGraph = Field(name="graph") # type: ignore[call-overload]
|
|
81
|
+
graph2: NestedDictGraph = Field(name="graph") # type: ignore[call-overload]
|
|
82
|
+
weights: list[float]
|
|
83
|
+
a: float
|
|
84
|
+
user_constraints: list[tuple[tuple[int, int], tuple[int, int]]] | None = None
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LongestPath(UseCase):
|
|
11
|
+
r"""
|
|
12
|
+
# Longest Path.
|
|
13
|
+
|
|
14
|
+
Description
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
The longest path problem is the problem of finding a simple path of maximum length
|
|
18
|
+
from a given start node to a given terminal node in a given graph. A path is called
|
|
19
|
+
simple if it does not have any repeated vertices.
|
|
20
|
+
|
|
21
|
+
Links
|
|
22
|
+
-----
|
|
23
|
+
|
|
24
|
+
[Wikipedia](https://en.wikipedia.org/wiki/Longest_path_problem)
|
|
25
|
+
|
|
26
|
+
[Transformation](https://www.sciencedirect.com/science/article/abs/pii/S030439752100092X#!)
|
|
27
|
+
|
|
28
|
+
Attributes
|
|
29
|
+
----------
|
|
30
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]]
|
|
31
|
+
\n Problem graph for the longest path problem in form of nested dictionaries.
|
|
32
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
33
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
34
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
35
|
+
|
|
36
|
+
### start_node:
|
|
37
|
+
\n At which node to start.
|
|
38
|
+
|
|
39
|
+
### terminal_node:
|
|
40
|
+
\n At which node to stop.
|
|
41
|
+
|
|
42
|
+
### steps:
|
|
43
|
+
\n How many nodes to include in the path.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
name: Literal["LP"] = "LP"
|
|
47
|
+
graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
|
|
48
|
+
start_node: str
|
|
49
|
+
terminal_node: str
|
|
50
|
+
steps: int
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MarketGraphClustering(UseCase):
|
|
9
|
+
r"""
|
|
10
|
+
# Market Graph Clustering.
|
|
11
|
+
|
|
12
|
+
Description
|
|
13
|
+
-----------
|
|
14
|
+
|
|
15
|
+
The authors formulate the index-tracking problem as a QUBO graph-clustering problem.
|
|
16
|
+
Their formulation restricts the number of assets while identifying the most
|
|
17
|
+
representative exemplars of an index. Their thesis is that a portfolio consisting of
|
|
18
|
+
the most representative set of exemplars will minimize tracking-error.
|
|
19
|
+
Initial results are very encouraging. Their tests show they accurately replicate the
|
|
20
|
+
returns of broad market indices, using only a small subset of their constituent
|
|
21
|
+
assets. Moreover, their QUBO formulation allows us to take advantage of recent
|
|
22
|
+
hardware advances to overcome the NP-hard nature of the clustering problem.
|
|
23
|
+
Using these novel architectures they obtain better solutions within small fractions
|
|
24
|
+
of the time required to solve equivalent problems formulated in traditional
|
|
25
|
+
constrained form and solved on traditional hardware. Their initial results certainly
|
|
26
|
+
offer hope and set the stage for larger-scale problems, in finance and beyond.
|
|
27
|
+
|
|
28
|
+
Their implementation is based on the work of *Bauckhage et al.*.
|
|
29
|
+
|
|
30
|
+
Q-Bit Interpretation
|
|
31
|
+
--------------------
|
|
32
|
+
|
|
33
|
+
"The qubit vector at index _k_ is 1 iff. stock _k_ from matrix _G_ (see below) is
|
|
34
|
+
chosen as medoid of a cluster. The step of assigning the remaining stocks to
|
|
35
|
+
clusters is not covered in this problem but can be easily done in linear time with
|
|
36
|
+
respect to the number of data points."
|
|
37
|
+
|
|
38
|
+
Links
|
|
39
|
+
-----
|
|
40
|
+
|
|
41
|
+
[Transformation (Market Graph Clustering via QUBO and Digital Annealing)](https://www.mdpi.com/1911-8074/14/1/34)
|
|
42
|
+
|
|
43
|
+
[Bauckhage et al. (A QUBO Formulation of the k-Medoids Problem)](http://ceur-ws.org/Vol-2454/paper_39.pdf)
|
|
44
|
+
|
|
45
|
+
Attributes
|
|
46
|
+
----------
|
|
47
|
+
### G: List[List[float]]
|
|
48
|
+
\n An *n x m* matrix, where *n* is the number of stocks and *m* is the number of
|
|
49
|
+
time units with returns for the respective stock at this time.
|
|
50
|
+
|
|
51
|
+
### k: int
|
|
52
|
+
\n The number of representatives desired.
|
|
53
|
+
|
|
54
|
+
### gamma: float
|
|
55
|
+
\n Penalty coefficient to enforce feasibility of the solution.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
name: Literal["MGC"] = "MGC"
|
|
59
|
+
G: list[list[float]]
|
|
60
|
+
k: int
|
|
61
|
+
gamma: float
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Provides the Max2SAT class."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from luna_quantum.solve.use_cases.type_aliases import Clause
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Max2SAT(UseCase):
|
|
16
|
+
r"""
|
|
17
|
+
# Maximum 2-SAT.
|
|
18
|
+
|
|
19
|
+
Description
|
|
20
|
+
-----------
|
|
21
|
+
|
|
22
|
+
For a formula in conjunctive normal form (CNF) with two literals per clause, the
|
|
23
|
+
Maximum 2-SAT problem determines the maximum number of clauses that can be
|
|
24
|
+
simultaneously satisfied by an assignment.
|
|
25
|
+
|
|
26
|
+
Q-Bit Interpretation
|
|
27
|
+
--------------------
|
|
28
|
+
|
|
29
|
+
Each qubit corresponds to the truth value of one of the variables, to be precise:
|
|
30
|
+
_sorted(variables)[i] == True_ iff. _qubits[i] == 1_.
|
|
31
|
+
|
|
32
|
+
Links
|
|
33
|
+
-----
|
|
34
|
+
|
|
35
|
+
[Wikipedia](https://en.wikipedia.org/wiki/2-satisfiability#Maximum-2-satisfiability)
|
|
36
|
+
|
|
37
|
+
[Transformation](https://arxiv.org/pdf/1811.11538.pdf)
|
|
38
|
+
|
|
39
|
+
Attributes
|
|
40
|
+
----------
|
|
41
|
+
### clauses: List[Tuple[Tuple[int, bool], Tuple[int, bool]]]
|
|
42
|
+
\n A list containing all clauses of the formula in CNF in form of tuples.
|
|
43
|
+
\n (e.g. the formula _x0 * x1 + -x1 * x2_:
|
|
44
|
+
\n _[((0, True), (1, True)), ((1, False), (2, True))]_ )
|
|
45
|
+
\n It is possible to use arbitrary variable indices.
|
|
46
|
+
|
|
47
|
+
### n_vars: Optional[int]
|
|
48
|
+
\n The number of different variables. Can be used to check whether the input
|
|
49
|
+
clauses have the desired number of different variables.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
name: Literal["M2SAT"] = "M2SAT"
|
|
53
|
+
clauses: list[Clause] = Field(name="clauses") # type: ignore[call-overload]
|
|
54
|
+
n_vars: int | None = None
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from luna_quantum.solve.use_cases.type_aliases import Clause
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Max3SAT(UseCase):
|
|
14
|
+
r"""
|
|
15
|
+
# Maximum 3-SAT.
|
|
16
|
+
|
|
17
|
+
Description
|
|
18
|
+
-----------
|
|
19
|
+
|
|
20
|
+
For a formula in conjunctive normal form (CNF) with three literals per clause, the
|
|
21
|
+
Maximum 3-SAT problem determines the maximum number of clauses that can be
|
|
22
|
+
simultaneously satisfied by an assignment.
|
|
23
|
+
|
|
24
|
+
Q-Bit Interpretation
|
|
25
|
+
--------------------
|
|
26
|
+
|
|
27
|
+
Let _n_ be the number of different variables and let _m_ be the number of clauses.
|
|
28
|
+
Then, each of the first _n_ qubits corresponds to the truth value of one of the
|
|
29
|
+
variables, to be precise: _sorted(variables)[i] == True_ iff. _qubits[i] == 1_. Each
|
|
30
|
+
of the last _m_ qubits tells whether the corresponding clause is fulfilled,
|
|
31
|
+
formally: _clauses[i]_ is fulfilled iff. _qubits[n + i] == 1_.
|
|
32
|
+
|
|
33
|
+
Links
|
|
34
|
+
-----
|
|
35
|
+
|
|
36
|
+
[Wikipedia](https://en.wikipedia.org/wiki/MAX-3SAT)
|
|
37
|
+
|
|
38
|
+
[Transformation](https://canvas.auckland.ac.nz/courses/14782/files/574983/download?verifier=1xqRikUjTEBwm8PnObD8YVmKdeEhZ9Ui8axW8HwP&wrap=1)
|
|
39
|
+
|
|
40
|
+
Attributes
|
|
41
|
+
----------
|
|
42
|
+
### clauses: List[Tuple[Tuple[int, bool], Tuple[int, bool], Tuple[int, bool]]]
|
|
43
|
+
\n A list containing all clauses of the formula in CNF in form of tuples.
|
|
44
|
+
\n (e.g. the formula _x0 * x1 * -x2 + -x1 * x2 * x3_:
|
|
45
|
+
\n _[((0, True), (1, True), (2, False)), ((1, False), (2, True), (3, True))]_ )
|
|
46
|
+
\n It is possible to use arbitrary variable indices.
|
|
47
|
+
|
|
48
|
+
### n_vars: Optional[int]
|
|
49
|
+
\n The number of different variables. Can be used to check whether the input
|
|
50
|
+
clauses have the desired number of different variables.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
name: Literal["M3SAT"] = "M3SAT"
|
|
54
|
+
clauses: list[Clause] = Field(name="clauses") # type: ignore[call-overload]
|
|
55
|
+
n_vars: int | None = None
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MaxClique(UseCase):
|
|
11
|
+
r"""
|
|
12
|
+
# Maximum Clique.
|
|
13
|
+
|
|
14
|
+
Description
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
The Maximum Clique problem describes the task of finding the largest sized clique in
|
|
18
|
+
a given graph. A clique is a set of nodes in a graph, where every node has an edge
|
|
19
|
+
to every other node in the clique. A k-clique denotes a clique with exactly k nodes.
|
|
20
|
+
The maximum clique of a graph is the clique with the highest possible k value.
|
|
21
|
+
|
|
22
|
+
There is a closely related problem, the decisional clique problem, which describes
|
|
23
|
+
the challenge of determining whether a clique of at least size k exists in the given
|
|
24
|
+
graph.
|
|
25
|
+
|
|
26
|
+
Math
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Links
|
|
33
|
+
-----
|
|
34
|
+
|
|
35
|
+
[Wikipedia](https://en.wikipedia.org/wiki/Clique_problem#Finding_a_single_maximal_clique)
|
|
36
|
+
|
|
37
|
+
[Transformation](https://arxiv.org/pdf/1801.08649.pdf)
|
|
38
|
+
|
|
39
|
+
Attributes
|
|
40
|
+
----------
|
|
41
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]]
|
|
42
|
+
\n Problem graph for the maximum clique problem in form of nested dictionaries.
|
|
43
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
44
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
45
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
46
|
+
|
|
47
|
+
### hard_constraints: Dict
|
|
48
|
+
\n Hard constraints that must be fulfilled by any valid instance. They are
|
|
49
|
+
defined in _aqcore.transformator.specifications.graph_specifications_.
|
|
50
|
+
|
|
51
|
+
### soft_constraints: Optional[Dict]
|
|
52
|
+
\n Desirable traits that instances should fulfill.
|
|
53
|
+
|
|
54
|
+
### check_soft_constraints: bool
|
|
55
|
+
\n Defines whether soft constraints should also be fulfilled. Default is
|
|
56
|
+
_False_.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
name: Literal["MCQ"] = "MCQ"
|
|
60
|
+
graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MaxCut(UseCase):
|
|
11
|
+
r"""
|
|
12
|
+
# Maximum Cut.
|
|
13
|
+
|
|
14
|
+
Description
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
The Maximum Cut problem tries to find a cut that maximizes the number of
|
|
18
|
+
intersecting edges in an undirected graph.
|
|
19
|
+
|
|
20
|
+
Q-Bit Interpretation
|
|
21
|
+
--------------------
|
|
22
|
+
A cut defines two sets of nodes, 0 and 1.
|
|
23
|
+
The qubits x = (x_0, x_1, ..., x_n) can be interpreted like this:
|
|
24
|
+
x_i = 0 iff. node i belongs to set 0 and x_i = 1 iff. it belongs to set 1.
|
|
25
|
+
|
|
26
|
+
Math
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
Links
|
|
32
|
+
-----
|
|
33
|
+
|
|
34
|
+
[Wikipedia](https://en.wikipedia.org/wiki/Maximum_cut)
|
|
35
|
+
|
|
36
|
+
[Transformation](https://arxiv.org/pdf/1811.11538.pdf)
|
|
37
|
+
|
|
38
|
+
Attributes
|
|
39
|
+
----------
|
|
40
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]]
|
|
41
|
+
\n Problem graph for the maximum cut problem in form of nested dictionaries.
|
|
42
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
43
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
44
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
name: Literal["MC"] = "MC"
|
|
48
|
+
graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MaxIndependentSet(UseCase):
|
|
11
|
+
r"""
|
|
12
|
+
# Maximum Independent Set.
|
|
13
|
+
|
|
14
|
+
Description
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
An independent set of a graph _G_ is a set of vertices of _G_, where every two
|
|
18
|
+
vertices are not connected by an edge in _G_. The Maximum Independent Set problem
|
|
19
|
+
tries to find the largest independent set of a graph.
|
|
20
|
+
|
|
21
|
+
Links
|
|
22
|
+
-----
|
|
23
|
+
|
|
24
|
+
[Description and Transformation](https://arxiv.org/pdf/1801.08653.pdf)
|
|
25
|
+
|
|
26
|
+
Attributes
|
|
27
|
+
----------
|
|
28
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]]
|
|
29
|
+
\n Problem graph for the maximum independent set problem in form of nested
|
|
30
|
+
dictionaries.
|
|
31
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
32
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
33
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
name: Literal["MIS"] = "MIS"
|
|
37
|
+
graph: dict[int, dict[int, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MinimalMaximalMatching(UseCase):
|
|
11
|
+
r"""
|
|
12
|
+
# Minimal Maximal Matching.
|
|
13
|
+
|
|
14
|
+
Description
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
For a graph _G = (V, E)_, the Minimal Maximal Matching problem tries to find a
|
|
18
|
+
"coloring" _C ⊆ E_ with the following three constraints:
|
|
19
|
+
\n 1. For each edge in _C_, the incident vertices shall be colored and the union of
|
|
20
|
+
all these vertices shall be called _D_.
|
|
21
|
+
\n 2. No two edges in _C_ share a vertex.
|
|
22
|
+
\n 3. If _u, v ∈ D_, then _(uv) ∉ E_.\n
|
|
23
|
+
|
|
24
|
+
Links
|
|
25
|
+
-----
|
|
26
|
+
|
|
27
|
+
[Description and Transformation](https://arxiv.org/pdf/1302.5843.pdf)
|
|
28
|
+
|
|
29
|
+
Attributes
|
|
30
|
+
----------
|
|
31
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]]
|
|
32
|
+
\n Problem graph for the minimal maximal matching problem in form of nested
|
|
33
|
+
dictionaries.
|
|
34
|
+
\n (e.g. fully connected graph with 3 nodes:
|
|
35
|
+
\n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
|
|
36
|
+
\n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
|
|
37
|
+
|
|
38
|
+
### A: int
|
|
39
|
+
\n A positive constant enforcing that no vertex has two colored edges.
|
|
40
|
+
|
|
41
|
+
### B: int
|
|
42
|
+
\n A constant to penalize when an edge is uncolored although it would not
|
|
43
|
+
violate the coloring condition. For _d_ being the maximal degree in the graph,
|
|
44
|
+
choose _A > (d - 2)B_.
|
|
45
|
+
|
|
46
|
+
### C: int
|
|
47
|
+
\n A constant (C < B) to minimize the number of colored edges.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
name: Literal["MMM"] = "MMM"
|
|
51
|
+
graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
|
|
52
|
+
A: int = 10
|
|
53
|
+
B: int = 2
|
|
54
|
+
C: int = 1
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from luna_quantum.solve.use_cases.base import UseCase
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from luna_quantum.solve.use_cases.type_aliases import NestedDictGraph
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MinimalSpanningTree(UseCase):
|
|
14
|
+
r"""
|
|
15
|
+
# Minimal Spanning Tree with maximal degree constraint.
|
|
16
|
+
|
|
17
|
+
Description
|
|
18
|
+
-----------
|
|
19
|
+
|
|
20
|
+
The Minimal Spanning Tree problem tries to find a spanning tree over all nodes in a
|
|
21
|
+
given input graph such that the cost of the covered edges (the sum of the weights
|
|
22
|
+
inside the tree) is minimal. The addition maximal degree constraint, i.e. limiting
|
|
23
|
+
the degree of the tree at each node to a maximum value, makes this problem NP-hard.
|
|
24
|
+
|
|
25
|
+
Convention on depth index of vertex and edge:
|
|
26
|
+
Zero index is vertex root and all the edges leaving from root, etc.
|
|
27
|
+
That means there are N/2 possible depths for edges and N/2 + 1 possible depths for
|
|
28
|
+
vertices.
|
|
29
|
+
|
|
30
|
+
Q-Bit Interpretation
|
|
31
|
+
--------------------
|
|
32
|
+
|
|
33
|
+
Assume we have a graph with _m_ nodes, _n_ edges, a max degree of _k_, and the qubit
|
|
34
|
+
vector _q_.
|
|
35
|
+
Then, for _i = 0, ..., n-1_, _q[i] = 1_ iff. edge _i_ is included in the tree.
|
|
36
|
+
Variables _n, ..., n + ⌈ m / 2 ⌉_ keep track of the depth of a node in the tree.
|
|
37
|
+
Now, let _a := n + ⌈ m / 2 ⌉_. Variables _a, ..., a + 2 * n_ tell for each edge in
|
|
38
|
+
the graph which vertex is closer to the root of the tree.
|
|
39
|
+
Finally, with _b := a * 2 * n_, the variables
|
|
40
|
+
_b, ..., b + m * ⌊ log2(maxDegree) + 1 ⌋_ count the degree of a node in the tree.
|
|
41
|
+
|
|
42
|
+
Links
|
|
43
|
+
-----
|
|
44
|
+
|
|
45
|
+
[Wikipedia](https://en.wikipedia.org/wiki/Degree-constrained_spanning_tree),
|
|
46
|
+
[Without degree constraint](https://en.wikipedia.org/wiki/Minimum_spanning_tree)
|
|
47
|
+
|
|
48
|
+
[Transformation](https://arxiv.org/abs/1302.5843)
|
|
49
|
+
|
|
50
|
+
Attributes
|
|
51
|
+
----------
|
|
52
|
+
### graph: Dict[int, Dict[int, Dict[str, float]]
|
|
53
|
+
\n Problem graph for the minimal spanning tree problem in form of nested
|
|
54
|
+
dictionaries. Each vertex needs to be weighted.
|
|
55
|
+
\n (e.g. Wikipedia example
|
|
56
|
+
\n _{
|
|
57
|
+
0: {1: {"weight": 1}, 3: {"weight": 4}, 4: {"weight": 3}},
|
|
58
|
+
1: {3: {"weight": 4}, 4: {"weight": 2}},
|
|
59
|
+
2: {4: {"weight": 4}, 5: {"weight": 5}},
|
|
60
|
+
3: {4: {"weight": 4}},
|
|
61
|
+
4: {5: {"weight": 7}}
|
|
62
|
+
}_ )
|
|
63
|
+
|
|
64
|
+
### max_degree : int
|
|
65
|
+
\n The maximum degree at one joint of the tree. (e.g. 2 is a special case of the
|
|
66
|
+
travelling salesman problem).
|
|
67
|
+
|
|
68
|
+
### A : Optional[float] = None.
|
|
69
|
+
\n The penalty factor for constraints. Can be left _None_ to be estimated from
|
|
70
|
+
the problem graph via the papers suggestion.
|
|
71
|
+
\n Default: _None_
|
|
72
|
+
|
|
73
|
+
### B : Optional[float] = 1.
|
|
74
|
+
\n The optimization penalty factor.
|
|
75
|
+
\n Deafult: _1_
|
|
76
|
+
|
|
77
|
+
### ba_ratio : Optional[float] = 0.1
|
|
78
|
+
\n A factor that increases or decreases the ratio between constraint and
|
|
79
|
+
model penalty factors in the automatic estimation. If constraints are
|
|
80
|
+
violated, this ratio needs to be decreased as the _A_ penalty needs to be
|
|
81
|
+
increased. _0.1_ is a good starting point.
|
|
82
|
+
\n Default: _0.1_
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
name: Literal["MST"] = "MST"
|
|
86
|
+
graph: NestedDictGraph = Field(name="graph") # type: ignore[call-overload]
|
|
87
|
+
max_degree: int
|
|
88
|
+
A: float | None = None
|
|
89
|
+
B: float | None = 1.0
|
|
90
|
+
ba_ratio: float | None = 0.1
|