From 4e87f19e12c2b8c7d07910e50f19015b1677530d Mon Sep 17 00:00:00 2001 From: miranska Date: Wed, 19 Jan 2022 20:52:37 -0500 Subject: [PATCH] Add EP-PQM-related code --- README.md | 37 +- compute_empirical_complexity.py | 224 ++++++++ datasets/SPECTrain.csv | 80 +++ datasets/balance_scale.csv | 625 +++++++++++++++++++++ datasets/breast_cancer.csv | 699 +++++++++++++++++++++++ datasets/tictactoe.csv | 958 ++++++++++++++++++++++++++++++++ datasets/zoo.csv | 101 ++++ requirements.txt | 3 +- string_comparison.py | 378 +++++++++++-- test_string_comparison.py | 27 + 10 files changed, 3089 insertions(+), 43 deletions(-) create mode 100644 compute_empirical_complexity.py create mode 100644 datasets/SPECTrain.csv create mode 100644 datasets/balance_scale.csv create mode 100644 datasets/breast_cancer.csv create mode 100644 datasets/tictactoe.csv create mode 100644 datasets/zoo.csv diff --git a/README.md b/README.md index bfcb1f8..358d88f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# String Comparison on a Quantum Computer Using Hamming Distance +# String Comparison on a Quantum Computer + +This repository contains the files needed to compare and classify the strings using Hamming distance between a string and a set of strings using a quantum computer. +For computing the distance between a target string and the closest string in the group of strings, see [preprint](https://arxiv.org/abs/2106.16173). The code for this preprint is packaged in [v0.1.0](https://github.com/miranska/qc-str/releases/tag/v0.1.0). The core code resides in `string_comparison.py`. + +Furthermore, this repository extends the above codebase by creating an efficient version of the Parametric Probabilistic Quantum Memory ([P-PQM](https://doi.org/10.1016/j.neucom.2020.01.116)) approach for computing the probability of a string belonging to a particular group of strings (i.e., a machine learning classification problem). We call our algorithm EP-PQM, see [preprint](https://arxiv.org/abs/2201.07265) for details. The code for this preprint is packaged in [v0.2.0](https://github.com/miranska/qc-str/releases/tag/v0.2.0). -This repository contains the files needed to compute the Hamming distance between a string and a set of strings -using a quantum computer; see [preprint](https://arxiv.org/abs/2106.16173) for details. -The code resides in `string_comparison.py`. ## Setup To set up the environment, run @@ -11,6 +13,7 @@ pip install -r requirements.txt ``` ## Usage examples +### Computing the distance between a target string and the closest string in a group `test_string_comparison.py` contains unit test cases for `string_comparison.py`. This file can also be interpreted as a set of examples of how `StringComparator` in `string_comparison.py` should be invoked. To run, do ```bash @@ -25,8 +28,18 @@ To execute code listings shown in the [preprint](https://arxiv.org/abs/2106.1617 python hd_paper_listings.py ``` +### EP-PQM + +The file `compute_empirical_complexity.py` simulates the generation of quantum circuits for string classification as described in the [preprint](https://arxiv.org/abs/2201.07265). Datasets found in `./datasets` (namely, Balance Scale, Breast Cancer, SPECT Heart, Tic-Tac-Toe Endgame, and Zoo) are taken from the UCI Machine Learning [Repository](https://archive.ics.uci.edu/ml/index.php). +To execute, run +```bash +python compute_empirical_complexity.py +``` +The output is saved in `stats.csv` and `stats.json`. + + ## Citation -If you use the algorithm or code, please cite them as follows: +If you use the algorithm or code, please cite them as follows. For computing Hamming distance: ```bibtex @article{khan2021string, author = {Mushahid Khan and Andriy Miranskyy}, @@ -40,6 +53,20 @@ If you use the algorithm or code, please cite them as follows: } ``` +For EP-PQM: +```bibtex +@article{khan2022string, + author = {Mushahid Khan and Jean Paul Latyr Faye and Udson C. Mendes and Andriy Miranskyy}, + title = {{EP-PQM: Efficient Parametric Probabilistic Quantum Memory with Fewer Qubits and Gates}}, + journal = {CoRR}, + volume = {abs/2201.07265}, + year = {2022}, + archivePrefix = {arXiv}, + url = {https://arxiv.org/abs/2201.07265}, + eprint = {2201.07265} +} +``` + ## Contact us If you found a bug or came up with a new feature -- please open an [issue](https://github.com/miranska/qc-str/issues) diff --git a/compute_empirical_complexity.py b/compute_empirical_complexity.py new file mode 100644 index 0000000..446faff --- /dev/null +++ b/compute_empirical_complexity.py @@ -0,0 +1,224 @@ +import json + +import numpy as np +import pandas as pd +from qiskit.test.mock import FakeQasmSimulator +from qiskit.transpiler.exceptions import TranspilerError + +from string_comparison import StringComparator + + +class NumpyEnc(json.JSONEncoder): + """ + Convert numpy int64 to the format comprehensible by the JSON encoder + """ + + def default(self, obj): + if isinstance(obj, np.int64): + return int(obj) + return json.JSONEncoder.default(self, obj) + + +def standardize_column_elements(column): + """ + Update column values to make sure that column element values are consistent + Note that the changes will happen in place + :param column: pandas series + :return: updated column, number of unique attributes + """ + dic = {} + numeric_id = 0 + for ind in range(0, len(column)): + element_value = column.iloc[ind] + if element_value not in dic: + dic[element_value] = numeric_id + numeric_id += 1 + column.iloc[ind] = dic[element_value] + return column, len(dic) + + +def get_data(file_name, label_location, encoding, columns_to_remove=None, + fraction_of_rows=0.9, random_seed=42): + """ + Take the dataset, reshuffle, retain 90% of it and return a list of datasets (one per label/class) + + :param file_name: name of the file to read the data from + :param label_location: location of the label column (first or last), applied after undesired columns are removed + :param encoding: Type of encoding: either one-hot or label + :param columns_to_remove: List of unwanted columns to remove + :param fraction_of_rows: Fraction of rows to retain for analysis + :param random_seed: The value of random seed needed for reproducibility + :return: a list of datasets, max number of attributes, features count + """ + + df = pd.read_csv(file_name, header=None) + + # remove unwanted columns + if columns_to_remove is not None: + df = df.drop(df.columns[columns_to_remove], axis=1) + # update column names + df.columns = list(range(0, len(df.columns))) + + # get indexes of data columns + col_count = len(df.columns) + if label_location == "first": + data_columns = range(1, col_count) + label_column = 0 + elif label_location == "last": + data_columns = range(0, col_count - 1) + label_column = col_count - 1 + else: + raise Exception(f"Unknown label_location {label_location}") + + features_cnt = len(data_columns) + # standardize column elements and get max number of attributes in a column/feature + max_attr_cnt = -1 + for data_column in data_columns: + updated_column, attr_cnt = standardize_column_elements(df[data_column].copy()) + df[data_column] = updated_column + if attr_cnt > max_attr_cnt: + max_attr_cnt = attr_cnt + + # get 90% of strings (drawn at random) + df = df.sample(n=round(len(df.index) * fraction_of_rows), random_state=random_seed) + + # get labels + labels = df[label_column].unique() + + # generate strings + strings = {} + for label in labels: + single_class = df[df[label_column] == label] + class_strings = [] + for ind in range(0, len(single_class.index)): + observation = single_class.iloc[ind] + if encoding == "label": + my_string = [] + for feature_ind in data_columns: + my_string.append(str(observation.iloc[feature_ind])) + class_strings.append(my_string) + elif encoding == "one-hot": + my_string = "" + if max_attr_cnt > 2: + for feature_ind in data_columns: + value = observation.iloc[feature_ind] + one_hot = [0] * max_attr_cnt + one_hot[value] = 1 + my_string += ''.join(map(str, one_hot)) + else: # use binary string for the 2-attribute case + for feature_ind in data_columns: + value = observation.iloc[feature_ind] + one_hot = [value] + my_string += ''.join(map(str, one_hot)) + + class_strings.append(my_string) + else: + raise Exception(f"Unknown encoding {encoding}") + strings[label] = class_strings + + return strings, max_attr_cnt, features_cnt + + +if __name__ == "__main__": + stats = [] + + files = [ + {"file_name": "./datasets/balance_scale.csv", "label_location": "first", 'labels': ['R'], + 'is_laborious': False}, + {"file_name": "./datasets/tictactoe.csv", "label_location": "last", 'labels': ['positive'], + 'is_laborious': True}, + {"file_name": "./datasets/breast_cancer.csv", "label_location": "last", "remove_columns": [0], 'labels': [2], + 'is_laborious': True}, + {"file_name": "./datasets/zoo.csv", "label_location": "last", "remove_columns": [0], 'labels': [1], + 'is_laborious': True}, + {"file_name": "./datasets/SPECTrain.csv", "label_location": "first", 'labels': [1], 'is_laborious': False} + ] + encodings = ["one-hot", "label"] + + is_fake_circuit_off = input("Creation of the circuit for fake simulator is laborious. " + "Do you want to skip it? (Y/n): ") or "Y" + if is_fake_circuit_off.upper() == 'Y': + print("Skip fake simulator") + backend_types = ["abstract"] + elif is_fake_circuit_off.upper() == 'N': + print("Keep fake simulator") + backend_types = ["abstract", "fake_simulator"] + else: + raise ValueError("Please enter y or n.") + + for file in files: + if "remove_columns" in file: + remove_columns = file["remove_columns"] + else: + remove_columns = None + for encoding in encodings: + + classes, max_attr_count, features_count = get_data(file["file_name"], + label_location=file["label_location"], + encoding=encoding, + columns_to_remove=remove_columns) + # parameters for String Comparisons + if encoding == "one-hot": + is_binary = True + symbol_length = max_attr_count + p_pqm = True + symbol_count = None + elif encoding == "label": + is_binary = False + symbol_length = None + p_pqm = False + symbol_count = max_attr_count + else: + raise Exception(f"Unknown encoding {encoding}") + + for label in classes: + if 'labels' in file: # process only a subset of labels present in file['labels'] + if label not in file['labels']: + continue + database = classes[label] + target = database[0] # dummy target string + for backend_type in backend_types: + print(f"Analyzing {file['file_name']} for label {label} on {backend_type}") + if backend_type == "abstract": + x = StringComparator(target, database, symbol_length=symbol_length, is_binary=is_binary, + symbol_count=symbol_count, + p_pqm=p_pqm) + elif backend_type == "fake_simulator": + if file['is_laborious']: + print(f" Skipping {file['file_name']} as it requires too much computing power") + continue + print(" Keep only two rows to speed up processing") + database = database[1:3] # keep only two rows to make it simpler to compute the circuit + try: + x = StringComparator(target, database, symbol_length=symbol_length, is_binary=is_binary, + symbol_count=symbol_count, + p_pqm=p_pqm, optimize_for=FakeQasmSimulator(), + optimization_levels=[0], attempts_per_optimization_level=1) + except TranspilerError as e: + print(print(f"Unexpected {e=}, {type(e)=}")) + break + else: + raise Exception(f"Unknown backend type {backend_type}") + + circ_decomposed = x.circuit.decompose().decompose(['c3sx', 'rcccx', 'rcccx_dg']).decompose('cu1') + run_stats = {'file_name': file['file_name'], 'encoding': encoding, 'label': label, + 'observations_count': len(database), 'features_count': features_count, + 'max_attr_count': max_attr_count, 'backend_type': backend_type, + 'qubits_count': x.circuit.num_qubits, 'circuit_depth': x.circuit.depth(), + 'circuit_count_ops': x.circuit.count_ops(), + 'qubits_count_decomposed': circ_decomposed.num_qubits, + 'circuit_depth_decomposed': circ_decomposed.depth(), + 'circuit_count_ops_decomposed': circ_decomposed.count_ops() + } + stats.append(run_stats) + + print(f"Final stats in basic dictionary") + print(stats) + + # save stats in JSON format + out_json = json.dumps(stats, cls=NumpyEnc) + with open('stats.json', 'w') as f: + json.dump(out_json, f) + + # let's also save it in a table + pd.json_normalize(stats).to_csv('stats.csv') diff --git a/datasets/SPECTrain.csv b/datasets/SPECTrain.csv new file mode 100644 index 0000000..2755ac7 --- /dev/null +++ b/datasets/SPECTrain.csv @@ -0,0 +1,80 @@ +1,0,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0 +1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1 +1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0 +1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1 +1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0 +1,0,0,0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,1 +1,1,0,1,1,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,1,1 +1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1 +1,0,0,1,0,0,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,1,1 +1,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0 +1,1,1,0,0,1,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0,1 +1,1,1,0,0,1,1,1,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0 +1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,1 +1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1 +1,1,0,1,1,0,0,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,1 +1,0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,1,1,1,0,1,1,1 +1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,1,0 +1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,1,1,0 +1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0 +1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1 +1,1,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,1,1,0,0 +1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0 +1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0 +1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0 +1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0 +1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0 +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +1,1,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,0,0,0,1,1,1 +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,0,1,0,0,1 +1,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,1,1 +1,1,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,0 +1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,1,1,1,1,1,0,1 +1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,1,0,0,0,1,1,1 +1,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 +1,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0 +1,1,0,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0 +0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 +0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0 +0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 +0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1 +0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0 +0,1,1,1,0,1,0,1,1,1,1,1,0,0,1,0,1,0,0,1,0,1,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0 +0,1,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,1,0,0,0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0 +0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0 +0,0,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1 +0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file diff --git a/datasets/balance_scale.csv b/datasets/balance_scale.csv new file mode 100644 index 0000000..7fff64d --- /dev/null +++ b/datasets/balance_scale.csv @@ -0,0 +1,625 @@ +B,1,1,1,1 +R,1,1,1,2 +R,1,1,1,3 +R,1,1,1,4 +R,1,1,1,5 +R,1,1,2,1 +R,1,1,2,2 +R,1,1,2,3 +R,1,1,2,4 +R,1,1,2,5 +R,1,1,3,1 +R,1,1,3,2 +R,1,1,3,3 +R,1,1,3,4 +R,1,1,3,5 +R,1,1,4,1 +R,1,1,4,2 +R,1,1,4,3 +R,1,1,4,4 +R,1,1,4,5 +R,1,1,5,1 +R,1,1,5,2 +R,1,1,5,3 +R,1,1,5,4 +R,1,1,5,5 +L,1,2,1,1 +B,1,2,1,2 +R,1,2,1,3 +R,1,2,1,4 +R,1,2,1,5 +B,1,2,2,1 +R,1,2,2,2 +R,1,2,2,3 +R,1,2,2,4 +R,1,2,2,5 +R,1,2,3,1 +R,1,2,3,2 +R,1,2,3,3 +R,1,2,3,4 +R,1,2,3,5 +R,1,2,4,1 +R,1,2,4,2 +R,1,2,4,3 +R,1,2,4,4 +R,1,2,4,5 +R,1,2,5,1 +R,1,2,5,2 +R,1,2,5,3 +R,1,2,5,4 +R,1,2,5,5 +L,1,3,1,1 +L,1,3,1,2 +B,1,3,1,3 +R,1,3,1,4 +R,1,3,1,5 +L,1,3,2,1 +R,1,3,2,2 +R,1,3,2,3 +R,1,3,2,4 +R,1,3,2,5 +B,1,3,3,1 +R,1,3,3,2 +R,1,3,3,3 +R,1,3,3,4 +R,1,3,3,5 +R,1,3,4,1 +R,1,3,4,2 +R,1,3,4,3 +R,1,3,4,4 +R,1,3,4,5 +R,1,3,5,1 +R,1,3,5,2 +R,1,3,5,3 +R,1,3,5,4 +R,1,3,5,5 +L,1,4,1,1 +L,1,4,1,2 +L,1,4,1,3 +B,1,4,1,4 +R,1,4,1,5 +L,1,4,2,1 +B,1,4,2,2 +R,1,4,2,3 +R,1,4,2,4 +R,1,4,2,5 +L,1,4,3,1 +R,1,4,3,2 +R,1,4,3,3 +R,1,4,3,4 +R,1,4,3,5 +B,1,4,4,1 +R,1,4,4,2 +R,1,4,4,3 +R,1,4,4,4 +R,1,4,4,5 +R,1,4,5,1 +R,1,4,5,2 +R,1,4,5,3 +R,1,4,5,4 +R,1,4,5,5 +L,1,5,1,1 +L,1,5,1,2 +L,1,5,1,3 +L,1,5,1,4 +B,1,5,1,5 +L,1,5,2,1 +L,1,5,2,2 +R,1,5,2,3 +R,1,5,2,4 +R,1,5,2,5 +L,1,5,3,1 +R,1,5,3,2 +R,1,5,3,3 +R,1,5,3,4 +R,1,5,3,5 +L,1,5,4,1 +R,1,5,4,2 +R,1,5,4,3 +R,1,5,4,4 +R,1,5,4,5 +B,1,5,5,1 +R,1,5,5,2 +R,1,5,5,3 +R,1,5,5,4 +R,1,5,5,5 +L,2,1,1,1 +B,2,1,1,2 +R,2,1,1,3 +R,2,1,1,4 +R,2,1,1,5 +B,2,1,2,1 +R,2,1,2,2 +R,2,1,2,3 +R,2,1,2,4 +R,2,1,2,5 +R,2,1,3,1 +R,2,1,3,2 +R,2,1,3,3 +R,2,1,3,4 +R,2,1,3,5 +R,2,1,4,1 +R,2,1,4,2 +R,2,1,4,3 +R,2,1,4,4 +R,2,1,4,5 +R,2,1,5,1 +R,2,1,5,2 +R,2,1,5,3 +R,2,1,5,4 +R,2,1,5,5 +L,2,2,1,1 +L,2,2,1,2 +L,2,2,1,3 +B,2,2,1,4 +R,2,2,1,5 +L,2,2,2,1 +B,2,2,2,2 +R,2,2,2,3 +R,2,2,2,4 +R,2,2,2,5 +L,2,2,3,1 +R,2,2,3,2 +R,2,2,3,3 +R,2,2,3,4 +R,2,2,3,5 +B,2,2,4,1 +R,2,2,4,2 +R,2,2,4,3 +R,2,2,4,4 +R,2,2,4,5 +R,2,2,5,1 +R,2,2,5,2 +R,2,2,5,3 +R,2,2,5,4 +R,2,2,5,5 +L,2,3,1,1 +L,2,3,1,2 +L,2,3,1,3 +L,2,3,1,4 +L,2,3,1,5 +L,2,3,2,1 +L,2,3,2,2 +B,2,3,2,3 +R,2,3,2,4 +R,2,3,2,5 +L,2,3,3,1 +B,2,3,3,2 +R,2,3,3,3 +R,2,3,3,4 +R,2,3,3,5 +L,2,3,4,1 +R,2,3,4,2 +R,2,3,4,3 +R,2,3,4,4 +R,2,3,4,5 +L,2,3,5,1 +R,2,3,5,2 +R,2,3,5,3 +R,2,3,5,4 +R,2,3,5,5 +L,2,4,1,1 +L,2,4,1,2 +L,2,4,1,3 +L,2,4,1,4 +L,2,4,1,5 +L,2,4,2,1 +L,2,4,2,2 +L,2,4,2,3 +B,2,4,2,4 +R,2,4,2,5 +L,2,4,3,1 +L,2,4,3,2 +R,2,4,3,3 +R,2,4,3,4 +R,2,4,3,5 +L,2,4,4,1 +B,2,4,4,2 +R,2,4,4,3 +R,2,4,4,4 +R,2,4,4,5 +L,2,4,5,1 +R,2,4,5,2 +R,2,4,5,3 +R,2,4,5,4 +R,2,4,5,5 +L,2,5,1,1 +L,2,5,1,2 +L,2,5,1,3 +L,2,5,1,4 +L,2,5,1,5 +L,2,5,2,1 +L,2,5,2,2 +L,2,5,2,3 +L,2,5,2,4 +B,2,5,2,5 +L,2,5,3,1 +L,2,5,3,2 +L,2,5,3,3 +R,2,5,3,4 +R,2,5,3,5 +L,2,5,4,1 +L,2,5,4,2 +R,2,5,4,3 +R,2,5,4,4 +R,2,5,4,5 +L,2,5,5,1 +B,2,5,5,2 +R,2,5,5,3 +R,2,5,5,4 +R,2,5,5,5 +L,3,1,1,1 +L,3,1,1,2 +B,3,1,1,3 +R,3,1,1,4 +R,3,1,1,5 +L,3,1,2,1 +R,3,1,2,2 +R,3,1,2,3 +R,3,1,2,4 +R,3,1,2,5 +B,3,1,3,1 +R,3,1,3,2 +R,3,1,3,3 +R,3,1,3,4 +R,3,1,3,5 +R,3,1,4,1 +R,3,1,4,2 +R,3,1,4,3 +R,3,1,4,4 +R,3,1,4,5 +R,3,1,5,1 +R,3,1,5,2 +R,3,1,5,3 +R,3,1,5,4 +R,3,1,5,5 +L,3,2,1,1 +L,3,2,1,2 +L,3,2,1,3 +L,3,2,1,4 +L,3,2,1,5 +L,3,2,2,1 +L,3,2,2,2 +B,3,2,2,3 +R,3,2,2,4 +R,3,2,2,5 +L,3,2,3,1 +B,3,2,3,2 +R,3,2,3,3 +R,3,2,3,4 +R,3,2,3,5 +L,3,2,4,1 +R,3,2,4,2 +R,3,2,4,3 +R,3,2,4,4 +R,3,2,4,5 +L,3,2,5,1 +R,3,2,5,2 +R,3,2,5,3 +R,3,2,5,4 +R,3,2,5,5 +L,3,3,1,1 +L,3,3,1,2 +L,3,3,1,3 +L,3,3,1,4 +L,3,3,1,5 +L,3,3,2,1 +L,3,3,2,2 +L,3,3,2,3 +L,3,3,2,4 +R,3,3,2,5 +L,3,3,3,1 +L,3,3,3,2 +B,3,3,3,3 +R,3,3,3,4 +R,3,3,3,5 +L,3,3,4,1 +L,3,3,4,2 +R,3,3,4,3 +R,3,3,4,4 +R,3,3,4,5 +L,3,3,5,1 +R,3,3,5,2 +R,3,3,5,3 +R,3,3,5,4 +R,3,3,5,5 +L,3,4,1,1 +L,3,4,1,2 +L,3,4,1,3 +L,3,4,1,4 +L,3,4,1,5 +L,3,4,2,1 +L,3,4,2,2 +L,3,4,2,3 +L,3,4,2,4 +L,3,4,2,5 +L,3,4,3,1 +L,3,4,3,2 +L,3,4,3,3 +B,3,4,3,4 +R,3,4,3,5 +L,3,4,4,1 +L,3,4,4,2 +B,3,4,4,3 +R,3,4,4,4 +R,3,4,4,5 +L,3,4,5,1 +L,3,4,5,2 +R,3,4,5,3 +R,3,4,5,4 +R,3,4,5,5 +L,3,5,1,1 +L,3,5,1,2 +L,3,5,1,3 +L,3,5,1,4 +L,3,5,1,5 +L,3,5,2,1 +L,3,5,2,2 +L,3,5,2,3 +L,3,5,2,4 +L,3,5,2,5 +L,3,5,3,1 +L,3,5,3,2 +L,3,5,3,3 +L,3,5,3,4 +B,3,5,3,5 +L,3,5,4,1 +L,3,5,4,2 +L,3,5,4,3 +R,3,5,4,4 +R,3,5,4,5 +L,3,5,5,1 +L,3,5,5,2 +B,3,5,5,3 +R,3,5,5,4 +R,3,5,5,5 +L,4,1,1,1 +L,4,1,1,2 +L,4,1,1,3 +B,4,1,1,4 +R,4,1,1,5 +L,4,1,2,1 +B,4,1,2,2 +R,4,1,2,3 +R,4,1,2,4 +R,4,1,2,5 +L,4,1,3,1 +R,4,1,3,2 +R,4,1,3,3 +R,4,1,3,4 +R,4,1,3,5 +B,4,1,4,1 +R,4,1,4,2 +R,4,1,4,3 +R,4,1,4,4 +R,4,1,4,5 +R,4,1,5,1 +R,4,1,5,2 +R,4,1,5,3 +R,4,1,5,4 +R,4,1,5,5 +L,4,2,1,1 +L,4,2,1,2 +L,4,2,1,3 +L,4,2,1,4 +L,4,2,1,5 +L,4,2,2,1 +L,4,2,2,2 +L,4,2,2,3 +B,4,2,2,4 +R,4,2,2,5 +L,4,2,3,1 +L,4,2,3,2 +R,4,2,3,3 +R,4,2,3,4 +R,4,2,3,5 +L,4,2,4,1 +B,4,2,4,2 +R,4,2,4,3 +R,4,2,4,4 +R,4,2,4,5 +L,4,2,5,1 +R,4,2,5,2 +R,4,2,5,3 +R,4,2,5,4 +R,4,2,5,5 +L,4,3,1,1 +L,4,3,1,2 +L,4,3,1,3 +L,4,3,1,4 +L,4,3,1,5 +L,4,3,2,1 +L,4,3,2,2 +L,4,3,2,3 +L,4,3,2,4 +L,4,3,2,5 +L,4,3,3,1 +L,4,3,3,2 +L,4,3,3,3 +B,4,3,3,4 +R,4,3,3,5 +L,4,3,4,1 +L,4,3,4,2 +B,4,3,4,3 +R,4,3,4,4 +R,4,3,4,5 +L,4,3,5,1 +L,4,3,5,2 +R,4,3,5,3 +R,4,3,5,4 +R,4,3,5,5 +L,4,4,1,1 +L,4,4,1,2 +L,4,4,1,3 +L,4,4,1,4 +L,4,4,1,5 +L,4,4,2,1 +L,4,4,2,2 +L,4,4,2,3 +L,4,4,2,4 +L,4,4,2,5 +L,4,4,3,1 +L,4,4,3,2 +L,4,4,3,3 +L,4,4,3,4 +L,4,4,3,5 +L,4,4,4,1 +L,4,4,4,2 +L,4,4,4,3 +B,4,4,4,4 +R,4,4,4,5 +L,4,4,5,1 +L,4,4,5,2 +L,4,4,5,3 +R,4,4,5,4 +R,4,4,5,5 +L,4,5,1,1 +L,4,5,1,2 +L,4,5,1,3 +L,4,5,1,4 +L,4,5,1,5 +L,4,5,2,1 +L,4,5,2,2 +L,4,5,2,3 +L,4,5,2,4 +L,4,5,2,5 +L,4,5,3,1 +L,4,5,3,2 +L,4,5,3,3 +L,4,5,3,4 +L,4,5,3,5 +L,4,5,4,1 +L,4,5,4,2 +L,4,5,4,3 +L,4,5,4,4 +B,4,5,4,5 +L,4,5,5,1 +L,4,5,5,2 +L,4,5,5,3 +B,4,5,5,4 +R,4,5,5,5 +L,5,1,1,1 +L,5,1,1,2 +L,5,1,1,3 +L,5,1,1,4 +B,5,1,1,5 +L,5,1,2,1 +L,5,1,2,2 +R,5,1,2,3 +R,5,1,2,4 +R,5,1,2,5 +L,5,1,3,1 +R,5,1,3,2 +R,5,1,3,3 +R,5,1,3,4 +R,5,1,3,5 +L,5,1,4,1 +R,5,1,4,2 +R,5,1,4,3 +R,5,1,4,4 +R,5,1,4,5 +B,5,1,5,1 +R,5,1,5,2 +R,5,1,5,3 +R,5,1,5,4 +R,5,1,5,5 +L,5,2,1,1 +L,5,2,1,2 +L,5,2,1,3 +L,5,2,1,4 +L,5,2,1,5 +L,5,2,2,1 +L,5,2,2,2 +L,5,2,2,3 +L,5,2,2,4 +B,5,2,2,5 +L,5,2,3,1 +L,5,2,3,2 +L,5,2,3,3 +R,5,2,3,4 +R,5,2,3,5 +L,5,2,4,1 +L,5,2,4,2 +R,5,2,4,3 +R,5,2,4,4 +R,5,2,4,5 +L,5,2,5,1 +B,5,2,5,2 +R,5,2,5,3 +R,5,2,5,4 +R,5,2,5,5 +L,5,3,1,1 +L,5,3,1,2 +L,5,3,1,3 +L,5,3,1,4 +L,5,3,1,5 +L,5,3,2,1 +L,5,3,2,2 +L,5,3,2,3 +L,5,3,2,4 +L,5,3,2,5 +L,5,3,3,1 +L,5,3,3,2 +L,5,3,3,3 +L,5,3,3,4 +B,5,3,3,5 +L,5,3,4,1 +L,5,3,4,2 +L,5,3,4,3 +R,5,3,4,4 +R,5,3,4,5 +L,5,3,5,1 +L,5,3,5,2 +B,5,3,5,3 +R,5,3,5,4 +R,5,3,5,5 +L,5,4,1,1 +L,5,4,1,2 +L,5,4,1,3 +L,5,4,1,4 +L,5,4,1,5 +L,5,4,2,1 +L,5,4,2,2 +L,5,4,2,3 +L,5,4,2,4 +L,5,4,2,5 +L,5,4,3,1 +L,5,4,3,2 +L,5,4,3,3 +L,5,4,3,4 +L,5,4,3,5 +L,5,4,4,1 +L,5,4,4,2 +L,5,4,4,3 +L,5,4,4,4 +B,5,4,4,5 +L,5,4,5,1 +L,5,4,5,2 +L,5,4,5,3 +B,5,4,5,4 +R,5,4,5,5 +L,5,5,1,1 +L,5,5,1,2 +L,5,5,1,3 +L,5,5,1,4 +L,5,5,1,5 +L,5,5,2,1 +L,5,5,2,2 +L,5,5,2,3 +L,5,5,2,4 +L,5,5,2,5 +L,5,5,3,1 +L,5,5,3,2 +L,5,5,3,3 +L,5,5,3,4 +L,5,5,3,5 +L,5,5,4,1 +L,5,5,4,2 +L,5,5,4,3 +L,5,5,4,4 +L,5,5,4,5 +L,5,5,5,1 +L,5,5,5,2 +L,5,5,5,3 +L,5,5,5,4 +B,5,5,5,5 diff --git a/datasets/breast_cancer.csv b/datasets/breast_cancer.csv new file mode 100644 index 0000000..a50b76f --- /dev/null +++ b/datasets/breast_cancer.csv @@ -0,0 +1,699 @@ +1000025,5,1,1,1,2,1,3,1,1,2 +1002945,5,4,4,5,7,10,3,2,1,2 +1015425,3,1,1,1,2,2,3,1,1,2 +1016277,6,8,8,1,3,4,3,7,1,2 +1017023,4,1,1,3,2,1,3,1,1,2 +1017122,8,10,10,8,7,10,9,7,1,4 +1018099,1,1,1,1,2,10,3,1,1,2 +1018561,2,1,2,1,2,1,3,1,1,2 +1033078,2,1,1,1,2,1,1,1,5,2 +1033078,4,2,1,1,2,1,2,1,1,2 +1035283,1,1,1,1,1,1,3,1,1,2 +1036172,2,1,1,1,2,1,2,1,1,2 +1041801,5,3,3,3,2,3,4,4,1,4 +1043999,1,1,1,1,2,3,3,1,1,2 +1044572,8,7,5,10,7,9,5,5,4,4 +1047630,7,4,6,4,6,1,4,3,1,4 +1048672,4,1,1,1,2,1,2,1,1,2 +1049815,4,1,1,1,2,1,3,1,1,2 +1050670,10,7,7,6,4,10,4,1,2,4 +1050718,6,1,1,1,2,1,3,1,1,2 +1054590,7,3,2,10,5,10,5,4,4,4 +1054593,10,5,5,3,6,7,7,10,1,4 +1056784,3,1,1,1,2,1,2,1,1,2 +1057013,8,4,5,1,2,?,7,3,1,4 +1059552,1,1,1,1,2,1,3,1,1,2 +1065726,5,2,3,4,2,7,3,6,1,4 +1066373,3,2,1,1,1,1,2,1,1,2 +1066979,5,1,1,1,2,1,2,1,1,2 +1067444,2,1,1,1,2,1,2,1,1,2 +1070935,1,1,3,1,2,1,1,1,1,2 +1070935,3,1,1,1,1,1,2,1,1,2 +1071760,2,1,1,1,2,1,3,1,1,2 +1072179,10,7,7,3,8,5,7,4,3,4 +1074610,2,1,1,2,2,1,3,1,1,2 +1075123,3,1,2,1,2,1,2,1,1,2 +1079304,2,1,1,1,2,1,2,1,1,2 +1080185,10,10,10,8,6,1,8,9,1,4 +1081791,6,2,1,1,1,1,7,1,1,2 +1084584,5,4,4,9,2,10,5,6,1,4 +1091262,2,5,3,3,6,7,7,5,1,4 +1096800,6,6,6,9,6,?,7,8,1,2 +1099510,10,4,3,1,3,3,6,5,2,4 +1100524,6,10,10,2,8,10,7,3,3,4 +1102573,5,6,5,6,10,1,3,1,1,4 +1103608,10,10,10,4,8,1,8,10,1,4 +1103722,1,1,1,1,2,1,2,1,2,2 +1105257,3,7,7,4,4,9,4,8,1,4 +1105524,1,1,1,1,2,1,2,1,1,2 +1106095,4,1,1,3,2,1,3,1,1,2 +1106829,7,8,7,2,4,8,3,8,2,4 +1108370,9,5,8,1,2,3,2,1,5,4 +1108449,5,3,3,4,2,4,3,4,1,4 +1110102,10,3,6,2,3,5,4,10,2,4 +1110503,5,5,5,8,10,8,7,3,7,4 +1110524,10,5,5,6,8,8,7,1,1,4 +1111249,10,6,6,3,4,5,3,6,1,4 +1112209,8,10,10,1,3,6,3,9,1,4 +1113038,8,2,4,1,5,1,5,4,4,4 +1113483,5,2,3,1,6,10,5,1,1,4 +1113906,9,5,5,2,2,2,5,1,1,4 +1115282,5,3,5,5,3,3,4,10,1,4 +1115293,1,1,1,1,2,2,2,1,1,2 +1116116,9,10,10,1,10,8,3,3,1,4 +1116132,6,3,4,1,5,2,3,9,1,4 +1116192,1,1,1,1,2,1,2,1,1,2 +1116998,10,4,2,1,3,2,4,3,10,4 +1117152,4,1,1,1,2,1,3,1,1,2 +1118039,5,3,4,1,8,10,4,9,1,4 +1120559,8,3,8,3,4,9,8,9,8,4 +1121732,1,1,1,1,2,1,3,2,1,2 +1121919,5,1,3,1,2,1,2,1,1,2 +1123061,6,10,2,8,10,2,7,8,10,4 +1124651,1,3,3,2,2,1,7,2,1,2 +1125035,9,4,5,10,6,10,4,8,1,4 +1126417,10,6,4,1,3,4,3,2,3,4 +1131294,1,1,2,1,2,2,4,2,1,2 +1132347,1,1,4,1,2,1,2,1,1,2 +1133041,5,3,1,2,2,1,2,1,1,2 +1133136,3,1,1,1,2,3,3,1,1,2 +1136142,2,1,1,1,3,1,2,1,1,2 +1137156,2,2,2,1,1,1,7,1,1,2 +1143978,4,1,1,2,2,1,2,1,1,2 +1143978,5,2,1,1,2,1,3,1,1,2 +1147044,3,1,1,1,2,2,7,1,1,2 +1147699,3,5,7,8,8,9,7,10,7,4 +1147748,5,10,6,1,10,4,4,10,10,4 +1148278,3,3,6,4,5,8,4,4,1,4 +1148873,3,6,6,6,5,10,6,8,3,4 +1152331,4,1,1,1,2,1,3,1,1,2 +1155546,2,1,1,2,3,1,2,1,1,2 +1156272,1,1,1,1,2,1,3,1,1,2 +1156948,3,1,1,2,2,1,1,1,1,2 +1157734,4,1,1,1,2,1,3,1,1,2 +1158247,1,1,1,1,2,1,2,1,1,2 +1160476,2,1,1,1,2,1,3,1,1,2 +1164066,1,1,1,1,2,1,3,1,1,2 +1165297,2,1,1,2,2,1,1,1,1,2 +1165790,5,1,1,1,2,1,3,1,1,2 +1165926,9,6,9,2,10,6,2,9,10,4 +1166630,7,5,6,10,5,10,7,9,4,4 +1166654,10,3,5,1,10,5,3,10,2,4 +1167439,2,3,4,4,2,5,2,5,1,4 +1167471,4,1,2,1,2,1,3,1,1,2 +1168359,8,2,3,1,6,3,7,1,1,4 +1168736,10,10,10,10,10,1,8,8,8,4 +1169049,7,3,4,4,3,3,3,2,7,4 +1170419,10,10,10,8,2,10,4,1,1,4 +1170420,1,6,8,10,8,10,5,7,1,4 +1171710,1,1,1,1,2,1,2,3,1,2 +1171710,6,5,4,4,3,9,7,8,3,4 +1171795,1,3,1,2,2,2,5,3,2,2 +1171845,8,6,4,3,5,9,3,1,1,4 +1172152,10,3,3,10,2,10,7,3,3,4 +1173216,10,10,10,3,10,8,8,1,1,4 +1173235,3,3,2,1,2,3,3,1,1,2 +1173347,1,1,1,1,2,5,1,1,1,2 +1173347,8,3,3,1,2,2,3,2,1,2 +1173509,4,5,5,10,4,10,7,5,8,4 +1173514,1,1,1,1,4,3,1,1,1,2 +1173681,3,2,1,1,2,2,3,1,1,2 +1174057,1,1,2,2,2,1,3,1,1,2 +1174057,4,2,1,1,2,2,3,1,1,2 +1174131,10,10,10,2,10,10,5,3,3,4 +1174428,5,3,5,1,8,10,5,3,1,4 +1175937,5,4,6,7,9,7,8,10,1,4 +1176406,1,1,1,1,2,1,2,1,1,2 +1176881,7,5,3,7,4,10,7,5,5,4 +1177027,3,1,1,1,2,1,3,1,1,2 +1177399,8,3,5,4,5,10,1,6,2,4 +1177512,1,1,1,1,10,1,1,1,1,2 +1178580,5,1,3,1,2,1,2,1,1,2 +1179818,2,1,1,1,2,1,3,1,1,2 +1180194,5,10,8,10,8,10,3,6,3,4 +1180523,3,1,1,1,2,1,2,2,1,2 +1180831,3,1,1,1,3,1,2,1,1,2 +1181356,5,1,1,1,2,2,3,3,1,2 +1182404,4,1,1,1,2,1,2,1,1,2 +1182410,3,1,1,1,2,1,1,1,1,2 +1183240,4,1,2,1,2,1,2,1,1,2 +1183246,1,1,1,1,1,?,2,1,1,2 +1183516,3,1,1,1,2,1,1,1,1,2 +1183911,2,1,1,1,2,1,1,1,1,2 +1183983,9,5,5,4,4,5,4,3,3,4 +1184184,1,1,1,1,2,5,1,1,1,2 +1184241,2,1,1,1,2,1,2,1,1,2 +1184840,1,1,3,1,2,?,2,1,1,2 +1185609,3,4,5,2,6,8,4,1,1,4 +1185610,1,1,1,1,3,2,2,1,1,2 +1187457,3,1,1,3,8,1,5,8,1,2 +1187805,8,8,7,4,10,10,7,8,7,4 +1188472,1,1,1,1,1,1,3,1,1,2 +1189266,7,2,4,1,6,10,5,4,3,4 +1189286,10,10,8,6,4,5,8,10,1,4 +1190394,4,1,1,1,2,3,1,1,1,2 +1190485,1,1,1,1,2,1,1,1,1,2 +1192325,5,5,5,6,3,10,3,1,1,4 +1193091,1,2,2,1,2,1,2,1,1,2 +1193210,2,1,1,1,2,1,3,1,1,2 +1193683,1,1,2,1,3,?,1,1,1,2 +1196295,9,9,10,3,6,10,7,10,6,4 +1196915,10,7,7,4,5,10,5,7,2,4 +1197080,4,1,1,1,2,1,3,2,1,2 +1197270,3,1,1,1,2,1,3,1,1,2 +1197440,1,1,1,2,1,3,1,1,7,2 +1197510,5,1,1,1,2,?,3,1,1,2 +1197979,4,1,1,1,2,2,3,2,1,2 +1197993,5,6,7,8,8,10,3,10,3,4 +1198128,10,8,10,10,6,1,3,1,10,4 +1198641,3,1,1,1,2,1,3,1,1,2 +1199219,1,1,1,2,1,1,1,1,1,2 +1199731,3,1,1,1,2,1,1,1,1,2 +1199983,1,1,1,1,2,1,3,1,1,2 +1200772,1,1,1,1,2,1,2,1,1,2 +1200847,6,10,10,10,8,10,10,10,7,4 +1200892,8,6,5,4,3,10,6,1,1,4 +1200952,5,8,7,7,10,10,5,7,1,4 +1201834,2,1,1,1,2,1,3,1,1,2 +1201936,5,10,10,3,8,1,5,10,3,4 +1202125,4,1,1,1,2,1,3,1,1,2 +1202812,5,3,3,3,6,10,3,1,1,4 +1203096,1,1,1,1,1,1,3,1,1,2 +1204242,1,1,1,1,2,1,1,1,1,2 +1204898,6,1,1,1,2,1,3,1,1,2 +1205138,5,8,8,8,5,10,7,8,1,4 +1205579,8,7,6,4,4,10,5,1,1,4 +1206089,2,1,1,1,1,1,3,1,1,2 +1206695,1,5,8,6,5,8,7,10,1,4 +1206841,10,5,6,10,6,10,7,7,10,4 +1207986,5,8,4,10,5,8,9,10,1,4 +1208301,1,2,3,1,2,1,3,1,1,2 +1210963,10,10,10,8,6,8,7,10,1,4 +1211202,7,5,10,10,10,10,4,10,3,4 +1212232,5,1,1,1,2,1,2,1,1,2 +1212251,1,1,1,1,2,1,3,1,1,2 +1212422,3,1,1,1,2,1,3,1,1,2 +1212422,4,1,1,1,2,1,3,1,1,2 +1213375,8,4,4,5,4,7,7,8,2,2 +1213383,5,1,1,4,2,1,3,1,1,2 +1214092,1,1,1,1,2,1,1,1,1,2 +1214556,3,1,1,1,2,1,2,1,1,2 +1214966,9,7,7,5,5,10,7,8,3,4 +1216694,10,8,8,4,10,10,8,1,1,4 +1216947,1,1,1,1,2,1,3,1,1,2 +1217051,5,1,1,1,2,1,3,1,1,2 +1217264,1,1,1,1,2,1,3,1,1,2 +1218105,5,10,10,9,6,10,7,10,5,4 +1218741,10,10,9,3,7,5,3,5,1,4 +1218860,1,1,1,1,1,1,3,1,1,2 +1218860,1,1,1,1,1,1,3,1,1,2 +1219406,5,1,1,1,1,1,3,1,1,2 +1219525,8,10,10,10,5,10,8,10,6,4 +1219859,8,10,8,8,4,8,7,7,1,4 +1220330,1,1,1,1,2,1,3,1,1,2 +1221863,10,10,10,10,7,10,7,10,4,4 +1222047,10,10,10,10,3,10,10,6,1,4 +1222936,8,7,8,7,5,5,5,10,2,4 +1223282,1,1,1,1,2,1,2,1,1,2 +1223426,1,1,1,1,2,1,3,1,1,2 +1223793,6,10,7,7,6,4,8,10,2,4 +1223967,6,1,3,1,2,1,3,1,1,2 +1224329,1,1,1,2,2,1,3,1,1,2 +1225799,10,6,4,3,10,10,9,10,1,4 +1226012,4,1,1,3,1,5,2,1,1,4 +1226612,7,5,6,3,3,8,7,4,1,4 +1227210,10,5,5,6,3,10,7,9,2,4 +1227244,1,1,1,1,2,1,2,1,1,2 +1227481,10,5,7,4,4,10,8,9,1,4 +1228152,8,9,9,5,3,5,7,7,1,4 +1228311,1,1,1,1,1,1,3,1,1,2 +1230175,10,10,10,3,10,10,9,10,1,4 +1230688,7,4,7,4,3,7,7,6,1,4 +1231387,6,8,7,5,6,8,8,9,2,4 +1231706,8,4,6,3,3,1,4,3,1,2 +1232225,10,4,5,5,5,10,4,1,1,4 +1236043,3,3,2,1,3,1,3,6,1,2 +1241232,3,1,4,1,2,?,3,1,1,2 +1241559,10,8,8,2,8,10,4,8,10,4 +1241679,9,8,8,5,6,2,4,10,4,4 +1242364,8,10,10,8,6,9,3,10,10,4 +1243256,10,4,3,2,3,10,5,3,2,4 +1270479,5,1,3,3,2,2,2,3,1,2 +1276091,3,1,1,3,1,1,3,1,1,2 +1277018,2,1,1,1,2,1,3,1,1,2 +128059,1,1,1,1,2,5,5,1,1,2 +1285531,1,1,1,1,2,1,3,1,1,2 +1287775,5,1,1,2,2,2,3,1,1,2 +144888,8,10,10,8,5,10,7,8,1,4 +145447,8,4,4,1,2,9,3,3,1,4 +167528,4,1,1,1,2,1,3,6,1,2 +169356,3,1,1,1,2,?,3,1,1,2 +183913,1,2,2,1,2,1,1,1,1,2 +191250,10,4,4,10,2,10,5,3,3,4 +1017023,6,3,3,5,3,10,3,5,3,2 +1100524,6,10,10,2,8,10,7,3,3,4 +1116116,9,10,10,1,10,8,3,3,1,4 +1168736,5,6,6,2,4,10,3,6,1,4 +1182404,3,1,1,1,2,1,1,1,1,2 +1182404,3,1,1,1,2,1,2,1,1,2 +1198641,3,1,1,1,2,1,3,1,1,2 +242970,5,7,7,1,5,8,3,4,1,2 +255644,10,5,8,10,3,10,5,1,3,4 +263538,5,10,10,6,10,10,10,6,5,4 +274137,8,8,9,4,5,10,7,8,1,4 +303213,10,4,4,10,6,10,5,5,1,4 +314428,7,9,4,10,10,3,5,3,3,4 +1182404,5,1,4,1,2,1,3,2,1,2 +1198641,10,10,6,3,3,10,4,3,2,4 +320675,3,3,5,2,3,10,7,1,1,4 +324427,10,8,8,2,3,4,8,7,8,4 +385103,1,1,1,1,2,1,3,1,1,2 +390840,8,4,7,1,3,10,3,9,2,4 +411453,5,1,1,1,2,1,3,1,1,2 +320675,3,3,5,2,3,10,7,1,1,4 +428903,7,2,4,1,3,4,3,3,1,4 +431495,3,1,1,1,2,1,3,2,1,2 +432809,3,1,3,1,2,?,2,1,1,2 +434518,3,1,1,1,2,1,2,1,1,2 +452264,1,1,1,1,2,1,2,1,1,2 +456282,1,1,1,1,2,1,3,1,1,2 +476903,10,5,7,3,3,7,3,3,8,4 +486283,3,1,1,1,2,1,3,1,1,2 +486662,2,1,1,2,2,1,3,1,1,2 +488173,1,4,3,10,4,10,5,6,1,4 +492268,10,4,6,1,2,10,5,3,1,4 +508234,7,4,5,10,2,10,3,8,2,4 +527363,8,10,10,10,8,10,10,7,3,4 +529329,10,10,10,10,10,10,4,10,10,4 +535331,3,1,1,1,3,1,2,1,1,2 +543558,6,1,3,1,4,5,5,10,1,4 +555977,5,6,6,8,6,10,4,10,4,4 +560680,1,1,1,1,2,1,1,1,1,2 +561477,1,1,1,1,2,1,3,1,1,2 +563649,8,8,8,1,2,?,6,10,1,4 +601265,10,4,4,6,2,10,2,3,1,4 +606140,1,1,1,1,2,?,2,1,1,2 +606722,5,5,7,8,6,10,7,4,1,4 +616240,5,3,4,3,4,5,4,7,1,2 +61634,5,4,3,1,2,?,2,3,1,2 +625201,8,2,1,1,5,1,1,1,1,2 +63375,9,1,2,6,4,10,7,7,2,4 +635844,8,4,10,5,4,4,7,10,1,4 +636130,1,1,1,1,2,1,3,1,1,2 +640744,10,10,10,7,9,10,7,10,10,4 +646904,1,1,1,1,2,1,3,1,1,2 +653777,8,3,4,9,3,10,3,3,1,4 +659642,10,8,4,4,4,10,3,10,4,4 +666090,1,1,1,1,2,1,3,1,1,2 +666942,1,1,1,1,2,1,3,1,1,2 +667204,7,8,7,6,4,3,8,8,4,4 +673637,3,1,1,1,2,5,5,1,1,2 +684955,2,1,1,1,3,1,2,1,1,2 +688033,1,1,1,1,2,1,1,1,1,2 +691628,8,6,4,10,10,1,3,5,1,4 +693702,1,1,1,1,2,1,1,1,1,2 +704097,1,1,1,1,1,1,2,1,1,2 +704168,4,6,5,6,7,?,4,9,1,2 +706426,5,5,5,2,5,10,4,3,1,4 +709287,6,8,7,8,6,8,8,9,1,4 +718641,1,1,1,1,5,1,3,1,1,2 +721482,4,4,4,4,6,5,7,3,1,2 +730881,7,6,3,2,5,10,7,4,6,4 +733639,3,1,1,1,2,?,3,1,1,2 +733639,3,1,1,1,2,1,3,1,1,2 +733823,5,4,6,10,2,10,4,1,1,4 +740492,1,1,1,1,2,1,3,1,1,2 +743348,3,2,2,1,2,1,2,3,1,2 +752904,10,1,1,1,2,10,5,4,1,4 +756136,1,1,1,1,2,1,2,1,1,2 +760001,8,10,3,2,6,4,3,10,1,4 +760239,10,4,6,4,5,10,7,1,1,4 +76389,10,4,7,2,2,8,6,1,1,4 +764974,5,1,1,1,2,1,3,1,2,2 +770066,5,2,2,2,2,1,2,2,1,2 +785208,5,4,6,6,4,10,4,3,1,4 +785615,8,6,7,3,3,10,3,4,2,4 +792744,1,1,1,1,2,1,1,1,1,2 +797327,6,5,5,8,4,10,3,4,1,4 +798429,1,1,1,1,2,1,3,1,1,2 +704097,1,1,1,1,1,1,2,1,1,2 +806423,8,5,5,5,2,10,4,3,1,4 +809912,10,3,3,1,2,10,7,6,1,4 +810104,1,1,1,1,2,1,3,1,1,2 +814265,2,1,1,1,2,1,1,1,1,2 +814911,1,1,1,1,2,1,1,1,1,2 +822829,7,6,4,8,10,10,9,5,3,4 +826923,1,1,1,1,2,1,1,1,1,2 +830690,5,2,2,2,3,1,1,3,1,2 +831268,1,1,1,1,1,1,1,3,1,2 +832226,3,4,4,10,5,1,3,3,1,4 +832567,4,2,3,5,3,8,7,6,1,4 +836433,5,1,1,3,2,1,1,1,1,2 +837082,2,1,1,1,2,1,3,1,1,2 +846832,3,4,5,3,7,3,4,6,1,2 +850831,2,7,10,10,7,10,4,9,4,4 +855524,1,1,1,1,2,1,2,1,1,2 +857774,4,1,1,1,3,1,2,2,1,2 +859164,5,3,3,1,3,3,3,3,3,4 +859350,8,10,10,7,10,10,7,3,8,4 +866325,8,10,5,3,8,4,4,10,3,4 +873549,10,3,5,4,3,7,3,5,3,4 +877291,6,10,10,10,10,10,8,10,10,4 +877943,3,10,3,10,6,10,5,1,4,4 +888169,3,2,2,1,4,3,2,1,1,2 +888523,4,4,4,2,2,3,2,1,1,2 +896404,2,1,1,1,2,1,3,1,1,2 +897172,2,1,1,1,2,1,2,1,1,2 +95719,6,10,10,10,8,10,7,10,7,4 +160296,5,8,8,10,5,10,8,10,3,4 +342245,1,1,3,1,2,1,1,1,1,2 +428598,1,1,3,1,1,1,2,1,1,2 +492561,4,3,2,1,3,1,2,1,1,2 +493452,1,1,3,1,2,1,1,1,1,2 +493452,4,1,2,1,2,1,2,1,1,2 +521441,5,1,1,2,2,1,2,1,1,2 +560680,3,1,2,1,2,1,2,1,1,2 +636437,1,1,1,1,2,1,1,1,1,2 +640712,1,1,1,1,2,1,2,1,1,2 +654244,1,1,1,1,1,1,2,1,1,2 +657753,3,1,1,4,3,1,2,2,1,2 +685977,5,3,4,1,4,1,3,1,1,2 +805448,1,1,1,1,2,1,1,1,1,2 +846423,10,6,3,6,4,10,7,8,4,4 +1002504,3,2,2,2,2,1,3,2,1,2 +1022257,2,1,1,1,2,1,1,1,1,2 +1026122,2,1,1,1,2,1,1,1,1,2 +1071084,3,3,2,2,3,1,1,2,3,2 +1080233,7,6,6,3,2,10,7,1,1,4 +1114570,5,3,3,2,3,1,3,1,1,2 +1114570,2,1,1,1,2,1,2,2,1,2 +1116715,5,1,1,1,3,2,2,2,1,2 +1131411,1,1,1,2,2,1,2,1,1,2 +1151734,10,8,7,4,3,10,7,9,1,4 +1156017,3,1,1,1,2,1,2,1,1,2 +1158247,1,1,1,1,1,1,1,1,1,2 +1158405,1,2,3,1,2,1,2,1,1,2 +1168278,3,1,1,1,2,1,2,1,1,2 +1176187,3,1,1,1,2,1,3,1,1,2 +1196263,4,1,1,1,2,1,1,1,1,2 +1196475,3,2,1,1,2,1,2,2,1,2 +1206314,1,2,3,1,2,1,1,1,1,2 +1211265,3,10,8,7,6,9,9,3,8,4 +1213784,3,1,1,1,2,1,1,1,1,2 +1223003,5,3,3,1,2,1,2,1,1,2 +1223306,3,1,1,1,2,4,1,1,1,2 +1223543,1,2,1,3,2,1,1,2,1,2 +1229929,1,1,1,1,2,1,2,1,1,2 +1231853,4,2,2,1,2,1,2,1,1,2 +1234554,1,1,1,1,2,1,2,1,1,2 +1236837,2,3,2,2,2,2,3,1,1,2 +1237674,3,1,2,1,2,1,2,1,1,2 +1238021,1,1,1,1,2,1,2,1,1,2 +1238464,1,1,1,1,1,?,2,1,1,2 +1238633,10,10,10,6,8,4,8,5,1,4 +1238915,5,1,2,1,2,1,3,1,1,2 +1238948,8,5,6,2,3,10,6,6,1,4 +1239232,3,3,2,6,3,3,3,5,1,2 +1239347,8,7,8,5,10,10,7,2,1,4 +1239967,1,1,1,1,2,1,2,1,1,2 +1240337,5,2,2,2,2,2,3,2,2,2 +1253505,2,3,1,1,5,1,1,1,1,2 +1255384,3,2,2,3,2,3,3,1,1,2 +1257200,10,10,10,7,10,10,8,2,1,4 +1257648,4,3,3,1,2,1,3,3,1,2 +1257815,5,1,3,1,2,1,2,1,1,2 +1257938,3,1,1,1,2,1,1,1,1,2 +1258549,9,10,10,10,10,10,10,10,1,4 +1258556,5,3,6,1,2,1,1,1,1,2 +1266154,8,7,8,2,4,2,5,10,1,4 +1272039,1,1,1,1,2,1,2,1,1,2 +1276091,2,1,1,1,2,1,2,1,1,2 +1276091,1,3,1,1,2,1,2,2,1,2 +1276091,5,1,1,3,4,1,3,2,1,2 +1277629,5,1,1,1,2,1,2,2,1,2 +1293439,3,2,2,3,2,1,1,1,1,2 +1293439,6,9,7,5,5,8,4,2,1,2 +1294562,10,8,10,1,3,10,5,1,1,4 +1295186,10,10,10,1,6,1,2,8,1,4 +527337,4,1,1,1,2,1,1,1,1,2 +558538,4,1,3,3,2,1,1,1,1,2 +566509,5,1,1,1,2,1,1,1,1,2 +608157,10,4,3,10,4,10,10,1,1,4 +677910,5,2,2,4,2,4,1,1,1,2 +734111,1,1,1,3,2,3,1,1,1,2 +734111,1,1,1,1,2,2,1,1,1,2 +780555,5,1,1,6,3,1,2,1,1,2 +827627,2,1,1,1,2,1,1,1,1,2 +1049837,1,1,1,1,2,1,1,1,1,2 +1058849,5,1,1,1,2,1,1,1,1,2 +1182404,1,1,1,1,1,1,1,1,1,2 +1193544,5,7,9,8,6,10,8,10,1,4 +1201870,4,1,1,3,1,1,2,1,1,2 +1202253,5,1,1,1,2,1,1,1,1,2 +1227081,3,1,1,3,2,1,1,1,1,2 +1230994,4,5,5,8,6,10,10,7,1,4 +1238410,2,3,1,1,3,1,1,1,1,2 +1246562,10,2,2,1,2,6,1,1,2,4 +1257470,10,6,5,8,5,10,8,6,1,4 +1259008,8,8,9,6,6,3,10,10,1,4 +1266124,5,1,2,1,2,1,1,1,1,2 +1267898,5,1,3,1,2,1,1,1,1,2 +1268313,5,1,1,3,2,1,1,1,1,2 +1268804,3,1,1,1,2,5,1,1,1,2 +1276091,6,1,1,3,2,1,1,1,1,2 +1280258,4,1,1,1,2,1,1,2,1,2 +1293966,4,1,1,1,2,1,1,1,1,2 +1296572,10,9,8,7,6,4,7,10,3,4 +1298416,10,6,6,2,4,10,9,7,1,4 +1299596,6,6,6,5,4,10,7,6,2,4 +1105524,4,1,1,1,2,1,1,1,1,2 +1181685,1,1,2,1,2,1,2,1,1,2 +1211594,3,1,1,1,1,1,2,1,1,2 +1238777,6,1,1,3,2,1,1,1,1,2 +1257608,6,1,1,1,1,1,1,1,1,2 +1269574,4,1,1,1,2,1,1,1,1,2 +1277145,5,1,1,1,2,1,1,1,1,2 +1287282,3,1,1,1,2,1,1,1,1,2 +1296025,4,1,2,1,2,1,1,1,1,2 +1296263,4,1,1,1,2,1,1,1,1,2 +1296593,5,2,1,1,2,1,1,1,1,2 +1299161,4,8,7,10,4,10,7,5,1,4 +1301945,5,1,1,1,1,1,1,1,1,2 +1302428,5,3,2,4,2,1,1,1,1,2 +1318169,9,10,10,10,10,5,10,10,10,4 +474162,8,7,8,5,5,10,9,10,1,4 +787451,5,1,2,1,2,1,1,1,1,2 +1002025,1,1,1,3,1,3,1,1,1,2 +1070522,3,1,1,1,1,1,2,1,1,2 +1073960,10,10,10,10,6,10,8,1,5,4 +1076352,3,6,4,10,3,3,3,4,1,4 +1084139,6,3,2,1,3,4,4,1,1,4 +1115293,1,1,1,1,2,1,1,1,1,2 +1119189,5,8,9,4,3,10,7,1,1,4 +1133991,4,1,1,1,1,1,2,1,1,2 +1142706,5,10,10,10,6,10,6,5,2,4 +1155967,5,1,2,10,4,5,2,1,1,2 +1170945,3,1,1,1,1,1,2,1,1,2 +1181567,1,1,1,1,1,1,1,1,1,2 +1182404,4,2,1,1,2,1,1,1,1,2 +1204558,4,1,1,1,2,1,2,1,1,2 +1217952,4,1,1,1,2,1,2,1,1,2 +1224565,6,1,1,1,2,1,3,1,1,2 +1238186,4,1,1,1,2,1,2,1,1,2 +1253917,4,1,1,2,2,1,2,1,1,2 +1265899,4,1,1,1,2,1,3,1,1,2 +1268766,1,1,1,1,2,1,1,1,1,2 +1277268,3,3,1,1,2,1,1,1,1,2 +1286943,8,10,10,10,7,5,4,8,7,4 +1295508,1,1,1,1,2,4,1,1,1,2 +1297327,5,1,1,1,2,1,1,1,1,2 +1297522,2,1,1,1,2,1,1,1,1,2 +1298360,1,1,1,1,2,1,1,1,1,2 +1299924,5,1,1,1,2,1,2,1,1,2 +1299994,5,1,1,1,2,1,1,1,1,2 +1304595,3,1,1,1,1,1,2,1,1,2 +1306282,6,6,7,10,3,10,8,10,2,4 +1313325,4,10,4,7,3,10,9,10,1,4 +1320077,1,1,1,1,1,1,1,1,1,2 +1320077,1,1,1,1,1,1,2,1,1,2 +1320304,3,1,2,2,2,1,1,1,1,2 +1330439,4,7,8,3,4,10,9,1,1,4 +333093,1,1,1,1,3,1,1,1,1,2 +369565,4,1,1,1,3,1,1,1,1,2 +412300,10,4,5,4,3,5,7,3,1,4 +672113,7,5,6,10,4,10,5,3,1,4 +749653,3,1,1,1,2,1,2,1,1,2 +769612,3,1,1,2,2,1,1,1,1,2 +769612,4,1,1,1,2,1,1,1,1,2 +798429,4,1,1,1,2,1,3,1,1,2 +807657,6,1,3,2,2,1,1,1,1,2 +8233704,4,1,1,1,1,1,2,1,1,2 +837480,7,4,4,3,4,10,6,9,1,4 +867392,4,2,2,1,2,1,2,1,1,2 +869828,1,1,1,1,1,1,3,1,1,2 +1043068,3,1,1,1,2,1,2,1,1,2 +1056171,2,1,1,1,2,1,2,1,1,2 +1061990,1,1,3,2,2,1,3,1,1,2 +1113061,5,1,1,1,2,1,3,1,1,2 +1116192,5,1,2,1,2,1,3,1,1,2 +1135090,4,1,1,1,2,1,2,1,1,2 +1145420,6,1,1,1,2,1,2,1,1,2 +1158157,5,1,1,1,2,2,2,1,1,2 +1171578,3,1,1,1,2,1,1,1,1,2 +1174841,5,3,1,1,2,1,1,1,1,2 +1184586,4,1,1,1,2,1,2,1,1,2 +1186936,2,1,3,2,2,1,2,1,1,2 +1197527,5,1,1,1,2,1,2,1,1,2 +1222464,6,10,10,10,4,10,7,10,1,4 +1240603,2,1,1,1,1,1,1,1,1,2 +1240603,3,1,1,1,1,1,1,1,1,2 +1241035,7,8,3,7,4,5,7,8,2,4 +1287971,3,1,1,1,2,1,2,1,1,2 +1289391,1,1,1,1,2,1,3,1,1,2 +1299924,3,2,2,2,2,1,4,2,1,2 +1306339,4,4,2,1,2,5,2,1,2,2 +1313658,3,1,1,1,2,1,1,1,1,2 +1313982,4,3,1,1,2,1,4,8,1,2 +1321264,5,2,2,2,1,1,2,1,1,2 +1321321,5,1,1,3,2,1,1,1,1,2 +1321348,2,1,1,1,2,1,2,1,1,2 +1321931,5,1,1,1,2,1,2,1,1,2 +1321942,5,1,1,1,2,1,3,1,1,2 +1321942,5,1,1,1,2,1,3,1,1,2 +1328331,1,1,1,1,2,1,3,1,1,2 +1328755,3,1,1,1,2,1,2,1,1,2 +1331405,4,1,1,1,2,1,3,2,1,2 +1331412,5,7,10,10,5,10,10,10,1,4 +1333104,3,1,2,1,2,1,3,1,1,2 +1334071,4,1,1,1,2,3,2,1,1,2 +1343068,8,4,4,1,6,10,2,5,2,4 +1343374,10,10,8,10,6,5,10,3,1,4 +1344121,8,10,4,4,8,10,8,2,1,4 +142932,7,6,10,5,3,10,9,10,2,4 +183936,3,1,1,1,2,1,2,1,1,2 +324382,1,1,1,1,2,1,2,1,1,2 +378275,10,9,7,3,4,2,7,7,1,4 +385103,5,1,2,1,2,1,3,1,1,2 +690557,5,1,1,1,2,1,2,1,1,2 +695091,1,1,1,1,2,1,2,1,1,2 +695219,1,1,1,1,2,1,2,1,1,2 +824249,1,1,1,1,2,1,3,1,1,2 +871549,5,1,2,1,2,1,2,1,1,2 +878358,5,7,10,6,5,10,7,5,1,4 +1107684,6,10,5,5,4,10,6,10,1,4 +1115762,3,1,1,1,2,1,1,1,1,2 +1217717,5,1,1,6,3,1,1,1,1,2 +1239420,1,1,1,1,2,1,1,1,1,2 +1254538,8,10,10,10,6,10,10,10,1,4 +1261751,5,1,1,1,2,1,2,2,1,2 +1268275,9,8,8,9,6,3,4,1,1,4 +1272166,5,1,1,1,2,1,1,1,1,2 +1294261,4,10,8,5,4,1,10,1,1,4 +1295529,2,5,7,6,4,10,7,6,1,4 +1298484,10,3,4,5,3,10,4,1,1,4 +1311875,5,1,2,1,2,1,1,1,1,2 +1315506,4,8,6,3,4,10,7,1,1,4 +1320141,5,1,1,1,2,1,2,1,1,2 +1325309,4,1,2,1,2,1,2,1,1,2 +1333063,5,1,3,1,2,1,3,1,1,2 +1333495,3,1,1,1,2,1,2,1,1,2 +1334659,5,2,4,1,1,1,1,1,1,2 +1336798,3,1,1,1,2,1,2,1,1,2 +1344449,1,1,1,1,1,1,2,1,1,2 +1350568,4,1,1,1,2,1,2,1,1,2 +1352663,5,4,6,8,4,1,8,10,1,4 +188336,5,3,2,8,5,10,8,1,2,4 +352431,10,5,10,3,5,8,7,8,3,4 +353098,4,1,1,2,2,1,1,1,1,2 +411453,1,1,1,1,2,1,1,1,1,2 +557583,5,10,10,10,10,10,10,1,1,4 +636375,5,1,1,1,2,1,1,1,1,2 +736150,10,4,3,10,3,10,7,1,2,4 +803531,5,10,10,10,5,2,8,5,1,4 +822829,8,10,10,10,6,10,10,10,10,4 +1016634,2,3,1,1,2,1,2,1,1,2 +1031608,2,1,1,1,1,1,2,1,1,2 +1041043,4,1,3,1,2,1,2,1,1,2 +1042252,3,1,1,1,2,1,2,1,1,2 +1057067,1,1,1,1,1,?,1,1,1,2 +1061990,4,1,1,1,2,1,2,1,1,2 +1073836,5,1,1,1,2,1,2,1,1,2 +1083817,3,1,1,1,2,1,2,1,1,2 +1096352,6,3,3,3,3,2,6,1,1,2 +1140597,7,1,2,3,2,1,2,1,1,2 +1149548,1,1,1,1,2,1,1,1,1,2 +1174009,5,1,1,2,1,1,2,1,1,2 +1183596,3,1,3,1,3,4,1,1,1,2 +1190386,4,6,6,5,7,6,7,7,3,4 +1190546,2,1,1,1,2,5,1,1,1,2 +1213273,2,1,1,1,2,1,1,1,1,2 +1218982,4,1,1,1,2,1,1,1,1,2 +1225382,6,2,3,1,2,1,1,1,1,2 +1235807,5,1,1,1,2,1,2,1,1,2 +1238777,1,1,1,1,2,1,1,1,1,2 +1253955,8,7,4,4,5,3,5,10,1,4 +1257366,3,1,1,1,2,1,1,1,1,2 +1260659,3,1,4,1,2,1,1,1,1,2 +1268952,10,10,7,8,7,1,10,10,3,4 +1275807,4,2,4,3,2,2,2,1,1,2 +1277792,4,1,1,1,2,1,1,1,1,2 +1277792,5,1,1,3,2,1,1,1,1,2 +1285722,4,1,1,3,2,1,1,1,1,2 +1288608,3,1,1,1,2,1,2,1,1,2 +1290203,3,1,1,1,2,1,2,1,1,2 +1294413,1,1,1,1,2,1,1,1,1,2 +1299596,2,1,1,1,2,1,1,1,1,2 +1303489,3,1,1,1,2,1,2,1,1,2 +1311033,1,2,2,1,2,1,1,1,1,2 +1311108,1,1,1,3,2,1,1,1,1,2 +1315807,5,10,10,10,10,2,10,10,10,4 +1318671,3,1,1,1,2,1,2,1,1,2 +1319609,3,1,1,2,3,4,1,1,1,2 +1323477,1,2,1,3,2,1,2,1,1,2 +1324572,5,1,1,1,2,1,2,2,1,2 +1324681,4,1,1,1,2,1,2,1,1,2 +1325159,3,1,1,1,2,1,3,1,1,2 +1326892,3,1,1,1,2,1,2,1,1,2 +1330361,5,1,1,1,2,1,2,1,1,2 +1333877,5,4,5,1,8,1,3,6,1,2 +1334015,7,8,8,7,3,10,7,2,3,4 +1334667,1,1,1,1,2,1,1,1,1,2 +1339781,1,1,1,1,2,1,2,1,1,2 +1339781,4,1,1,1,2,1,3,1,1,2 +13454352,1,1,3,1,2,1,2,1,1,2 +1345452,1,1,3,1,2,1,2,1,1,2 +1345593,3,1,1,3,2,1,2,1,1,2 +1347749,1,1,1,1,2,1,1,1,1,2 +1347943,5,2,2,2,2,1,1,1,2,2 +1348851,3,1,1,1,2,1,3,1,1,2 +1350319,5,7,4,1,6,1,7,10,3,4 +1350423,5,10,10,8,5,5,7,10,1,4 +1352848,3,10,7,8,5,8,7,4,1,4 +1353092,3,2,1,2,2,1,3,1,1,2 +1354840,2,1,1,1,2,1,3,1,1,2 +1354840,5,3,2,1,3,1,1,1,1,2 +1355260,1,1,1,1,2,1,2,1,1,2 +1365075,4,1,4,1,2,1,1,1,1,2 +1365328,1,1,2,1,2,1,2,1,1,2 +1368267,5,1,1,1,2,1,1,1,1,2 +1368273,1,1,1,1,2,1,1,1,1,2 +1368882,2,1,1,1,2,1,1,1,1,2 +1369821,10,10,10,10,5,10,10,10,7,4 +1371026,5,10,10,10,4,10,5,6,3,4 +1371920,5,1,1,1,2,1,3,2,1,2 +466906,1,1,1,1,2,1,1,1,1,2 +466906,1,1,1,1,2,1,1,1,1,2 +534555,1,1,1,1,2,1,1,1,1,2 +536708,1,1,1,1,2,1,1,1,1,2 +566346,3,1,1,1,2,1,2,3,1,2 +603148,4,1,1,1,2,1,1,1,1,2 +654546,1,1,1,1,2,1,1,1,8,2 +654546,1,1,1,3,2,1,1,1,1,2 +695091,5,10,10,5,4,5,4,4,1,4 +714039,3,1,1,1,2,1,1,1,1,2 +763235,3,1,1,1,2,1,2,1,2,2 +776715,3,1,1,1,3,2,1,1,1,2 +841769,2,1,1,1,2,1,1,1,1,2 +888820,5,10,10,3,7,3,8,10,2,4 +897471,4,8,6,4,3,4,10,6,1,4 +897471,4,8,8,5,4,5,10,4,1,4 diff --git a/datasets/tictactoe.csv b/datasets/tictactoe.csv new file mode 100644 index 0000000..40e3574 --- /dev/null +++ b/datasets/tictactoe.csv @@ -0,0 +1,958 @@ +x,x,x,x,o,o,x,o,o,positive +x,x,x,x,o,o,o,x,o,positive +x,x,x,x,o,o,o,o,x,positive +x,x,x,x,o,o,o,b,b,positive +x,x,x,x,o,o,b,o,b,positive +x,x,x,x,o,o,b,b,o,positive +x,x,x,x,o,b,o,o,b,positive +x,x,x,x,o,b,o,b,o,positive +x,x,x,x,o,b,b,o,o,positive +x,x,x,x,b,o,o,o,b,positive +x,x,x,x,b,o,o,b,o,positive +x,x,x,x,b,o,b,o,o,positive +x,x,x,o,x,o,x,o,o,positive +x,x,x,o,x,o,o,x,o,positive +x,x,x,o,x,o,o,o,x,positive +x,x,x,o,x,o,o,b,b,positive +x,x,x,o,x,o,b,o,b,positive +x,x,x,o,x,o,b,b,o,positive +x,x,x,o,x,b,o,o,b,positive +x,x,x,o,x,b,o,b,o,positive +x,x,x,o,x,b,b,o,o,positive +x,x,x,o,o,x,x,o,o,positive +x,x,x,o,o,x,o,x,o,positive +x,x,x,o,o,x,o,o,x,positive +x,x,x,o,o,x,o,b,b,positive +x,x,x,o,o,x,b,o,b,positive +x,x,x,o,o,x,b,b,o,positive +x,x,x,o,o,b,x,o,b,positive +x,x,x,o,o,b,x,b,o,positive +x,x,x,o,o,b,o,x,b,positive +x,x,x,o,o,b,o,b,x,positive +x,x,x,o,o,b,b,x,o,positive +x,x,x,o,o,b,b,o,x,positive +x,x,x,o,o,b,b,b,b,positive +x,x,x,o,b,x,o,o,b,positive +x,x,x,o,b,x,o,b,o,positive +x,x,x,o,b,x,b,o,o,positive +x,x,x,o,b,o,x,o,b,positive +x,x,x,o,b,o,x,b,o,positive +x,x,x,o,b,o,o,x,b,positive +x,x,x,o,b,o,o,b,x,positive +x,x,x,o,b,o,b,x,o,positive +x,x,x,o,b,o,b,o,x,positive +x,x,x,o,b,o,b,b,b,positive +x,x,x,o,b,b,x,o,o,positive +x,x,x,o,b,b,o,x,o,positive +x,x,x,o,b,b,o,o,x,positive +x,x,x,o,b,b,o,b,b,positive +x,x,x,o,b,b,b,o,b,positive +x,x,x,o,b,b,b,b,o,positive +x,x,x,b,x,o,o,o,b,positive +x,x,x,b,x,o,o,b,o,positive +x,x,x,b,x,o,b,o,o,positive +x,x,x,b,o,x,o,o,b,positive +x,x,x,b,o,x,o,b,o,positive +x,x,x,b,o,x,b,o,o,positive +x,x,x,b,o,o,x,o,b,positive +x,x,x,b,o,o,x,b,o,positive +x,x,x,b,o,o,o,x,b,positive +x,x,x,b,o,o,o,b,x,positive +x,x,x,b,o,o,b,x,o,positive +x,x,x,b,o,o,b,o,x,positive +x,x,x,b,o,o,b,b,b,positive +x,x,x,b,o,b,x,o,o,positive +x,x,x,b,o,b,o,x,o,positive +x,x,x,b,o,b,o,o,x,positive +x,x,x,b,o,b,o,b,b,positive +x,x,x,b,o,b,b,o,b,positive +x,x,x,b,o,b,b,b,o,positive +x,x,x,b,b,o,x,o,o,positive +x,x,x,b,b,o,o,x,o,positive +x,x,x,b,b,o,o,o,x,positive +x,x,x,b,b,o,o,b,b,positive +x,x,x,b,b,o,b,o,b,positive +x,x,x,b,b,o,b,b,o,positive +x,x,x,b,b,b,o,o,b,positive +x,x,x,b,b,b,o,b,o,positive +x,x,x,b,b,b,b,o,o,positive +x,x,o,x,x,o,o,o,x,positive +x,x,o,x,o,x,x,o,o,positive +x,x,o,x,o,o,x,o,x,positive +x,x,o,x,o,o,x,b,b,positive +x,x,o,x,o,b,x,o,b,positive +x,x,o,x,o,b,x,b,o,positive +x,x,o,x,b,o,x,o,b,positive +x,x,o,x,b,b,x,o,o,positive +x,x,o,o,x,x,o,x,o,positive +x,x,o,o,x,x,o,o,x,positive +x,x,o,o,x,o,x,o,x,positive +x,x,o,o,x,o,o,x,x,positive +x,x,o,o,x,o,b,x,b,positive +x,x,o,o,x,o,b,b,x,positive +x,x,o,o,x,b,o,x,b,positive +x,x,o,o,x,b,o,b,x,positive +x,x,o,o,x,b,b,x,o,positive +x,x,o,o,x,b,b,o,x,positive +x,x,o,b,x,o,o,x,b,positive +x,x,o,b,x,o,o,b,x,positive +x,x,o,b,x,o,b,o,x,positive +x,x,o,b,x,b,o,x,o,positive +x,x,o,b,x,b,o,o,x,positive +x,x,b,x,o,o,x,o,b,positive +x,x,b,x,o,o,x,b,o,positive +x,x,b,x,o,b,x,o,o,positive +x,x,b,x,b,o,x,o,o,positive +x,x,b,o,x,o,o,x,b,positive +x,x,b,o,x,o,o,b,x,positive +x,x,b,o,x,o,b,x,o,positive +x,x,b,o,x,o,b,o,x,positive +x,x,b,o,x,b,o,x,o,positive +x,x,b,o,x,b,o,o,x,positive +x,x,b,b,x,o,o,x,o,positive +x,x,b,b,x,o,o,o,x,positive +x,o,x,x,x,o,x,o,o,positive +x,o,x,x,x,o,o,o,x,positive +x,o,x,x,o,o,x,x,o,positive +x,o,x,x,o,o,x,b,b,positive +x,o,x,x,o,b,x,b,o,positive +x,o,x,x,b,o,x,o,b,positive +x,o,x,x,b,o,x,b,o,positive +x,o,x,x,b,b,x,o,o,positive +x,o,x,o,x,x,x,o,o,positive +x,o,x,o,x,x,o,o,x,positive +x,o,x,o,x,o,x,x,o,positive +x,o,x,o,x,o,x,o,x,positive +x,o,x,o,x,o,x,b,b,positive +x,o,x,o,x,o,o,x,x,positive +x,o,x,o,x,o,b,b,x,positive +x,o,x,o,x,b,x,o,b,positive +x,o,x,o,x,b,x,b,o,positive +x,o,x,o,x,b,o,b,x,positive +x,o,x,o,x,b,b,o,x,positive +x,o,x,o,o,x,o,x,x,positive +x,o,x,o,o,x,b,b,x,positive +x,o,x,o,b,x,o,b,x,positive +x,o,x,o,b,x,b,o,x,positive +x,o,x,b,x,o,x,o,b,positive +x,o,x,b,x,o,x,b,o,positive +x,o,x,b,x,o,o,b,x,positive +x,o,x,b,x,o,b,o,x,positive +x,o,x,b,x,b,x,o,o,positive +x,o,x,b,x,b,o,o,x,positive +x,o,x,b,o,x,o,b,x,positive +x,o,x,b,b,x,o,o,x,positive +x,o,o,x,x,x,x,o,o,positive +x,o,o,x,x,x,o,x,o,positive +x,o,o,x,x,x,o,o,x,positive +x,o,o,x,x,x,o,b,b,positive +x,o,o,x,x,x,b,o,b,positive +x,o,o,x,x,x,b,b,o,positive +x,o,o,x,x,o,x,o,x,positive +x,o,o,x,x,o,x,b,b,positive +x,o,o,x,x,o,o,x,x,positive +x,o,o,x,x,o,b,b,x,positive +x,o,o,x,x,b,x,o,b,positive +x,o,o,x,x,b,x,b,o,positive +x,o,o,x,x,b,o,b,x,positive +x,o,o,x,x,b,b,o,x,positive +x,o,o,x,o,x,x,x,o,positive +x,o,o,x,o,x,x,b,b,positive +x,o,o,x,o,o,x,x,x,positive +x,o,o,x,o,b,x,x,b,positive +x,o,o,x,o,b,x,b,x,positive +x,o,o,x,b,x,x,o,b,positive +x,o,o,x,b,x,x,b,o,positive +x,o,o,x,b,o,x,x,b,positive +x,o,o,x,b,o,x,b,x,positive +x,o,o,x,b,b,x,x,o,positive +x,o,o,x,b,b,x,o,x,positive +x,o,o,x,b,b,x,b,b,positive +x,o,o,o,x,x,x,o,x,positive +x,o,o,o,x,x,o,x,x,positive +x,o,o,o,x,x,b,b,x,positive +x,o,o,o,x,o,x,x,x,positive +x,o,o,o,x,b,x,b,x,positive +x,o,o,o,x,b,b,x,x,positive +x,o,o,o,o,x,x,x,x,positive +x,o,o,o,b,b,x,x,x,positive +x,o,o,b,x,x,o,b,x,positive +x,o,o,b,x,x,b,o,x,positive +x,o,o,b,x,o,x,b,x,positive +x,o,o,b,x,o,b,x,x,positive +x,o,o,b,x,b,x,o,x,positive +x,o,o,b,x,b,o,x,x,positive +x,o,o,b,x,b,b,b,x,positive +x,o,o,b,o,b,x,x,x,positive +x,o,o,b,b,o,x,x,x,positive +x,o,b,x,x,x,o,o,b,positive +x,o,b,x,x,x,o,b,o,positive +x,o,b,x,x,x,b,o,o,positive +x,o,b,x,x,o,x,o,b,positive +x,o,b,x,x,o,x,b,o,positive +x,o,b,x,x,o,o,b,x,positive +x,o,b,x,x,o,b,o,x,positive +x,o,b,x,x,b,x,o,o,positive +x,o,b,x,x,b,o,o,x,positive +x,o,b,x,o,x,x,b,o,positive +x,o,b,x,o,o,x,x,b,positive +x,o,b,x,o,o,x,b,x,positive +x,o,b,x,o,b,x,x,o,positive +x,o,b,x,o,b,x,b,b,positive +x,o,b,x,b,x,x,o,o,positive +x,o,b,x,b,o,x,x,o,positive +x,o,b,x,b,o,x,o,x,positive +x,o,b,x,b,o,x,b,b,positive +x,o,b,x,b,b,x,o,b,positive +x,o,b,x,b,b,x,b,o,positive +x,o,b,o,x,x,o,b,x,positive +x,o,b,o,x,x,b,o,x,positive +x,o,b,o,x,o,x,b,x,positive +x,o,b,o,x,o,b,x,x,positive +x,o,b,o,x,b,x,o,x,positive +x,o,b,o,x,b,o,x,x,positive +x,o,b,o,x,b,b,b,x,positive +x,o,b,o,o,b,x,x,x,positive +x,o,b,o,b,o,x,x,x,positive +x,o,b,b,x,x,o,o,x,positive +x,o,b,b,x,o,x,o,x,positive +x,o,b,b,x,o,o,x,x,positive +x,o,b,b,x,o,b,b,x,positive +x,o,b,b,x,b,o,b,x,positive +x,o,b,b,x,b,b,o,x,positive +x,o,b,b,o,o,x,x,x,positive +x,b,x,x,o,o,x,o,b,positive +x,b,x,x,o,o,x,b,o,positive +x,b,x,x,o,b,x,o,o,positive +x,b,x,x,b,o,x,o,o,positive +x,b,x,o,x,o,x,o,b,positive +x,b,x,o,x,o,x,b,o,positive +x,b,x,o,x,o,o,b,x,positive +x,b,x,o,x,o,b,o,x,positive +x,b,x,o,x,b,x,o,o,positive +x,b,x,o,x,b,o,o,x,positive +x,b,x,o,o,x,o,b,x,positive +x,b,x,o,o,x,b,o,x,positive +x,b,x,o,b,x,o,o,x,positive +x,b,x,b,x,o,x,o,o,positive +x,b,x,b,x,o,o,o,x,positive +x,b,x,b,o,x,o,o,x,positive +x,b,o,x,x,x,o,o,b,positive +x,b,o,x,x,x,o,b,o,positive +x,b,o,x,x,x,b,o,o,positive +x,b,o,x,x,o,x,o,b,positive +x,b,o,x,x,o,o,b,x,positive +x,b,o,x,x,o,b,o,x,positive +x,b,o,x,x,b,x,o,o,positive +x,b,o,x,x,b,o,o,x,positive +x,b,o,x,o,x,x,o,b,positive +x,b,o,x,o,x,x,b,o,positive +x,b,o,x,o,o,x,x,b,positive +x,b,o,x,o,o,x,b,x,positive +x,b,o,x,o,b,x,x,o,positive +x,b,o,x,o,b,x,o,x,positive +x,b,o,x,o,b,x,b,b,positive +x,b,o,x,b,x,x,o,o,positive +x,b,o,x,b,o,x,o,x,positive +x,b,o,x,b,o,x,b,b,positive +x,b,o,x,b,b,x,o,b,positive +x,b,o,x,b,b,x,b,o,positive +x,b,o,o,x,x,o,b,x,positive +x,b,o,o,x,x,b,o,x,positive +x,b,o,o,x,o,x,b,x,positive +x,b,o,o,x,o,b,x,x,positive +x,b,o,o,x,b,x,o,x,positive +x,b,o,o,x,b,o,x,x,positive +x,b,o,o,x,b,b,b,x,positive +x,b,o,o,o,b,x,x,x,positive +x,b,o,o,b,o,x,x,x,positive +x,b,o,b,x,x,o,o,x,positive +x,b,o,b,x,o,x,o,x,positive +x,b,o,b,x,o,o,x,x,positive +x,b,o,b,x,o,b,b,x,positive +x,b,o,b,x,b,o,b,x,positive +x,b,o,b,x,b,b,o,x,positive +x,b,o,b,o,o,x,x,x,positive +x,b,b,x,x,o,x,o,o,positive +x,b,b,x,x,o,o,o,x,positive +x,b,b,x,o,x,x,o,o,positive +x,b,b,x,o,o,x,x,o,positive +x,b,b,x,o,o,x,o,x,positive +x,b,b,x,o,o,x,b,b,positive +x,b,b,x,o,b,x,o,b,positive +x,b,b,x,o,b,x,b,o,positive +x,b,b,x,b,o,x,o,b,positive +x,b,b,x,b,o,x,b,o,positive +x,b,b,x,b,b,x,o,o,positive +x,b,b,o,x,x,o,o,x,positive +x,b,b,o,x,o,x,o,x,positive +x,b,b,o,x,o,o,x,x,positive +x,b,b,o,x,o,b,b,x,positive +x,b,b,o,x,b,o,b,x,positive +x,b,b,o,x,b,b,o,x,positive +x,b,b,b,x,o,o,b,x,positive +x,b,b,b,x,o,b,o,x,positive +x,b,b,b,x,b,o,o,x,positive +o,x,x,x,x,o,x,o,o,positive +o,x,x,x,x,o,o,x,o,positive +o,x,x,x,o,x,o,o,x,positive +o,x,x,o,x,x,x,o,o,positive +o,x,x,o,x,o,x,x,o,positive +o,x,x,o,x,o,x,o,x,positive +o,x,x,o,x,o,x,b,b,positive +o,x,x,o,x,o,b,x,b,positive +o,x,x,o,x,b,x,o,b,positive +o,x,x,o,x,b,x,b,o,positive +o,x,x,o,x,b,b,x,o,positive +o,x,x,o,o,x,x,o,x,positive +o,x,x,o,o,x,b,b,x,positive +o,x,x,o,b,x,b,o,x,positive +o,x,x,b,x,o,x,o,b,positive +o,x,x,b,x,o,x,b,o,positive +o,x,x,b,x,o,o,x,b,positive +o,x,x,b,x,o,b,x,o,positive +o,x,x,b,x,b,x,o,o,positive +o,x,x,b,x,b,o,x,o,positive +o,x,x,b,o,x,o,b,x,positive +o,x,x,b,o,x,b,o,x,positive +o,x,x,b,b,x,o,o,x,positive +o,x,o,x,x,x,x,o,o,positive +o,x,o,x,x,x,o,x,o,positive +o,x,o,x,x,x,o,o,x,positive +o,x,o,x,x,x,o,b,b,positive +o,x,o,x,x,x,b,o,b,positive +o,x,o,x,x,x,b,b,o,positive +o,x,o,x,x,o,o,x,x,positive +o,x,o,x,x,o,b,x,b,positive +o,x,o,x,x,b,o,x,b,positive +o,x,o,x,x,b,b,x,o,positive +o,x,o,x,o,o,x,x,x,positive +o,x,o,o,x,x,x,x,o,positive +o,x,o,o,x,x,b,x,b,positive +o,x,o,o,x,o,x,x,x,positive +o,x,o,o,x,b,x,x,b,positive +o,x,o,o,x,b,b,x,x,positive +o,x,o,o,o,x,x,x,x,positive +o,x,o,o,b,b,x,x,x,positive +o,x,o,b,x,x,o,x,b,positive +o,x,o,b,x,x,b,x,o,positive +o,x,o,b,x,o,x,x,b,positive +o,x,o,b,x,o,b,x,x,positive +o,x,o,b,x,b,x,x,o,positive +o,x,o,b,x,b,o,x,x,positive +o,x,o,b,x,b,b,x,b,positive +o,x,o,b,o,b,x,x,x,positive +o,x,o,b,b,o,x,x,x,positive +o,x,b,x,x,x,o,o,b,positive +o,x,b,x,x,x,o,b,o,positive +o,x,b,x,x,x,b,o,o,positive +o,x,b,x,x,o,o,x,b,positive +o,x,b,x,x,o,b,x,o,positive +o,x,b,x,x,b,o,x,o,positive +o,x,b,o,x,x,b,x,o,positive +o,x,b,o,x,o,x,x,b,positive +o,x,b,o,x,o,b,x,x,positive +o,x,b,o,x,b,x,x,o,positive +o,x,b,o,x,b,b,x,b,positive +o,x,b,o,o,b,x,x,x,positive +o,x,b,o,b,o,x,x,x,positive +o,x,b,b,x,x,o,x,o,positive +o,x,b,b,x,o,x,x,o,positive +o,x,b,b,x,o,o,x,x,positive +o,x,b,b,x,o,b,x,b,positive +o,x,b,b,x,b,o,x,b,positive +o,x,b,b,x,b,b,x,o,positive +o,x,b,b,o,o,x,x,x,positive +o,o,x,x,x,x,x,o,o,positive +o,o,x,x,x,x,o,x,o,positive +o,o,x,x,x,x,o,o,x,positive +o,o,x,x,x,x,o,b,b,positive +o,o,x,x,x,x,b,o,b,positive +o,o,x,x,x,x,b,b,o,positive +o,o,x,x,x,o,x,x,o,positive +o,o,x,x,x,o,x,o,x,positive +o,o,x,x,x,o,x,b,b,positive +o,o,x,x,x,b,x,o,b,positive +o,o,x,x,x,b,x,b,o,positive +o,o,x,x,o,x,o,x,x,positive +o,o,x,x,o,x,b,b,x,positive +o,o,x,x,o,o,x,x,x,positive +o,o,x,x,b,x,o,b,x,positive +o,o,x,x,b,x,b,o,x,positive +o,o,x,o,x,x,x,x,o,positive +o,o,x,o,x,x,x,o,x,positive +o,o,x,o,x,x,x,b,b,positive +o,o,x,o,x,x,b,b,x,positive +o,o,x,o,x,o,x,x,x,positive +o,o,x,o,x,b,x,x,b,positive +o,o,x,o,x,b,x,b,x,positive +o,o,x,o,o,x,x,x,x,positive +o,o,x,o,b,x,x,b,x,positive +o,o,x,o,b,x,b,x,x,positive +o,o,x,o,b,b,x,x,x,positive +o,o,x,b,x,x,x,o,b,positive +o,o,x,b,x,x,x,b,o,positive +o,o,x,b,x,x,o,b,x,positive +o,o,x,b,x,x,b,o,x,positive +o,o,x,b,x,o,x,x,b,positive +o,o,x,b,x,o,x,b,x,positive +o,o,x,b,x,b,x,x,o,positive +o,o,x,b,x,b,x,o,x,positive +o,o,x,b,x,b,x,b,b,positive +o,o,x,b,o,x,x,b,x,positive +o,o,x,b,o,x,b,x,x,positive +o,o,x,b,o,b,x,x,x,positive +o,o,x,b,b,x,x,o,x,positive +o,o,x,b,b,x,o,x,x,positive +o,o,x,b,b,x,b,b,x,positive +o,o,x,b,b,o,x,x,x,positive +o,o,b,x,x,x,x,o,b,positive +o,o,b,x,x,x,x,b,o,positive +o,o,b,x,x,x,o,x,b,positive +o,o,b,x,x,x,o,b,x,positive +o,o,b,x,x,x,b,x,o,positive +o,o,b,x,x,x,b,o,x,positive +o,o,b,x,x,x,b,b,b,positive +o,o,b,x,o,b,x,x,x,positive +o,o,b,x,b,o,x,x,x,positive +o,o,b,o,x,b,x,x,x,positive +o,o,b,o,b,x,x,x,x,positive +o,o,b,b,x,o,x,x,x,positive +o,o,b,b,o,x,x,x,x,positive +o,o,b,b,b,b,x,x,x,positive +o,b,x,x,x,x,o,o,b,positive +o,b,x,x,x,x,o,b,o,positive +o,b,x,x,x,x,b,o,o,positive +o,b,x,x,x,o,x,o,b,positive +o,b,x,x,x,o,x,b,o,positive +o,b,x,x,x,b,x,o,o,positive +o,b,x,x,o,x,o,b,x,positive +o,b,x,x,o,x,b,o,x,positive +o,b,x,x,b,x,o,o,x,positive +o,b,x,o,x,x,x,o,b,positive +o,b,x,o,x,x,x,b,o,positive +o,b,x,o,x,x,b,o,x,positive +o,b,x,o,x,o,x,x,b,positive +o,b,x,o,x,o,x,b,x,positive +o,b,x,o,x,b,x,x,o,positive +o,b,x,o,x,b,x,o,x,positive +o,b,x,o,x,b,x,b,b,positive +o,b,x,o,o,x,x,b,x,positive +o,b,x,o,o,x,b,x,x,positive +o,b,x,o,o,b,x,x,x,positive +o,b,x,o,b,x,x,o,x,positive +o,b,x,o,b,x,b,b,x,positive +o,b,x,o,b,o,x,x,x,positive +o,b,x,b,x,x,x,o,o,positive +o,b,x,b,x,x,o,o,x,positive +o,b,x,b,x,o,x,x,o,positive +o,b,x,b,x,o,x,o,x,positive +o,b,x,b,x,o,x,b,b,positive +o,b,x,b,x,b,x,o,b,positive +o,b,x,b,x,b,x,b,o,positive +o,b,x,b,o,x,x,o,x,positive +o,b,x,b,o,x,o,x,x,positive +o,b,x,b,o,x,b,b,x,positive +o,b,x,b,o,o,x,x,x,positive +o,b,x,b,b,x,o,b,x,positive +o,b,x,b,b,x,b,o,x,positive +o,b,o,x,x,x,x,o,b,positive +o,b,o,x,x,x,x,b,o,positive +o,b,o,x,x,x,o,x,b,positive +o,b,o,x,x,x,o,b,x,positive +o,b,o,x,x,x,b,x,o,positive +o,b,o,x,x,x,b,o,x,positive +o,b,o,x,x,x,b,b,b,positive +o,b,o,x,o,b,x,x,x,positive +o,b,o,x,b,o,x,x,x,positive +o,b,o,o,x,b,x,x,x,positive +o,b,o,o,b,x,x,x,x,positive +o,b,o,b,x,o,x,x,x,positive +o,b,o,b,o,x,x,x,x,positive +o,b,o,b,b,b,x,x,x,positive +o,b,b,x,x,x,x,o,o,positive +o,b,b,x,x,x,o,x,o,positive +o,b,b,x,x,x,o,o,x,positive +o,b,b,x,x,x,o,b,b,positive +o,b,b,x,x,x,b,o,b,positive +o,b,b,x,x,x,b,b,o,positive +o,b,b,x,o,o,x,x,x,positive +o,b,b,o,x,o,x,x,x,positive +o,b,b,o,o,x,x,x,x,positive +o,b,b,o,b,b,x,x,x,positive +o,b,b,b,o,b,x,x,x,positive +o,b,b,b,b,o,x,x,x,positive +b,x,x,o,x,o,x,o,b,positive +b,x,x,o,x,o,x,b,o,positive +b,x,x,o,x,o,o,x,b,positive +b,x,x,o,x,o,b,x,o,positive +b,x,x,o,x,b,x,o,o,positive +b,x,x,o,x,b,o,x,o,positive +b,x,x,o,o,x,o,b,x,positive +b,x,x,o,o,x,b,o,x,positive +b,x,x,o,b,x,o,o,x,positive +b,x,x,b,x,o,x,o,o,positive +b,x,x,b,x,o,o,x,o,positive +b,x,x,b,o,x,o,o,x,positive +b,x,o,x,x,x,o,o,b,positive +b,x,o,x,x,x,o,b,o,positive +b,x,o,x,x,x,b,o,o,positive +b,x,o,x,x,o,o,x,b,positive +b,x,o,x,x,b,o,x,o,positive +b,x,o,o,x,x,o,x,b,positive +b,x,o,o,x,x,b,x,o,positive +b,x,o,o,x,o,x,x,b,positive +b,x,o,o,x,o,b,x,x,positive +b,x,o,o,x,b,x,x,o,positive +b,x,o,o,x,b,o,x,x,positive +b,x,o,o,x,b,b,x,b,positive +b,x,o,o,o,b,x,x,x,positive +b,x,o,o,b,o,x,x,x,positive +b,x,o,b,x,x,o,x,o,positive +b,x,o,b,x,o,o,x,x,positive +b,x,o,b,x,o,b,x,b,positive +b,x,o,b,x,b,o,x,b,positive +b,x,o,b,x,b,b,x,o,positive +b,x,o,b,o,o,x,x,x,positive +b,x,b,x,x,o,o,x,o,positive +b,x,b,o,x,x,o,x,o,positive +b,x,b,o,x,o,x,x,o,positive +b,x,b,o,x,o,o,x,x,positive +b,x,b,o,x,o,b,x,b,positive +b,x,b,o,x,b,o,x,b,positive +b,x,b,o,x,b,b,x,o,positive +b,x,b,b,x,o,o,x,b,positive +b,x,b,b,x,o,b,x,o,positive +b,x,b,b,x,b,o,x,o,positive +b,o,x,x,x,x,o,o,b,positive +b,o,x,x,x,x,o,b,o,positive +b,o,x,x,x,x,b,o,o,positive +b,o,x,x,x,o,x,o,b,positive +b,o,x,x,x,o,x,b,o,positive +b,o,x,x,x,b,x,o,o,positive +b,o,x,x,o,x,o,b,x,positive +b,o,x,x,b,x,o,o,x,positive +b,o,x,o,x,x,x,o,b,positive +b,o,x,o,x,x,x,b,o,positive +b,o,x,o,x,x,o,b,x,positive +b,o,x,o,x,x,b,o,x,positive +b,o,x,o,x,o,x,x,b,positive +b,o,x,o,x,o,x,b,x,positive +b,o,x,o,x,b,x,x,o,positive +b,o,x,o,x,b,x,o,x,positive +b,o,x,o,x,b,x,b,b,positive +b,o,x,o,o,x,x,b,x,positive +b,o,x,o,o,x,b,x,x,positive +b,o,x,o,o,b,x,x,x,positive +b,o,x,o,b,x,x,o,x,positive +b,o,x,o,b,x,o,x,x,positive +b,o,x,o,b,x,b,b,x,positive +b,o,x,o,b,o,x,x,x,positive +b,o,x,b,x,x,x,o,o,positive +b,o,x,b,x,x,o,o,x,positive +b,o,x,b,x,o,x,x,o,positive +b,o,x,b,x,o,x,o,x,positive +b,o,x,b,x,o,x,b,b,positive +b,o,x,b,x,b,x,o,b,positive +b,o,x,b,x,b,x,b,o,positive +b,o,x,b,o,x,o,x,x,positive +b,o,x,b,o,x,b,b,x,positive +b,o,x,b,o,o,x,x,x,positive +b,o,x,b,b,x,o,b,x,positive +b,o,x,b,b,x,b,o,x,positive +b,o,o,x,x,x,x,o,b,positive +b,o,o,x,x,x,x,b,o,positive +b,o,o,x,x,x,o,x,b,positive +b,o,o,x,x,x,o,b,x,positive +b,o,o,x,x,x,b,x,o,positive +b,o,o,x,x,x,b,o,x,positive +b,o,o,x,x,x,b,b,b,positive +b,o,o,x,o,b,x,x,x,positive +b,o,o,x,b,o,x,x,x,positive +b,o,o,o,x,b,x,x,x,positive +b,o,o,o,b,x,x,x,x,positive +b,o,o,b,x,o,x,x,x,positive +b,o,o,b,o,x,x,x,x,positive +b,o,o,b,b,b,x,x,x,positive +b,o,b,x,x,x,x,o,o,positive +b,o,b,x,x,x,o,x,o,positive +b,o,b,x,x,x,o,o,x,positive +b,o,b,x,x,x,o,b,b,positive +b,o,b,x,x,x,b,o,b,positive +b,o,b,x,x,x,b,b,o,positive +b,o,b,x,o,o,x,x,x,positive +b,o,b,o,x,o,x,x,x,positive +b,o,b,o,o,x,x,x,x,positive +b,o,b,o,b,b,x,x,x,positive +b,o,b,b,o,b,x,x,x,positive +b,o,b,b,b,o,x,x,x,positive +b,b,x,x,x,o,x,o,o,positive +b,b,x,x,o,x,o,o,x,positive +b,b,x,o,x,x,x,o,o,positive +b,b,x,o,x,x,o,o,x,positive +b,b,x,o,x,o,x,x,o,positive +b,b,x,o,x,o,x,o,x,positive +b,b,x,o,x,o,x,b,b,positive +b,b,x,o,x,b,x,o,b,positive +b,b,x,o,x,b,x,b,o,positive +b,b,x,o,o,x,x,o,x,positive +b,b,x,o,o,x,o,x,x,positive +b,b,x,o,o,x,b,b,x,positive +b,b,x,o,b,x,o,b,x,positive +b,b,x,o,b,x,b,o,x,positive +b,b,x,b,x,o,x,o,b,positive +b,b,x,b,x,o,x,b,o,positive +b,b,x,b,x,b,x,o,o,positive +b,b,x,b,o,x,o,b,x,positive +b,b,x,b,o,x,b,o,x,positive +b,b,x,b,b,x,o,o,x,positive +b,b,o,x,x,x,x,o,o,positive +b,b,o,x,x,x,o,x,o,positive +b,b,o,x,x,x,o,o,x,positive +b,b,o,x,x,x,o,b,b,positive +b,b,o,x,x,x,b,o,b,positive +b,b,o,x,x,x,b,b,o,positive +b,b,o,x,o,o,x,x,x,positive +b,b,o,o,x,o,x,x,x,positive +b,b,o,o,o,x,x,x,x,positive +b,b,o,o,b,b,x,x,x,positive +b,b,o,b,o,b,x,x,x,positive +b,b,o,b,b,o,x,x,x,positive +b,b,b,x,x,x,o,o,b,positive +b,b,b,x,x,x,o,b,o,positive +b,b,b,x,x,x,b,o,o,positive +b,b,b,o,o,b,x,x,x,positive +b,b,b,o,b,o,x,x,x,positive +b,b,b,b,o,o,x,x,x,positive +x,x,o,x,x,o,o,b,o,negative +x,x,o,x,x,o,b,o,o,negative +x,x,o,x,x,b,o,o,o,negative +x,x,o,x,o,x,o,o,b,negative +x,x,o,x,o,x,o,b,o,negative +x,x,o,x,o,o,o,x,b,negative +x,x,o,x,o,o,o,b,x,negative +x,x,o,x,o,o,b,x,o,negative +x,x,o,x,o,b,o,x,o,negative +x,x,o,x,o,b,o,o,x,negative +x,x,o,x,o,b,o,b,b,negative +x,x,o,x,b,x,o,o,o,negative +x,x,o,x,b,o,o,x,o,negative +x,x,o,x,b,o,b,b,o,negative +x,x,o,o,x,o,x,b,o,negative +x,x,o,o,o,x,o,x,b,negative +x,x,o,o,o,x,o,b,x,negative +x,x,o,o,o,o,x,x,b,negative +x,x,o,o,o,o,x,b,x,negative +x,x,o,o,o,o,b,x,x,negative +x,x,o,o,o,b,o,x,x,negative +x,x,o,o,b,o,x,x,o,negative +x,x,o,b,x,x,o,o,o,negative +x,x,o,b,x,o,x,o,o,negative +x,x,o,b,x,o,b,b,o,negative +x,x,o,b,o,x,o,x,o,negative +x,x,o,b,o,x,o,o,x,negative +x,x,o,b,o,x,o,b,b,negative +x,x,o,b,o,o,x,x,o,negative +x,x,o,b,o,o,o,x,x,negative +x,x,o,b,o,b,o,x,b,negative +x,x,o,b,o,b,o,b,x,negative +x,x,o,b,b,o,x,b,o,negative +x,x,o,b,b,o,b,x,o,negative +x,x,b,x,x,o,o,o,o,negative +x,x,b,x,o,x,o,o,o,negative +x,x,b,x,b,b,o,o,o,negative +x,x,b,o,x,x,o,o,o,negative +x,x,b,o,o,o,x,x,o,negative +x,x,b,o,o,o,x,o,x,negative +x,x,b,o,o,o,x,b,b,negative +x,x,b,o,o,o,o,x,x,negative +x,x,b,o,o,o,b,x,b,negative +x,x,b,o,o,o,b,b,x,negative +x,x,b,b,x,b,o,o,o,negative +x,x,b,b,b,x,o,o,o,negative +x,o,x,x,x,b,o,o,o,negative +x,o,x,x,o,x,o,o,b,negative +x,o,x,x,o,x,b,o,o,negative +x,o,x,x,o,o,b,o,x,negative +x,o,x,x,o,b,o,o,x,negative +x,o,x,x,o,b,b,o,b,negative +x,o,x,x,b,x,o,o,o,negative +x,o,x,o,o,x,x,o,b,negative +x,o,x,o,o,o,x,x,b,negative +x,o,x,o,o,o,x,b,x,negative +x,o,x,o,o,o,b,x,x,negative +x,o,x,o,o,b,x,o,x,negative +x,o,x,b,x,x,o,o,o,negative +x,o,x,b,o,x,x,o,o,negative +x,o,x,b,o,x,b,o,b,negative +x,o,x,b,o,o,x,o,x,negative +x,o,x,b,o,b,x,o,b,negative +x,o,x,b,o,b,b,o,x,negative +x,o,o,x,x,o,b,x,o,negative +x,o,o,x,o,x,o,x,b,negative +x,o,o,x,o,x,o,b,x,negative +x,o,o,x,o,x,b,o,x,negative +x,o,o,x,o,b,o,x,x,negative +x,o,o,b,x,o,x,x,o,negative +x,o,o,b,o,x,x,o,x,negative +x,o,o,b,o,x,o,x,x,negative +x,o,b,x,o,x,o,o,x,negative +x,o,b,x,o,x,b,o,b,negative +x,o,b,x,o,b,b,o,x,negative +x,o,b,o,o,x,x,o,x,negative +x,o,b,b,o,x,x,o,b,negative +x,o,b,b,o,x,b,o,x,negative +x,o,b,b,o,b,x,o,x,negative +x,b,x,x,x,o,o,o,o,negative +x,b,x,x,o,x,o,o,o,negative +x,b,x,x,b,b,o,o,o,negative +x,b,x,o,x,x,o,o,o,negative +x,b,x,o,o,o,x,x,o,negative +x,b,x,o,o,o,x,o,x,negative +x,b,x,o,o,o,x,b,b,negative +x,b,x,o,o,o,o,x,x,negative +x,b,x,o,o,o,b,x,b,negative +x,b,x,o,o,o,b,b,x,negative +x,b,x,b,x,b,o,o,o,negative +x,b,x,b,b,x,o,o,o,negative +x,b,o,x,x,o,o,x,o,negative +x,b,o,x,x,o,b,b,o,negative +x,b,o,x,o,x,o,x,o,negative +x,b,o,x,o,x,o,o,x,negative +x,b,o,x,o,x,o,b,b,negative +x,b,o,x,o,o,o,x,x,negative +x,b,o,x,o,b,o,x,b,negative +x,b,o,x,o,b,o,b,x,negative +x,b,o,x,b,o,b,x,o,negative +x,b,o,o,x,o,x,x,o,negative +x,b,o,o,o,x,o,x,x,negative +x,b,o,b,x,o,x,b,o,negative +x,b,o,b,x,o,b,x,o,negative +x,b,o,b,o,x,o,x,b,negative +x,b,o,b,o,x,o,b,x,negative +x,b,o,b,o,b,o,x,x,negative +x,b,o,b,b,o,x,x,o,negative +x,b,b,x,x,b,o,o,o,negative +x,b,b,x,b,x,o,o,o,negative +x,b,b,o,o,o,x,x,b,negative +x,b,b,o,o,o,x,b,x,negative +x,b,b,o,o,o,b,x,x,negative +x,b,b,b,x,x,o,o,o,negative +o,x,x,x,x,b,o,o,o,negative +o,x,x,x,o,x,o,b,o,negative +o,x,x,x,o,x,b,o,o,negative +o,x,x,x,o,o,x,b,o,negative +o,x,x,x,o,o,b,x,o,negative +o,x,x,x,o,b,x,o,o,negative +o,x,x,x,o,b,o,x,o,negative +o,x,x,x,o,b,b,b,o,negative +o,x,x,x,b,x,o,o,o,negative +o,x,x,o,x,x,o,o,b,negative +o,x,x,o,x,x,o,b,o,negative +o,x,x,o,x,o,o,b,x,negative +o,x,x,o,x,b,o,o,x,negative +o,x,x,o,x,b,o,b,b,negative +o,x,x,o,o,x,x,b,o,negative +o,x,x,o,o,x,o,x,b,negative +o,x,x,o,o,x,b,x,o,negative +o,x,x,o,o,o,x,x,b,negative +o,x,x,o,o,o,x,b,x,negative +o,x,x,o,o,o,b,x,x,negative +o,x,x,o,o,b,x,x,o,negative +o,x,x,o,o,b,o,x,x,negative +o,x,x,o,b,x,o,x,o,negative +o,x,x,o,b,x,o,b,b,negative +o,x,x,o,b,o,o,x,x,negative +o,x,x,o,b,b,o,x,b,negative +o,x,x,o,b,b,o,b,x,negative +o,x,x,b,x,x,o,o,o,negative +o,x,x,b,o,x,x,o,o,negative +o,x,x,b,o,x,o,x,o,negative +o,x,x,b,o,x,b,b,o,negative +o,x,x,b,o,o,x,x,o,negative +o,x,x,b,o,b,x,b,o,negative +o,x,x,b,o,b,b,x,o,negative +o,x,o,x,x,o,x,b,o,negative +o,x,o,x,o,x,x,b,o,negative +o,x,o,x,o,x,o,x,b,negative +o,x,o,x,o,x,o,b,x,negative +o,x,o,x,o,x,b,x,o,negative +o,x,o,x,o,b,x,x,o,negative +o,x,o,x,o,b,o,x,x,negative +o,x,o,x,b,o,x,x,o,negative +o,x,o,o,x,x,o,b,x,negative +o,x,o,o,b,x,o,x,x,negative +o,x,o,b,o,x,x,x,o,negative +o,x,o,b,o,x,o,x,x,negative +o,x,b,x,o,x,x,o,o,negative +o,x,b,x,o,x,o,x,o,negative +o,x,b,x,o,x,b,b,o,negative +o,x,b,x,o,o,x,x,o,negative +o,x,b,x,o,b,x,b,o,negative +o,x,b,x,o,b,b,x,o,negative +o,x,b,o,x,x,o,o,x,negative +o,x,b,o,x,x,o,b,b,negative +o,x,b,o,x,b,o,b,x,negative +o,x,b,o,o,x,x,x,o,negative +o,x,b,o,o,x,o,x,x,negative +o,x,b,o,b,x,o,x,b,negative +o,x,b,o,b,x,o,b,x,negative +o,x,b,o,b,b,o,x,x,negative +o,x,b,b,o,x,x,b,o,negative +o,x,b,b,o,x,b,x,o,negative +o,x,b,b,o,b,x,x,o,negative +o,o,x,x,o,x,x,o,b,negative +o,o,x,x,o,x,x,b,o,negative +o,o,x,x,o,x,b,x,o,negative +o,o,x,x,o,b,x,x,o,negative +o,o,x,x,o,b,x,o,x,negative +o,o,x,o,x,x,o,x,b,negative +o,o,x,o,x,b,o,x,x,negative +o,o,x,b,o,x,x,x,o,negative +o,o,o,x,x,o,x,x,b,negative +o,o,o,x,x,o,x,b,x,negative +o,o,o,x,x,o,b,x,x,negative +o,o,o,x,x,b,x,x,o,negative +o,o,o,x,x,b,x,o,x,negative +o,o,o,x,x,b,x,b,b,negative +o,o,o,x,x,b,o,x,x,negative +o,o,o,x,x,b,b,x,b,negative +o,o,o,x,x,b,b,b,x,negative +o,o,o,x,o,x,x,x,b,negative +o,o,o,x,o,x,x,b,x,negative +o,o,o,x,o,x,b,x,x,negative +o,o,o,x,b,x,x,x,o,negative +o,o,o,x,b,x,x,o,x,negative +o,o,o,x,b,x,x,b,b,negative +o,o,o,x,b,x,o,x,x,negative +o,o,o,x,b,x,b,x,b,negative +o,o,o,x,b,x,b,b,x,negative +o,o,o,x,b,b,x,x,b,negative +o,o,o,x,b,b,x,b,x,negative +o,o,o,x,b,b,b,x,x,negative +o,o,o,o,x,x,x,x,b,negative +o,o,o,o,x,x,x,b,x,negative +o,o,o,o,x,x,b,x,x,negative +o,o,o,b,x,x,x,x,o,negative +o,o,o,b,x,x,x,o,x,negative +o,o,o,b,x,x,x,b,b,negative +o,o,o,b,x,x,o,x,x,negative +o,o,o,b,x,x,b,x,b,negative +o,o,o,b,x,x,b,b,x,negative +o,o,o,b,x,b,x,x,b,negative +o,o,o,b,x,b,x,b,x,negative +o,o,o,b,x,b,b,x,x,negative +o,o,o,b,b,x,x,x,b,negative +o,o,o,b,b,x,x,b,x,negative +o,o,o,b,b,x,b,x,x,negative +o,o,b,x,o,x,x,x,o,negative +o,o,b,x,o,x,x,o,x,negative +o,o,b,o,x,x,o,x,x,negative +o,b,x,x,o,x,x,o,o,negative +o,b,x,x,o,x,o,x,o,negative +o,b,x,x,o,x,b,b,o,negative +o,b,x,x,o,o,x,x,o,negative +o,b,x,x,o,b,x,b,o,negative +o,b,x,x,o,b,b,x,o,negative +o,b,x,o,x,x,o,x,o,negative +o,b,x,o,x,x,o,b,b,negative +o,b,x,o,x,o,o,x,x,negative +o,b,x,o,x,b,o,x,b,negative +o,b,x,o,x,b,o,b,x,negative +o,b,x,o,o,x,x,x,o,negative +o,b,x,o,b,x,o,x,b,negative +o,b,x,o,b,b,o,x,x,negative +o,b,x,b,o,x,x,b,o,negative +o,b,x,b,o,x,b,x,o,negative +o,b,x,b,o,b,x,x,o,negative +o,b,o,x,x,o,x,x,o,negative +o,b,o,x,o,x,x,x,o,negative +o,b,o,x,o,x,o,x,x,negative +o,b,o,o,x,x,o,x,x,negative +o,b,b,x,o,x,x,b,o,negative +o,b,b,x,o,x,b,x,o,negative +o,b,b,x,o,b,x,x,o,negative +o,b,b,o,x,x,o,x,b,negative +o,b,b,o,x,x,o,b,x,negative +o,b,b,o,x,b,o,x,x,negative +o,b,b,o,b,x,o,x,x,negative +o,b,b,b,o,x,x,x,o,negative +b,x,x,x,x,o,o,o,o,negative +b,x,x,x,o,x,o,o,o,negative +b,x,x,x,b,b,o,o,o,negative +b,x,x,o,x,x,o,o,o,negative +b,x,x,o,o,o,x,x,o,negative +b,x,x,o,o,o,x,o,x,negative +b,x,x,o,o,o,x,b,b,negative +b,x,x,o,o,o,o,x,x,negative +b,x,x,o,o,o,b,x,b,negative +b,x,x,o,o,o,b,b,x,negative +b,x,x,b,x,b,o,o,o,negative +b,x,x,b,b,x,o,o,o,negative +b,x,o,x,x,o,x,o,o,negative +b,x,o,x,x,o,b,b,o,negative +b,x,o,x,o,x,o,x,o,negative +b,x,o,x,o,x,o,o,x,negative +b,x,o,x,o,x,o,b,b,negative +b,x,o,x,o,o,x,x,o,negative +b,x,o,x,o,o,o,x,x,negative +b,x,o,x,o,b,o,x,b,negative +b,x,o,x,o,b,o,b,x,negative +b,x,o,x,b,o,x,b,o,negative +b,x,o,x,b,o,b,x,o,negative +b,x,o,o,o,x,o,x,x,negative +b,x,o,b,x,o,x,b,o,negative +b,x,o,b,o,x,o,x,b,negative +b,x,o,b,o,x,o,b,x,negative +b,x,o,b,o,b,o,x,x,negative +b,x,o,b,b,o,x,x,o,negative +b,x,b,x,x,b,o,o,o,negative +b,x,b,x,b,x,o,o,o,negative +b,x,b,o,o,o,x,x,b,negative +b,x,b,o,o,o,x,b,x,negative +b,x,b,o,o,o,b,x,x,negative +b,x,b,b,x,x,o,o,o,negative +b,o,x,x,o,x,x,o,o,negative +b,o,x,x,o,x,b,o,b,negative +b,o,x,x,o,o,x,o,x,negative +b,o,x,x,o,b,x,o,b,negative +b,o,x,x,o,b,b,o,x,negative +b,o,x,b,o,x,x,o,b,negative +b,o,x,b,o,b,x,o,x,negative +b,o,o,x,x,o,x,x,o,negative +b,o,o,x,o,x,x,o,x,negative +b,o,o,x,o,x,o,x,x,negative +b,o,b,x,o,x,x,o,b,negative +b,o,b,x,o,x,b,o,x,negative +b,o,b,x,o,b,x,o,x,negative +b,o,b,b,o,x,x,o,x,negative +b,b,x,x,x,b,o,o,o,negative +b,b,x,x,b,x,o,o,o,negative +b,b,x,o,o,o,x,x,b,negative +b,b,x,o,o,o,x,b,x,negative +b,b,x,o,o,o,b,x,x,negative +b,b,x,b,x,x,o,o,o,negative +b,b,o,x,x,o,x,b,o,negative +b,b,o,x,x,o,b,x,o,negative +b,b,o,x,o,x,o,x,b,negative +b,b,o,x,o,x,o,b,x,negative +b,b,o,x,o,b,o,x,x,negative +b,b,o,x,b,o,x,x,o,negative +b,b,o,b,x,o,x,x,o,negative +b,b,o,b,o,x,o,x,x,negative +x,x,o,o,x,x,x,o,o,negative +x,x,o,o,o,x,x,x,o,negative +x,x,o,o,o,x,x,o,x,negative +x,o,x,x,x,o,o,x,o,negative +x,o,x,x,o,x,o,x,o,negative +x,o,x,x,o,o,o,x,x,negative +x,o,x,o,x,x,o,x,o,negative +x,o,x,o,o,x,x,x,o,negative +x,o,o,o,x,x,x,x,o,negative +o,x,x,x,x,o,o,o,x,negative +o,x,x,x,o,o,x,o,x,negative +o,x,x,x,o,o,o,x,x,negative +o,x,o,x,x,o,x,o,x,negative +o,x,o,x,o,x,x,o,x,negative +o,x,o,o,x,x,x,o,x,negative +o,o,x,x,x,o,o,x,x,negative diff --git a/datasets/zoo.csv b/datasets/zoo.csv new file mode 100644 index 0000000..ca71f7d --- /dev/null +++ b/datasets/zoo.csv @@ -0,0 +1,101 @@ +aardvark,1,0,0,1,0,0,1,1,1,1,0,0,4,0,0,1,1 +antelope,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +bass,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,4 +bear,1,0,0,1,0,0,1,1,1,1,0,0,4,0,0,1,1 +boar,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +buffalo,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +calf,1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,1 +carp,0,0,1,0,0,1,0,1,1,0,0,1,0,1,1,0,4 +catfish,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,4 +cavy,1,0,0,1,0,0,0,1,1,1,0,0,4,0,1,0,1 +cheetah,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +chicken,0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,2 +chub,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,4 +clam,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,7 +crab,0,0,1,0,0,1,1,0,0,0,0,0,4,0,0,0,7 +crayfish,0,0,1,0,0,1,1,0,0,0,0,0,6,0,0,0,7 +crow,0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,0,2 +deer,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +dogfish,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,4 +dolphin,0,0,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1 +dove,0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,2 +duck,0,1,1,0,1,1,0,0,1,1,0,0,2,1,0,0,2 +elephant,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +flamingo,0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,1,2 +flea,0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,6 +frog,0,0,1,0,0,1,1,1,1,1,0,0,4,0,0,0,5 +frog,0,0,1,0,0,1,1,1,1,1,1,0,4,0,0,0,5 +fruitbat,1,0,0,1,1,0,0,1,1,1,0,0,2,1,0,0,1 +giraffe,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +girl,1,0,0,1,0,0,1,1,1,1,0,0,2,0,1,1,1 +gnat,0,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,6 +goat,1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,1 +gorilla,1,0,0,1,0,0,0,1,1,1,0,0,2,0,0,1,1 +gull,0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,2 +haddock,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,4 +hamster,1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,0,1 +hare,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,0,1 +hawk,0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,0,2 +herring,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,4 +honeybee,1,0,1,0,1,0,0,0,0,1,1,0,6,0,1,0,6 +housefly,1,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,6 +kiwi,0,1,1,0,0,0,1,0,1,1,0,0,2,1,0,0,2 +ladybird,0,0,1,0,1,0,1,0,0,1,0,0,6,0,0,0,6 +lark,0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,2 +leopard,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +lion,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +lobster,0,0,1,0,0,1,1,0,0,0,0,0,6,0,0,0,7 +lynx,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +mink,1,0,0,1,0,1,1,1,1,1,0,0,4,1,0,1,1 +mole,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,0,1 +mongoose,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +moth,1,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,6 +newt,0,0,1,0,0,1,1,1,1,1,0,0,4,1,0,0,5 +octopus,0,0,1,0,0,1,1,0,0,0,0,0,8,0,0,1,7 +opossum,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,0,1 +oryx,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1 +ostrich,0,1,1,0,0,0,0,0,1,1,0,0,2,1,0,1,2 +parakeet,0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,2 +penguin,0,1,1,0,0,1,1,0,1,1,0,0,2,1,0,1,2 +pheasant,0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,2 +pike,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,4 +piranha,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,4 +pitviper,0,0,1,0,0,0,1,1,1,1,1,0,0,1,0,0,3 +platypus,1,0,1,1,0,1,1,0,1,1,0,0,4,1,0,1,1 +polecat,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +pony,1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,1 +porpoise,0,0,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1 +puma,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +pussycat,1,0,0,1,0,0,1,1,1,1,0,0,4,1,1,1,1 +raccoon,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +reindeer,1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,1 +rhea,0,1,1,0,0,0,1,0,1,1,0,0,2,1,0,1,2 +scorpion,0,0,0,0,0,0,1,0,0,1,1,0,8,1,0,0,7 +seahorse,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,4 +seal,1,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1,1 +sealion,1,0,0,1,0,1,1,1,1,1,0,1,2,1,0,1,1 +seasnake,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,0,3 +seawasp,0,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,7 +skimmer,0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,2 +skua,0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,2 +slowworm,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,3 +slug,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,7 +sole,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,4 +sparrow,0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,2 +squirrel,1,0,0,1,0,0,0,1,1,1,0,0,2,1,0,0,1 +starfish,0,0,1,0,0,1,1,0,0,0,0,0,5,0,0,0,7 +stingray,0,0,1,0,0,1,1,1,1,0,1,1,0,1,0,1,4 +swan,0,1,1,0,1,1,0,0,1,1,0,0,2,1,0,1,2 +termite,0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,6 +toad,0,0,1,0,0,1,0,1,1,1,0,0,4,0,0,0,5 +tortoise,0,0,1,0,0,0,0,0,1,1,0,0,4,1,0,1,3 +tuatara,0,0,1,0,0,0,1,1,1,1,0,0,4,1,0,0,3 +tuna,0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,4 +vampire,1,0,0,1,1,0,0,1,1,1,0,0,2,1,0,0,1 +vole,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,0,1 +vulture,0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,1,2 +wallaby,1,0,0,1,0,0,0,1,1,1,0,0,2,1,0,1,1 +wasp,1,0,1,0,1,0,0,0,0,1,1,0,6,0,0,0,6 +wolf,1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,1 +worm,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,7 +wren,0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,2 diff --git a/requirements.txt b/requirements.txt index 107f7ae..3ee208c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ -qiskit +qiskit==0.33.1 pandas tabulate +pylatexenc diff --git a/string_comparison.py b/string_comparison.py index d508590..17132ab 100644 --- a/string_comparison.py +++ b/string_comparison.py @@ -10,6 +10,7 @@ from qiskit.compiler import transpile from qiskit.extensions import * from qiskit.quantum_info.operators import Operator +from qiskit.visualization import plot_histogram from tabulate import tabulate logger = logging.getLogger(__name__) @@ -17,29 +18,49 @@ class StringComparator: - def __init__(self, target, db, symbol_length=1, is_binary=True, - shots=8192, quantum_instance=Aer.get_backend('qasm_simulator')): + def __init__(self, target, db, symbol_length=1, symbol_count=None, is_binary=True, + shots=8192, quantum_instance=Aer.get_backend('qasm_simulator'), + optimize_for=None, optimization_levels=None, attempts_per_optimization_level=None, + default_dataset=False, t=1, p_pqm=False + ): """ Compare a string against a set of strings. :param target: target string - :param db: a list of strings against which we compare the target string + :param db: a set of strings (passed in a list) against which we compare the target string :param symbol_length: the number of characters that codify a symbol; used only when is_binary == True + :param symbol_count: the number of characters in the alphabet; used only when is_binary == False. + the default value is None -- in this case the number of symbols is determined automatically based on the + number of distinct characters in the `db`. However, we may need to override this number for machine + learning tasks as a particular dataset may not have all the characters present in all the classes :param is_binary: are we dealing with binary strings? :param shots: the number of measurements to take :param quantum_instance: the pointer to the backend on which we want to execute the code + :param optimize_for: architecture for which the code should be optimized, e.g., `FakeMontreal()`. + If none -- no optimization will be performed. + :param optimization_levels: a list of optimization levels (QisKit transpiler takes values between 0 and 3) + :param attempts_per_optimization_level: a number of times transpiler will be executed to find optimal circuit + :param default_dataset: When True, this enables creation of a database containing all strings in equal superpositon. + When False, the database is initialized with strings passed in parameter `db`. + :param p_pqm: When True, this will run the storage and retrieval algorithms of parametric probabilistic quantum memory + When False, this will run the extended p-pqm storage and retrieval algorithms + :param t: parameter `t, a value within `(0, 1]` range is used by P-PQM algorithm to compute weighted Hamming distance, + which may improve performance of machine learning classification. + When `t=1` (the default value), P-PQM reduces to PQM. """ - + self.t = t self.quantum_instance = quantum_instance self.shots = shots self.is_binary = is_binary + self.default_dataset = default_dataset + self.p_pqm = p_pqm if is_binary: # check that strings contain only 0s and 1s self.symbol_length = symbol_length self.target_string, self.string_db = self._massage_binary_strings(target, db) else: self.target_string, self.string_db, self.symbol_length, self.symb_map = \ - self._massage_symbol_strings(target, db) + self._massage_symbol_strings(target, db, symbol_count) self.input_size = len(self.target_string) @@ -47,25 +68,97 @@ def __init__(self, target, db, symbol_length=1, is_binary=True, logger.debug(f"Database is {self.string_db}") # Create Circuit - self.u_register_len = 2 - self.u_register = QuantumRegister(self.u_register_len) - self.memory_register = QuantumRegister(self.input_size) - self.size_of_single_ham_register = math.floor(self.input_size / self.symbol_length) - self.single_ham_dist_register = QuantumRegister(self.size_of_single_ham_register) - self.qubits_range = self.size_of_single_ham_register + self.u_register_len + self.input_size - self.classic_register = ClassicalRegister(self.qubits_range - self.size_of_single_ham_register - 1) - self.circuit = QuantumCircuit(self.u_register, self.memory_register, self.single_ham_dist_register, - self.classic_register) - - # TODO: we can use the attribute directly and not pass it as a parameter in the next two function calls - self._store_information(self.string_db) - self._retrieve_information(self.target_string) - - self.circuit.measure(range(1, self.qubits_range - self.size_of_single_ham_register), - range(0, self.qubits_range - self.size_of_single_ham_register - 1)) + if p_pqm: + self.u_register_len = 2 + self.u_register = QuantumRegister(self.u_register_len) + self.memory_register = QuantumRegister(self.input_size) + self.pattern_register = QuantumRegister(self.input_size) + self.qubits_range = self.u_register_len + self.input_size + self.classic_register = ClassicalRegister(self.input_size + 1) + + self.circuit = QuantumCircuit(self.u_register, self.memory_register, self.pattern_register, + self.classic_register) + self._store_information_p_pqm(self.string_db) + self._retrieve_information_P_PQM(self.target_string) + + self.circuit.measure(range(1, self.qubits_range), range(0, self.input_size + 1)) + + else: + self.u_register_len = 2 + self.u_register = QuantumRegister(self.u_register_len) + self.memory_register = QuantumRegister(self.input_size) + self.size_of_single_ham_register = math.floor(self.input_size / self.symbol_length) + self.single_ham_dist_register = QuantumRegister(self.size_of_single_ham_register) + self.qubits_range = self.size_of_single_ham_register + self.u_register_len + self.input_size + self.classic_register = ClassicalRegister(self.qubits_range - self.size_of_single_ham_register - 1) + self.circuit = QuantumCircuit(self.u_register, self.memory_register, self.single_ham_dist_register, + self.classic_register) + + # TODO: we can use the attribute directly and not pass it as a parameter in the next two function calls + + if default_dataset: + self._store_default_database(len(self.string_db[0])) + if not default_dataset: + self._store_information(self.string_db) + + self._retrieve_information(self.target_string) + + self.circuit.measure(range(1, self.qubits_range - self.size_of_single_ham_register), + range(0, self.qubits_range - self.size_of_single_ham_register - 1)) + + if optimize_for is not None: + self._optimize_circuit(optimize_for, optimization_levels=optimization_levels, + attempts_per_optimization_level=attempts_per_optimization_level) self.results = None + def _optimize_circuit(self, backend_architecture, optimization_levels=range(0, 1), + attempts_per_optimization_level=1): + """ + Try to optimize circuit by minimizing it's depth. Currently, it does a naive grid search. + + :param backend_architecture: the architecture for which the code should be optimized + :param optimization_levels: a range of optimization levels + (the transpiler currently supports the values between 0 and 3) + :param attempts_per_optimization_level: the number of attempts per optimization level + :return: None + """ + cfg = backend_architecture.configuration() + + best_depth = math.inf + best_circuit = None + + depth_stats = [] + + for opt_level in optimization_levels: + for attempt in range(0, attempts_per_optimization_level): + optimized_circuit = transpile(self.circuit, coupling_map=cfg.coupling_map, basis_gates=cfg.basis_gates, + optimization_level=opt_level) #, layout_method='sabre', + # routing_method='sabre') + current_depth = optimized_circuit.depth() + depth_stats.append([opt_level, current_depth]) + if current_depth < best_depth: + best_circuit = optimized_circuit + best_depth = current_depth + self.circuit = best_circuit + + self.optimizer_stats = pd.DataFrame(depth_stats, columns=['optimization_level', 'circuit_depth']).\ + groupby('optimization_level').describe().unstack(1).reset_index().\ + pivot(index='optimization_level', values=0, columns='level_1') + logger.debug(f"Optimized depth is {self.circuit.depth()}") + logger.debug(f"Summary stats of transpiler attempts{tabulate(self.optimizer_stats, headers='keys')}") + + def get_optimizer_stats(self): + """ + Get optimizer stats + + :return: pandas data frame with the optimizer stats + """ + try: + return self.optimizer_stats + except AttributeError: + raise AttributeError("Optimizer was not invoked, no stats present") + def _massage_binary_strings(self, target, db): """ Massage binary strings and perform sanity checks @@ -104,12 +197,13 @@ def _massage_binary_strings(self, target, db): return target, db @staticmethod - def _massage_symbol_strings(target, db): + def _massage_symbol_strings(target, db, override_symbol_count=None): """ Massage binary strings and perform sanity checks :param target: target string :param db: database of strings + :param override_symbol_count: number of symbols in the alphabet, if None -- determined automatically :return: target string converted to binary format, database strings converted to binary format, length of symbol in binary format, @@ -143,9 +237,17 @@ def _massage_symbol_strings(target, db): symbols[symbol] = id_cnt id_cnt += 1 + # override symbol length if symbol count was specified by the user + dic_symbol_count = len(symbols) + if override_symbol_count is not None: + if dic_symbol_count > override_symbol_count: + raise ValueError(f"Alphabet has at least {dic_symbol_count}, " + f"but the user asked only for {override_symbol_count} symbols") + dic_symbol_count = override_symbol_count + # figure out how many bits a symbol needs - symbol_length = math.ceil(math.log2(len(symbols))) - logger.debug(f"We got {len(symbols)} distinct symbols requiring {symbol_length} bits per symbol") + symbol_length = math.ceil(math.log2(dic_symbol_count)) + logger.debug(f"We got {dic_symbol_count} distinct symbols requiring {symbol_length} bits per symbol") # convert ids for the symbols to binary strings bin_format = f"0{symbol_length}b" @@ -186,7 +288,7 @@ def run(self, quantum_instance=None): # tweak raw results and add those strings that have 0 shots/pulses associated with them # these are the strings that will have hamming distance equal to the total number of symbols for string in self.string_db: - full_binary_string = string[::-1] + "0" + full_binary_string = string[::-1] + "1" if full_binary_string not in results_raw: results_raw[full_binary_string] = 0 @@ -212,6 +314,38 @@ def run(self, quantum_instance=None): } return self.results + def get_circuit_depth(self): + """ + Get circuit depth + :return: circuit's depth + """ + return self.circuit.depth() + + def get_transpiled_circuit_depth(self): + """ + Get transpiled circuit depth + :return: circuit's depth + """ + return self.circuit.decompose().depth() + + def visualise_circuit(self, file_name): + """ + Visualise circuit + + :param file_name: The name of the file to save the circuit to + :return: None + """ + self.circuit.draw(output='mpl', filename=file_name) + + def visualise_transpiled_circuit(self, file_name): + """ + Visualise transpiled circuit + + :param file_name: The name of the file to save the circuit to + :return: None + """ + self.circuit.decompose().draw(output='mpl', filename=file_name) + def debug_print_raw_shots(self): """ Print raw pulse counts @@ -220,6 +354,14 @@ def debug_print_raw_shots(self): print("Raw results") print(self.results['raw_results']) + def debug_produce_histogram(self): + """ + Generate histogram of raw pulse counts + :return: None + """ + print("Histogram") + plot_histogram(self.results['raw_results']) + def debug_produce_summary_stats(self): """ Produce summary stats and print it @@ -275,7 +417,7 @@ def _get_count_of_useful_values(self, raw_results): if input_string in self.string_db: input_string_cnt = raw_results[registry_value] useful_shots_count += input_string_cnt - if suffix == '0': + if suffix == '1': p_val_dic[input_string] = input_string_cnt logging.debug(f"The useful number of shots is {useful_shots_count} out of {self.shots}") @@ -292,7 +434,6 @@ def _store_information(self, logs): log = logs[ind] self._copy_pattern_to_memory_register(log) - self._fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(log) self.circuit.mct(self.memory_register, self.u_register[0]) _x = len(logs) + 1 - (ind + 1) cs = Operator([ @@ -305,19 +446,75 @@ def _store_information(self, logs): # Reverse previous operations self.circuit.mct(self.memory_register, self.u_register[0]) - self._fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(log) self._copy_pattern_to_memory_register(log) - def _fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(self, my_string): - for j in range(self.input_size): - if my_string[j] == "1": + def _store_information_p_pqm(self, logs): + self.circuit.x(self.u_register[1]) + for i in range(len(logs)): + string = logs[i] + logging.debug(f"Processing {string}") + j = len(string) - 1 + while (j >= 0): + if (string[j] == '1'): + self.circuit.x(self.pattern_register[j]) + j -= 1 + + for j in range(self.input_size): + self.circuit.ccx(self.pattern_register[j], self.u_register[1], self.memory_register[j]) + + for j in range(self.input_size): + self.circuit.cx(self.pattern_register[j], self.memory_register[j]) self.circuit.x(self.memory_register[j]) - self.circuit.x(self.memory_register[j]) + + self.circuit.mct(self.memory_register, self.u_register[0]) + + x = len(logs) + 1 - (i + 1) + cs = Operator([ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, math.sqrt((x - 1) / x), 1 / (math.sqrt(x))], + [0, 0, -1 / (math.sqrt(x)), math.sqrt((x - 1) / x)] + ]) + + self.circuit.unitary(cs, [1, 0], label='cs') + + self.circuit.mct(self.memory_register, self.u_register[0]) + + for j in range(self.input_size): + self.circuit.cx(self.pattern_register[j], self.memory_register[j]) + self.circuit.x(self.memory_register[j]) + + for j in range(self.input_size): + self.circuit.ccx(self.pattern_register[j], self.u_register[1], self.memory_register[j]) + + j = len(string) - 1 + while (j >= 0): + if (string[j] == '1'): + self.circuit.x(self.pattern_register[j]) + j -= 1 + + def _store_default_database(self, length): + for j in range(length): + self.circuit.h(self.memory_register[j]) + for j in range(self.size_of_single_ham_register): + self.circuit.x(self.single_ham_dist_register[j]) + + def _fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(self, my_string): + if not self.p_pqm: + for j in range(self.input_size): + if my_string[j] == "0": + self.circuit.x(self.memory_register[j]) + else: + for j in range(self.input_size): + if my_string[j] == "1": + self.circuit.x(self.memory_register[j]) def _copy_pattern_to_memory_register(self, my_string): for j in range(len(my_string)): if my_string[j] == "1": self.circuit.cx(self.u_register[1], self.memory_register[j]) + else: + self.circuit.x(self.memory_register[j]) def _compare_input_and_pattern_for_single_ham_register(self): for j in range(self.size_of_single_ham_register): @@ -326,20 +523,19 @@ def _compare_input_and_pattern_for_single_ham_register(self): for ind in range(idx, idx + self.symbol_length): temp.append(ind + 2) self.circuit.mct(temp, self.single_ham_dist_register[j]) - self.circuit.x(self.single_ham_dist_register[j]) def _retrieve_information(self, input_string): self.circuit.h(1) self._fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(input_string) self._compare_input_and_pattern_for_single_ham_register() u_gate = Operator([ - [math.e ** (complex(0, 1) * math.pi / (2 * (self.input_size/self.symbol_length))), 0], + [math.e ** (complex(0, 1) * math.pi / (2 * ((self.input_size/self.symbol_length) * self.t))), 0], [0, 1] ]) for ind in range(self.size_of_single_ham_register): self.circuit.unitary(u_gate, self.single_ham_dist_register[ind], label='U') u_minus_2_gate = Operator([ - [1 / math.e ** (complex(0, 1) * math.pi / (self.input_size/self.symbol_length)), 0], + [1 / math.e ** (complex(0, 1) * math.pi / ((self.input_size/self.symbol_length) * self.t)), 0], [0, 1] ]) gate2x2 = UnitaryGate(u_minus_2_gate) @@ -353,6 +549,31 @@ def _retrieve_information(self, input_string): self.circuit.h(1) + def _retrieve_information_P_PQM(self, input_string): + self.circuit.h(1) + self._fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(input_string) + + u_gate = Operator([ + [math.e ** (complex(0, 1) * math.pi / (2 * ((self.input_size / self.symbol_length) * self.t))), 0], + [0, 1] + ]) + for ind in range(self.input_size): + self.circuit.unitary(u_gate, self.memory_register[ind], label='U') + u_minus_2_gate = Operator([ + [1 / math.e ** (complex(0, 1) * math.pi / ((self.input_size / self.symbol_length) * self.t)), 0], + [0, 1] + ]) + gate2x2 = UnitaryGate(u_minus_2_gate) + gate2x2_ctrl = add_control(gate2x2, 1, 'CU2x2', '1') + for j in range(self.input_size): + self.circuit.append(gate2x2_ctrl, [1, self.memory_register[j]]) + + # Reverse previous operations + self._fill_ones_in_memory_register_which_are_equal_to_bits_in_pattern(input_string) + + self.circuit.h(1) + + @staticmethod def hamming_distance(str_one, str_two, symbol_length=1): """ @@ -452,7 +673,7 @@ def _convert_p_value_to_hamming_distance(self, p_values, prob_of_c): temp = 2 * prob_of_c * len(p_values) * p_value - 1 if temp > 1: temp = 1.0 - ham_distances.append(int(round((self.input_size/(self.symbol_length * math.pi)) * (math.acos(temp))))) + ham_distances.append(int(round(((self.input_size/(self.symbol_length * math.pi)) * self.t) * (math.acos(temp))))) return ham_distances @@ -472,8 +693,12 @@ def _convert_p_value_to_hamming_distance(self, p_values, prob_of_c): # Extra debug info x.debug_print_raw_shots() x.debug_produce_summary_stats() + print(f"Circuit's depth is {x.get_circuit_depth()}") + print(f"Transpiled circuit's depth is {x.get_transpiled_circuit_depth()}") + x.visualise_circuit("example1_circuit.pdf") + x.visualise_transpiled_circuit("example1_transpiled_circuit.pdf") - # Example 2 + # Example 2 print("\nExample 2") # Normal execution dataset = ['01001', '11010', '01110', '10110'] @@ -485,3 +710,82 @@ def _convert_p_value_to_hamming_distance(self, p_values, prob_of_c): # Extra debug info x.debug_print_raw_shots() x.debug_produce_summary_stats() + print(f"Circuit's depth is {x.get_circuit_depth()}") + print(f"Transpiled circuit's depth is {x.get_transpiled_circuit_depth()}") + x.visualise_circuit("example2_circuit.pdf") + x.visualise_transpiled_circuit("example2_transpiled_circuit.pdf") + + # Example 3 + print("\nExample 3") + # Normal execution + dataset = [['foo', 'bar', 'foo'], + ['foo', 'bar', 'quux'], + ['foo', 'quux', 'foo'], + ['quux', 'bar', 'foo'], + ['quux', 'baz', 'foo'], + ['quux', 'baz', 'qux'] + ] + target = ['foo', 'bar', 'foo'] + x = StringComparator(target, dataset, is_binary=False, shots=100000) + # Note that we need to increase shots from 10K to 100K-- otherwise some times ranking gets broken + results = x.run() + print(f"probability of measuring register c as 0 is {results['prob_of_measuring_register_c_as_0']}") + print(f"p-values are {results['p_values']}") + print(f"hamming distances are {results['hamming_distances']}") + # Extra debug info + x.debug_print_raw_shots() + x.debug_produce_summary_stats() + print(f"Circuit's depth is {x.get_circuit_depth()}") + print(f"Transpiled circuit's depth is {x.get_transpiled_circuit_depth()}") + x.visualise_circuit("example3_circuit.pdf") + x.visualise_transpiled_circuit("example3_transpiled_circuit.pdf") + + # Example 4 + # Now let's swap + print("\nExample 4 -- this one is identical to Example 3, just in the binary form") + # Normal execution + dataset = ['000001000', '000001010', '000010000', '010001000', '010011000', '010011100'] + x = StringComparator('000001000', dataset, + symbol_length=3, shots=100000) + results = x.run() + print(f"probability of measuring register c as 0 is {results['prob_of_measuring_register_c_as_0']}") + print(f"p-values are {results['p_values']}") + print(f"hamming distances are {results['hamming_distances']}") + # Extra debug info + x.debug_print_raw_shots() + x.debug_produce_summary_stats() + print(f"Circuit's depth is {x.get_circuit_depth()}") + print(f"Transpiled circuit's depth is {x.get_transpiled_circuit_depth()}") + x.visualise_circuit("example4_circuit.pdf") + x.visualise_transpiled_circuit("example4_transpiled_circuit.pdf") + + # Example 5 + print("\nExample 5 -- for the paper") + # Normal execution + dataset = [['foo', 'bar', 'foo'], ['foo', 'bar', 'bar'], ['foo', 'quux', 'bar'], ['bar', 'foo', 'foo']] + target = ['foo', 'quux', 'foo'] + x = StringComparator(target, dataset, is_binary=False, shots=10000) + results = x.run() + print(f"probability of measuring register c as 0 is {results['prob_of_measuring_register_c_as_0']}") + print(f"p-values are {results['p_values']}") + print(f"hamming distances are {results['hamming_distances']}") + # Extra debug info + x.debug_print_raw_shots() + x.debug_produce_summary_stats() + print(f"Circuit's depth is {x.get_circuit_depth()}") + print(f"Transpiled circuit's depth is {x.get_transpiled_circuit_depth()}") + x.visualise_circuit("example5_circuit.pdf") + x.visualise_transpiled_circuit("example5_transpiled_circuit.pdf") + + # Example 6 + print("Example 6: test optimizer") + # Normal execution + dataset = ['1001', '1000'] + from qiskit.test.mock import FakeMontreal + x = StringComparator('1001', dataset, symbol_length=2, shots=8192, optimize_for=FakeMontreal()) + # Extra debug info + print(f"Optimized circuit's depth is {x.get_circuit_depth()}") + print(f"Summary stats of transpiler's attempts\n{tabulate(x.get_optimizer_stats(), headers='keys')}") + results = x.run(quantum_instance=FakeMontreal()) + x.debug_produce_summary_stats() + print(f"Raw results: {results}") diff --git a/test_string_comparison.py b/test_string_comparison.py index 3fcc893..425bae9 100644 --- a/test_string_comparison.py +++ b/test_string_comparison.py @@ -4,6 +4,13 @@ class StringComparatorTestCase(unittest.TestCase): + def test_one_char_symbol_p_pqm(self): + dataset = ['01001', '11010', '01110', '10110'] + x = StringComparator('10110', dataset, p_pqm=True, shots=20000) + actual_hd = x.run()['hamming_distances'] + expected_hd = [5, 2, 2, 0] + self.assertEqual(expected_hd, actual_hd, 'incorrect hamming distance') + def test_one_char_symbol(self): dataset = ['01001', '11010', '01110', '10110'] x = StringComparator('10110', dataset, symbol_length=1) @@ -54,5 +61,25 @@ def test_all_different_two_char_symbol(self): expected_hd = [2, 2, 2, 2, 2, 2] self.assertEqual(expected_hd, actual_hd, 'incorrect hamming distance') + def test_default_database(self): + dataset = ['000', '010', '100', '111', '001', '101', '110', '011'] + x = StringComparator('100', dataset, symbol_length=1, default_dataset=True) + actual_hd = x.run()['hamming_distances'] + expected_hd = [1, 2, 0, 2, 2, 1, 1, 3] + self.assertEqual(expected_hd, actual_hd, 'incorrect hamming distance') + + def test_dictionary_override(self): + dataset = [['a', 'b'], ['a', 'c']] + x = StringComparator(['a', 'b'], dataset, is_binary=False) + self.assertEqual(x.symbol_length, 2, 'incorrect symbol length') + self.assertEqual(len(x.target_string), 4, 'incorrect target string length') + self.assertEqual(len(x.string_db[0]), 4, 'incorrect db string length') + + x = StringComparator(['a', 'b'], dataset, is_binary=False, symbol_count=5) + self.assertEqual(x.symbol_length, 3, 'incorrect symbol length') + self.assertEqual(len(x.target_string), 6, 'incorrect target string length') + self.assertEqual(len(x.string_db[0]), 6, 'incorrect db string length') + + if __name__ == '__main__': unittest.main()