luna-quantum 1.1.0__cp312-cp312-win_amd64.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.
Files changed (276) hide show
  1. luna_quantum/__init__.py +139 -0
  2. luna_quantum/__init__.pyi +98 -0
  3. luna_quantum/_core.cp312-win_amd64.pyd +0 -0
  4. luna_quantum/_core.pyi +4286 -0
  5. luna_quantum/_utility.py +148 -0
  6. luna_quantum/_utility.pyi +20 -0
  7. luna_quantum/algorithms/__init__.py +1 -0
  8. luna_quantum/aqm_overwrites/__init__.py +3 -0
  9. luna_quantum/aqm_overwrites/model.py +184 -0
  10. luna_quantum/backends/__init__.py +1 -0
  11. luna_quantum/client/__init__.py +0 -0
  12. luna_quantum/client/controllers/__init__.py +4 -0
  13. luna_quantum/client/controllers/luna_http_client.py +37 -0
  14. luna_quantum/client/controllers/luna_platform_client.py +256 -0
  15. luna_quantum/client/controllers/luna_q.py +67 -0
  16. luna_quantum/client/controllers/luna_solve.py +129 -0
  17. luna_quantum/client/error/__init__.py +0 -0
  18. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  19. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  20. luna_quantum/client/error/luna_error.py +2 -0
  21. luna_quantum/client/error/luna_server_error.py +20 -0
  22. luna_quantum/client/error/timeout_error.py +12 -0
  23. luna_quantum/client/error/transformation_error.py +18 -0
  24. luna_quantum/client/error/utils/__init__.py +0 -0
  25. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  26. luna_quantum/client/interfaces/__init__.py +4 -0
  27. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  28. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  29. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  30. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  31. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  32. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  33. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  34. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  35. luna_quantum/client/interfaces/services/__init__.py +0 -0
  36. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  37. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  38. luna_quantum/client/interfaces/services/service_i.py +56 -0
  39. luna_quantum/client/rest_client/__init__.py +15 -0
  40. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  41. luna_quantum/client/rest_client/info_rest_client.py +74 -0
  42. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  43. luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
  44. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  45. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  46. luna_quantum/client/schemas/__init__.py +26 -0
  47. luna_quantum/client/schemas/circuit.py +48 -0
  48. luna_quantum/client/schemas/create/__init__.py +15 -0
  49. luna_quantum/client/schemas/create/circuit.py +30 -0
  50. luna_quantum/client/schemas/create/optimization.py +39 -0
  51. luna_quantum/client/schemas/create/qpu_token.py +22 -0
  52. luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
  53. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
  54. luna_quantum/client/schemas/create/qubo.py +19 -0
  55. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  56. luna_quantum/client/schemas/enums/__init__.py +0 -0
  57. luna_quantum/client/schemas/enums/call_style.py +13 -0
  58. luna_quantum/client/schemas/enums/circuit.py +42 -0
  59. luna_quantum/client/schemas/enums/model_format.py +11 -0
  60. luna_quantum/client/schemas/enums/problem.py +50 -0
  61. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  62. luna_quantum/client/schemas/enums/sense.py +8 -0
  63. luna_quantum/client/schemas/enums/status.py +40 -0
  64. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  65. luna_quantum/client/schemas/error_message.py +14 -0
  66. luna_quantum/client/schemas/model_metadata.py +35 -0
  67. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  68. luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
  69. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  70. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
  71. luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
  72. luna_quantum/client/schemas/representation.py +19 -0
  73. luna_quantum/client/schemas/solution.py +106 -0
  74. luna_quantum/client/schemas/solve_job.py +50 -0
  75. luna_quantum/client/schemas/solver_info.py +11 -0
  76. luna_quantum/client/schemas/user.py +11 -0
  77. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  78. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  79. luna_quantum/client/utils/__init__.py +0 -0
  80. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  81. luna_quantum/config.py +11 -0
  82. luna_quantum/decorators.py +248 -0
  83. luna_quantum/errors.py +34 -0
  84. luna_quantum/errors.pyi +287 -0
  85. luna_quantum/exceptions/__init__.py +0 -0
  86. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  87. luna_quantum/exceptions/luna_quantum_call_type_error.py +9 -0
  88. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  89. luna_quantum/factories/__init__.py +4 -0
  90. luna_quantum/factories/luna_solve_client_factory.py +100 -0
  91. luna_quantum/factories/usecase_factory.py +489 -0
  92. luna_quantum/py.typed +0 -0
  93. luna_quantum/solve/__init__.py +13 -0
  94. luna_quantum/solve/default_token.py +304 -0
  95. luna_quantum/solve/domain/__init__.py +0 -0
  96. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  97. luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
  98. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  99. luna_quantum/solve/domain/model_metadata.py +56 -0
  100. luna_quantum/solve/domain/solve_job.py +230 -0
  101. luna_quantum/solve/errors/__init__.py +0 -0
  102. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  103. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  104. luna_quantum/solve/errors/solve_base_error.py +5 -0
  105. luna_quantum/solve/errors/token_missing_error.py +11 -0
  106. luna_quantum/solve/interfaces/__init__.py +0 -0
  107. luna_quantum/solve/interfaces/algorithm_i.py +49 -0
  108. luna_quantum/solve/interfaces/backend_i.py +28 -0
  109. luna_quantum/solve/interfaces/usecases/__init__.py +59 -0
  110. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  111. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  112. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  113. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  114. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  115. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  116. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  117. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  118. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  119. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  120. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  121. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  122. luna_quantum/solve/interfaces/usecases/solve_job_get_by_id_usecase_i.py +27 -0
  123. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  124. luna_quantum/solve/parameters/__init__.py +0 -0
  125. luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
  126. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  127. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  128. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  129. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
  130. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
  131. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  132. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  133. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  134. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  135. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  136. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  137. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  138. luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
  139. luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
  140. luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
  141. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  142. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  149. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  150. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
  151. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  152. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  153. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +10 -0
  154. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/__init__.py +29 -0
  155. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/config.py +58 -0
  156. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/flexqaoa.py +188 -0
  157. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/optimizers.py +53 -0
  158. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/pipeline.py +164 -0
  159. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +112 -0
  160. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  161. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
  162. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  163. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
  164. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  165. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  166. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  167. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  168. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  169. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  170. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  171. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  172. luna_quantum/solve/parameters/backends/__init__.py +27 -0
  173. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  174. luna_quantum/solve/parameters/backends/aqarios_gpu.py +17 -0
  175. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  176. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  177. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  178. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  179. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  180. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  181. luna_quantum/solve/parameters/backends/cudaq/__init__.py +5 -0
  182. luna_quantum/solve/parameters/backends/cudaq/cudaq_base.py +16 -0
  183. luna_quantum/solve/parameters/backends/cudaq/cudaq_cpu.py +30 -0
  184. luna_quantum/solve/parameters/backends/cudaq/cudaq_gpu.py +32 -0
  185. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  186. luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
  187. luna_quantum/solve/parameters/backends/fda.py +17 -0
  188. luna_quantum/solve/parameters/backends/ibm.py +138 -0
  189. luna_quantum/solve/parameters/backends/qctrl.py +103 -0
  190. luna_quantum/solve/parameters/backends/zib.py +17 -0
  191. luna_quantum/solve/parameters/constants.py +11 -0
  192. luna_quantum/solve/parameters/errors.py +30 -0
  193. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  194. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  195. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  196. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  197. luna_quantum/solve/use_cases/__init__.py +119 -0
  198. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  199. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  200. luna_quantum/solve/use_cases/base.py +7 -0
  201. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  202. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  203. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  204. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  205. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  206. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  207. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  208. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  209. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  210. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  211. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  212. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  213. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  214. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  215. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  216. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  217. luna_quantum/solve/use_cases/longest_path.py +50 -0
  218. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  219. luna_quantum/solve/use_cases/max2sat.py +54 -0
  220. luna_quantum/solve/use_cases/max3sat.py +55 -0
  221. luna_quantum/solve/use_cases/max_clique.py +60 -0
  222. luna_quantum/solve/use_cases/max_cut.py +48 -0
  223. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  224. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  225. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  226. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  227. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  228. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  229. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  230. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  231. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  232. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  233. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  234. luna_quantum/solve/use_cases/set_cover.py +56 -0
  235. luna_quantum/solve/use_cases/set_packing.py +54 -0
  236. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  237. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  238. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  239. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  240. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  241. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  242. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  243. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  244. luna_quantum/solve/usecases/__init__.py +45 -0
  245. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  246. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  247. luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
  248. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  249. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  250. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  251. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  252. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  253. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  254. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  255. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  256. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  257. luna_quantum/solve/usecases/solve_job_get_by_id_usecase.py +44 -0
  258. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +105 -0
  259. luna_quantum/transformations.py +18 -0
  260. luna_quantum/transformations.pyi +371 -0
  261. luna_quantum/translator.py +23 -0
  262. luna_quantum/translator.pyi +869 -0
  263. luna_quantum/util/__init__.py +0 -0
  264. luna_quantum/util/active_waiting.py +79 -0
  265. luna_quantum/util/class_patcher.py +164 -0
  266. luna_quantum/util/debug_info.py +52 -0
  267. luna_quantum/util/log_utils.py +187 -0
  268. luna_quantum/util/pretty_base.py +67 -0
  269. luna_quantum/util/pydantic_utils.py +38 -0
  270. luna_quantum/utils.py +3 -0
  271. luna_quantum/utils.pyi +67 -0
  272. luna_quantum-1.1.0.dist-info/METADATA +36 -0
  273. luna_quantum-1.1.0.dist-info/RECORD +276 -0
  274. luna_quantum-1.1.0.dist-info/WHEEL +4 -0
  275. luna_quantum-1.1.0.dist-info/licenses/LICENSE +176 -0
  276. luna_quantum-1.1.0.dist-info/licenses/NOTICE +13 -0
