Source code for qlauncher.problems.problem_initialization.qatm

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