Source code for quantum_launcher.problems.problem_initialization.qatm
1""" This module contains the QATM class."""
2import os
3
4import numpy as np
5import pandas as pd
6
7from quantum_launcher.base import Problem
8
9
[docs]
10class QATM(Problem):
11 """
12 Class for Quantum Aircraft Traffic Management (QATM) problem.
13
14 This class represents Quantum Aircraft Traffic Management (QATM) problem which is a combinatorial optimization problem
15 that involves scheduling a set of aircrafts on a set of manouvers. Each aircraft consists of a sequence of manouvers
16 that must be performed. The objective is to find a schedule that minimizes the number of collisions between aircrafts.
17 The class contains an instance of the problem, so it can be passed into Quantum Launcher.
18
19 Attributes:
20 onehot (str): The one-hot encoding used for the problem.
21 instance (dict): The instance of the problem.
22 instance_name (str | None): The name of the instance.
23 instance_path (str): The path to the instance file.
24
25 """
26
27 def __init__(self, onehot: str = 'exact', instance: any = None, instance_name: str | None = None,
28 optimization_problem: bool = False) -> None:
29 super().__init__(instance=instance, instance_name=instance_name)
30 self.onehot = onehot
31 self.optimization_problem = optimization_problem
32
33 @property
34 def setup(self) -> dict:
35 return {
36 'onehot': self.onehot,
37 'instance_name': self.instance_name
38 }
39
40 def _get_path(self) -> str:
41 return f'{self.name}@{self.instance_name.split(".", 1)[0]}'
42
[docs]
43 @classmethod
44 def from_file(cls, instance_path: str, instance_name: str):
45 cm_path = os.path.join(instance_path, 'CM_' + instance_name)
46 aircrafts_path = os.path.join(
47 instance_path, 'aircrafts_' + instance_name)
48
49 instance = {'cm': np.loadtxt(cm_path), 'aircrafts': pd.read_csv(aircrafts_path, delimiter=' ', names=['manouver', 'aircraft'])}
50 return QATM('exact', instance, instance_name)
51
[docs]
52 def analyze_result(self, result: dict):
53 """
54 Analyzes the result in terms of collisions and violations of onehot constraint.
55
56 Parameters:
57 result (dict): A dictionary where keys are bitstrings and values are probabilities.
58
59 Returns:
60 dict: A dictionary containing collisions, onehot violations, and changes as ndarrays.
61 """
62 keys = list(result.keys())
63 vectorized_result = (np.fromstring(
64 "".join(keys), 'u1') - ord('0')).reshape(len(result), -1)
65
66 cm = self.instance['cm'].copy().astype(int)
67 np.fill_diagonal(cm, 0)
68 collisions = np.einsum(
69 'ij,ij->i', vectorized_result @ cm, vectorized_result) / 2
70
71 df = pd.DataFrame(vectorized_result.transpose())
72 df['aircraft'] = self.instance['aircrafts']['aircraft']
73 onehot_violations = (df.groupby(by='aircraft').sum()
74 != 1).sum(axis=0).ravel()
75
76 df['manouver'] = self.instance['aircrafts']['manouver']
77 no_changes = df[df['aircraft'] == df['manouver']]
78 changes = (len(no_changes) - no_changes.drop(
79 ['manouver', 'aircraft'], axis=1).sum()).ravel().astype(int)
80 changes[onehot_violations != 0] = -1
81
82 at_least_one = (df.loc[:, df.columns != 'manouver'].groupby(
83 'aircraft').sum() > 0).all().ravel().astype(int)
84
85 return {'collisions': collisions,
86 'onehot_violations': onehot_violations,
87 'changes': changes,
88 'at_least_one': at_least_one}