@@ -0,0 +1,46 @@
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 GraphPartitioning(UseCase):
9
+ r"""
10
+ Graph Partitioning.
11
+
12
+ Description
13
+ -----------
14
+
15
+ The Graph Partitioning problem tries to find two equal sized partitions for a given
16
+ undirected graph with an even number of vertices, so that the number of edges
17
+ connecting the two subsets is minimized.
18
+
19
+ Links
20
+ -----
21
+
22
+ [Transformation](https://arxiv.org/abs/1302.5843)
23
+
24
+ Attributes
25
+ ----------
26
+ ### graph : Dict[int, Dict[int, Dict[str, float]]]
27
+ \n The graph, for which the partitions are to be foundin form of nested
28
+ dictionaries.
29
+ \n (e.g. fully connected graph with 3 nodes:
30
+ \n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
31
+ \n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
32
+
33
+ ### A : Optional[int]
34
+ \n Penalty parameter A panalizes violation of the constraint that makes sure
35
+ both partitions are of equal size. It can be left "None" to be estimated from
36
+ the problem graph via the papers suggestion.
37
+
38
+ ### B : Optional[int]
39
+ \n Optimization penalty parameter B penalizes each edge connecting two nodes of
40
+ different partitions. If not given it defaults to 1.
41
+ """
42
+
43
+ name: Literal["GP"] = "GP"
44
+ graph: dict[str, dict[str, dict[str, float]]]
45
+ A: int | None = None
46
+ B: int | None = 1
@@ -0,0 +1,49 @@
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 HamiltonianCycle(UseCase):
11
+ r"""
12
+ # Hamiltonian Cycle.
13
+
14
+ Description
15
+ -----------
16
+
17
+ The Hamiltonian Cycle problem, either for a directed or undirected graph, asks the
18
+ following: starting at an arbitrary node in the graph, can one travel along the
19
+ edges of the graph so that each graph will be visited exactly once and there is an
20
+ edge between the starting node and the last node?
21
+
22
+ Links
23
+ -----
24
+
25
+ [Wikipedia](https://en.wikipedia.org/wiki/Hamiltonian_path_problem)
26
+
27
+ [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 hamiltonian cycle 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: Optional[float]
39
+ \n Positive penalty value which enforces that each node is visited exactly once.
40
+ \n Default: _1.0_
41
+ """
42
+
43
+ # Hamiltonian Cycle is just TSP with B = 0.
44
+
45
+ name: Literal["HC"] = "HC"
46
+ graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
47
+ directed: bool | None = False
48
+ A: float = 1.0
49
+ B: float = 0.0
@@ -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 InducedSubGraphIsomorphism(UseCase):
11
+ r"""
12
+ # Induced Subgraph Isomorphism.
13
+
14
+ Description
15
+ -----------
16
+
17
+ Given two graphs the induced subgraph isomorphism problem is to decide if there
18
+ exists an edge invariant injective mapping from the vertices of the first graph to
19
+ the second graph.
20
+ The task is slightly different from the subgraph isomorphism problem, because here
21
+ additional edges present between two vertices in the second graph to which the
22
+ isomorphism maps, are prohibited.
23
+
24
+ This Implementation is heavily based on the subgraph isomorphism problem
25
+ implementation.
26
+ It uses slack variables to counterbalance unnecessary penalties.
27
+
28
+ Links
29
+ -----
30
+
31
+ [Wikipedia](https://en.wikipedia.org/wiki/Induced_subgraph_isomorphism_problem)
32
+
33
+ [Transformation](https://researchspace.auckland.ac.nz/bitstream/handle/2292/31756/CDMTCS499.pdf)
34
+
35
+ Attributes
36
+ ----------
37
+ ### graph1: Dict[int, Dict[int, Dict[str, float]]]
38
+ \n The first graph in form of nested dictionaries.
39
+ \n (e.g. fully connected graph with 3 nodes:
40
+ \n _{0: {1: {}, 2: {}}, 1: {0: {}, 2: {}}, 2: {0: {}, 1: {}}}_
41
+ \n or _networkx.to_dict_of_dicts(networkx.complete_graph(3))_ )
42
+
43
+ ### graph2: Dict[int, Dict[int, Dict[str, float]]]
44
+ \n The second graph, on which the first one is to be mapped, also in form of
45
+ nested dictionaries.
46
+ """
47
+
48
+ name: Literal["ISGI"] = "ISGI"
49
+ graph1: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
50
+ graph2: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
@@ -0,0 +1,44 @@
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 JobShopScheduling(UseCase):
11
+ r"""
12
+ # Job Shop Scheduling.
13
+
14
+ Description
15
+ -----------
16
+
17
+ Consider a number of jobs, each of which consists of a number of operations which
18
+ have to be processed in a specific order. Each operation has a specific machine that
19
+ it needs to be processed on and only one operation in a job can be processed at a
20
+ given time. Also, each machine can only execute one job at a time. The objective of
21
+ the Job Shop Scheduling problem is to schedule all operations in a valid sequence
22
+ while minimizing the makespan of the jobs, i.e. the completion time of the last
23
+ running job.
24
+
25
+ Links
26
+ -----
27
+
28
+ [Wikipedia](https://en.wikipedia.org/wiki/Job-shop_scheduling)
29
+
30
+ [Transformation](https://arxiv.org/pdf/1506.08479.pdf)
31
+
32
+ Attributes
33
+ ----------
34
+ ### jobs: Dict[int, List[Tuple[int, int]]]
35
+ \n A dictionary containing all jobs. Each job is a list of operations and each
36
+ operation is tuple containing the machine and the processing time.
37
+
38
+ ### T: int
39
+ \n Strict upper bound when all jobs should be finished.
40
+ """
41
+
42
+ name: Literal["JSS"] = "JSS"
43
+ jobs: dict[int, list[tuple[int, int]]] = Field(name="dict") # type: ignore[call-overload]
44
+ T: int = 0
@@ -0,0 +1,49 @@
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 KMedoidsClustering(UseCase):
9
+ r"""
10
+ # K-Medoids Clustering.
11
+
12
+ Description
13
+ -----------
14
+
15
+ The authors are concerned with k-medoids clustering and propose a quadratic
16
+ unconstrained binary optimization (*QUBO*) formulation of the problem of
17
+ identifying *k* medoids among *n* data points without having to cluster the data.
18
+ Given our *QUBO* formulation of this NP-hard problem, it should be possible to solve
19
+ it on adiabatic quantum computers.
20
+
21
+ Q-Bit Interpretation
22
+ --------------------
23
+
24
+ "The qubit vector at index _k_ is 1 iff. data point _k_ from the distance matrix is
25
+ chosen as medoid of a cluster. The step of assigning the remaining data points to
26
+ clusters is not covered in this problem but can be easily done in linear time with
27
+ respect to the number of data points."
28
+
29
+ Links
30
+ -----
31
+
32
+ [Transformation](http://ceur-ws.org/Vol-2454/paper_39.pdf)
33
+
34
+ Attributes
35
+ ----------
36
+ D : List[List[float]]
37
+ \n The (*n x n*) similarity matrix (diagonal elements are *1* (*one*)).
38
+
39
+ k : int
40
+ \n The number of medoids.
41
+
42
+ gamma : float
43
+ \n Penalty coefficient to enforce feasibility.
44
+ """
45
+
46
+ name: Literal["KMC"] = "KMC"
47
+ D: list[list[float]]
48
+ k: int
49
+ gamma: float
@@ -0,0 +1,56 @@
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 KnapsackIntegerWeights(UseCase):
9
+ r"""
10
+ # Knapsack with Integer Weights.
11
+
12
+ Description
13
+ -----------
14
+
15
+ Given a knapsack that can only carry a weight _W_ and a set of objects, each object
16
+ having a weight _w_ and a value _c_, the Knapsack with Integer Weights problem tries
17
+ to find objects so that the sum of their values is maximized while, at the same
18
+ time, the sum of their weights does not exceed the capacity of the knapsack.
19
+
20
+ Links
21
+ -----
22
+
23
+ [Description and Transformation](https://arxiv.org/pdf/1302.5843.pdf)
24
+
25
+ Attributes
26
+ ----------
27
+ ### w: List[int]
28
+ \n The weight of each object.
29
+
30
+ ### c: List[float]
31
+ \n The value of each object.
32
+
33
+ ### W: int
34
+ \n The weight that the knapsack can carry.
35
+
36
+ ### B: float
37
+ \n A positive constant to reward putting an object into the knapsack.
38
+ \n Default: _1_
39
+
40
+ ### A: Optional[float]
41
+ \n A positive penalty value, enforcing that the maximal weight will not be
42
+ exceeded. If specified, the equation _A > B _max_(c)_ must hold. If not
43
+ specified, will be computed automatically as _A = 1 + B _max_(c)_.
44
+
45
+ ### linear_encoding: bool
46
+ \n If false, the number of qubits will be highly reduced, using the log trick
47
+ from section 2.4 of the paper linked above.
48
+ """
49
+
50
+ name: Literal["KIW"] = "KIW"
51
+ w: list[int]
52
+ c: list[float]
53
+ W: int
54
+ B: float = 1.0
55
+ A: float | None = None
56
+ linear_encoding: bool = False
@@ -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