diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d62621e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,215 @@
+### Python template
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# Entire idea folder
+.idea/*
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
diff --git a/team 8/Business_Application.md b/team 8/Business_Application.md
new file mode 100644
index 0000000..d8f4a96
--- /dev/null
+++ b/team 8/Business_Application.md
@@ -0,0 +1,67 @@
+# Space Debris Removal Optimization
+
+### What is Space Debris?
+Space debris (also known as space junk, space pollution, space waste, space trash, or space garbage) refers to objects that were created by humans but are no longer functional in space.
+The debris includes rocket thrusters, abandoned satellites, and most importantly, fragments from collisions and explosions. It is estimated that 95% of all manmade satellites in low Earth orbit (LEO) are space junk.
+
+
+
+### Why Space Debris is a Problem?
+There were approximately 128 million pieces of debris under 1 cm (0.4 in), about 900,000 pieces between 1 and 10 cm, and approximately 34,000 pieces larger than 10 cm (3.9 in) in orbit around the Earth as of January 2019.
+
+Space debris orbits around the earth at tremendous speeds - about 15,700 miles per hour (25,265 kph) in low Earth orbit which is 10 times the speed of a bullet. So there is a possibility that active satellites and spacecraft could be damaged by space debris. Space travel is also at risk due to all this debris.
+
+A large amount of space debris in orbit could hinder satellite activities for many generations to come.
+
+**Kessler syndrome** (also called Kessler effect) was proposed by NASA scientist Donald J. Kessler in 1978 as a scenario where collisions between objects in low Earth orbit (LEO) may result in a cascade creating space debris and increasing collision likelihood. According to Kessler, modeling results concluded in 2009 that the debris environment was already unstable, "such that attempts to eliminate past debris sources will likely fail since fragments from future collisions will be generated faster than atmospheric drag can remove them."
+
+### Recent Events
+* **Space junk slams into International Space Station, leaving hole in robotic arm:** Space junk hurtling towards the station smashed into one of its robotic arms, leaving a hole.
+NASA and the Canadian Space Agency first noticed the damage on Canadarm2 on May 12, according to a recent statement. The debris left a gaping hole in a section of the arm boom and thermal blanket.
+* **International Space Station swerves to dodge space junk:** The ISS had been forced to move due to space junk from a U.S. launch vehicle sent into orbit in 1994.
+ A close encounter was avoided by dropping by 310 metres (339 yards) as part of an unscheduled maneuver carried out by mission control.
+
+
+### Space Debris Removal Optimization
+In space debris removal optimization, the goal is to create an optimal path for satellite vessels to collect as much debris as possible in one pass, while saving fuel. As a result, space debris collection will take fewer days overall.
+
+A space debris removal optimization could also be described as combinatorial optimization problem, which is searching for maxima (or minima) of an objective function F whose domain is a discrete but large configuration space (in contrast to an N-dimensional continuous space).
+
+
+
+This can be also considered as a Knapsack problem where the goal is to determine the number of items each with a weight and value to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. According to its name, it refers to the problem of filling a fixed-size knapsack with valuable items when constrained by a fixed size. A similar problem occurs when decision-makers have to select from a set of non-divisible projects or tasks within a fixed budget or timeframe.
+
+
+
+To optimize the path and take into account the resources required to travel, we add complexity to the problem. The new term is related to the Traveling Salesman Problem (TSP) whose goal is to optimize a path on a graph, such that all nodes are visited and each road is taken only once. In our case, we want to maximize the amount of nodes visited, representing the debris that are collected, while minimizing the length of the path, indicated by weights on the edges of the graph.
+
+The two problems that represent the situation of debris collection are known to be computationally hard to solve on classical computers: for large amounts of debris, it may take more that the age of the universe to solve.
+
+### Potential Customers
+* Space agencies, like NASA, ESA, etc, are potential customers because space debris can hinder their missions.
+* Governments around the world are also our potential customers since space debris can interfere with satellite operations as this is a matter of national security. In addition, it is related to the sustainability of space.
+* Space companies such as SpaceX and OneWeb, which plan to deploy 40,000+ satellites in the near future, will also be interested in our product since they wish to avoid collisions with space debris.
+* We believe that startups such as CleanSpace, Astroscale, and others who are interested in space debris removal will be interested in our product since they want to collect more space debris with less cost and mission time.
+For e.g: Fujitsu worked with Glasgow University and Astroscale to demonstrate quantum advantage in space debris removal. The team designed an optimal mission in just 0.083 seconds using quantum inspired algorithms that reduced fuel costs by 25% and overall mission days by 23%. In addition, they were awarded £1 million in grants from the UK government.
+
+### Architecture
+
+We gather open source space debris data and encode it for quantum computers. Our first model leverages gate-based quantum computing using the QAOA algorithm. It is platform agnostic and can be run either on IBM hardware or Xanadu hardware. In the near future, it will be also possible to run our model on quantum annealers such as D-Wave hardware.
+
+As a pre-processing step, we also use AI to clean and rank debris according to size, collection cost, etc. This process reduces the size of the problem to solve according to the collection priorities and makes the program more efficient to run.
+
+### Business Model
+**Yearly Subscription:** We offer both on-premises and cloud deployment options for our model on a yearly subscription basis.
+
+Our solution is scalable and can be used by several space companies or agencies with no or minimal changes. Our model returns the optimal path for satellite vessels to collect as much debris as possible in one pass.
+
+
+
+### References:
+* https://en.wikipedia.org/wiki/Space_debris
+* https://www.youtube.com/watch?v=Ctvzf_p0qUA
+* https://www.cbsnews.com/news/space-junk-damage-international-space-station
+* https://www.reuters.com/lifestyle/science/international-space-station-swerves-dodge-space-junk-2021-12-03
+* https://en.wikipedia.org/wiki/Knapsack_problem
+* E. Farhi, J. Goldstone, and S. Gutmann, “A quantum approximate optimization algorithm.”, arXiv 1411.4028, 2014
+
diff --git a/team 8/Debris_Removal_Model_Qiskit.ipynb b/team 8/Debris_Removal_Model_Qiskit.ipynb
new file mode 100644
index 0000000..456aae3
--- /dev/null
+++ b/team 8/Debris_Removal_Model_Qiskit.ipynb
@@ -0,0 +1,779 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import networkx as nx # tool to handle general Graphs \n",
+ "import matplotlib.pyplot as plt \n",
+ "from matplotlib import cm\n",
+ "from matplotlib.ticker import LinearLocator, FormatStrFormatter\n",
+ "from typing import Any, Dict, List, Tuple\n",
+ "from qiskit import Aer, IBMQ\n",
+ "from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, transpile, assemble\n",
+ "from qiskit.providers.ibmq import least_busy\n",
+ "from qiskit.tools.monitor import job_monitor\n",
+ "from qiskit.visualization import plot_histogram"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Firstly, we define a class we can draw a graph in convinient way\n",
+ "class GraphModel:\n",
+ " \n",
+ " n_nodes: int\n",
+ " edges: List[Tuple[int, int]]\n",
+ " graph: nx.Graph\n",
+ " \n",
+ " def __init__(self, n_nodes, edges, weights, distancies, qaoa_solve=None):\n",
+ " \n",
+ " self.n_nodes = n_nodes\n",
+ " self.edges = edges\n",
+ " self.weights = weights\n",
+ " self.distancies = distancies\n",
+ " self.graph = nx.Graph()\n",
+ " self.graph.add_nodes_from(np.arange(0,n_nodes,1))\n",
+ " self.graph.add_edges_from(edges)\n",
+ " #self.qaoa_solve = qaoa_solve\n",
+ " \n",
+ " def draw_raw_graph(self):\n",
+ " \n",
+ " # Generate plot of the Graph\n",
+ " colors = ['cornflowerblue' for node in self.graph.nodes()]\n",
+ " default_axes = plt.axes(frameon=False)\n",
+ " random_pos = nx.random_layout(self.graph, seed=42)\n",
+ " pos = nx.spring_layout(self.graph, pos=random_pos)\n",
+ "\n",
+ " nx.draw_networkx_nodes(self.graph, node_color=colors, node_size=900,pos = pos, \n",
+ " alpha=1, ax=default_axes) \n",
+ " nx.draw_networkx_edges(self.graph, pos = pos, width=8,alpha=1,ax=default_axes,\n",
+ " edge_color=\"tab:gray\")\n",
+ " nx.draw_networkx_labels(self.graph, pos = pos, font_size=22, font_color=\"white\")\n",
+ "\n",
+ "\n",
+ " def draw_done_graph(self,bitstring):\n",
+ " \n",
+ " # Draw a graph in accordance with its bitstring\n",
+ " color_map = []\n",
+ " edgelist_different = []\n",
+ " edgelist_same = []\n",
+ " default_axes = plt.axes(frameon=False)\n",
+ " default_axes.axis('off')\n",
+ " random_pos = nx.random_layout(self.graph, seed=42)\n",
+ " pos = nx.spring_layout(self.graph, pos=random_pos)\n",
+ " \n",
+ " if bitstring == None:\n",
+ " self.draw_raw_graph()\n",
+ " else:\n",
+ " for i in bitstring:\n",
+ " if i > 0:\n",
+ " color_map.append('red')\n",
+ " else: \n",
+ " color_map.append('cornflowerblue')\n",
+ "# for edge in self.edges:\n",
+ "# if bitstring[edge[0]] != bitstring[edge[1]]:\n",
+ "# edgelist_different.append(edge)\n",
+ "# else:\n",
+ "# edgelist_same.append(edge)\n",
+ " \n",
+ " nx.draw_networkx_nodes(self.graph, node_color=color_map, node_size=900,pos = pos, \n",
+ " alpha=1, ax=default_axes) \n",
+ " nx.draw_networkx_edges(self.graph, pos = pos, edgelist = self.edges, \n",
+ " width=8,alpha=1,ax=default_axes,edge_color=\"tab:grey\")\n",
+ "# nx.draw_networkx_edges(self.graph, pos = pos, edgelist = edgelist_different,\n",
+ "# width=8,alpha=1,ax=default_axes, edge_color=\"tab:red\")\n",
+ " nx.draw_networkx_labels(self.graph, pos = pos, font_size=22, font_color=\"white\")\n",
+ " \n",
+ " def connections(self, node): \n",
+ " connection_list = []\n",
+ " for edge in self.edges:\n",
+ " if (edge[0] == node):\n",
+ " connection_list.append(edge[1])\n",
+ " elif (edge[1] == node):\n",
+ " connection_list.append(edge[0])\n",
+ " connection_list = list(dict.fromkeys(connection_list))\n",
+ " return connection_list\n",
+ " \n",
+ " # This function returns all edges corresponding to certain node of the graph G \n",
+ " def find_edges(self, node): \n",
+ " connection_edges = []\n",
+ " for edge in self.edges:\n",
+ " if (edge[0] == node):\n",
+ " connection_edges.append(edge)\n",
+ " elif (edge[1] == node):\n",
+ " connection_edges.append(edge)\n",
+ " connection_edges = list(dict.fromkeys(connection_edges)) \n",
+ " return connection_edges"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def graph_drawing(G,regime, *args, **kwargs):\n",
+ " bitstring = kwargs.get('bitstring', None)\n",
+ " filename = kwargs.get('filename', None)\n",
+ " figure, axes = plt.subplots(frameon=False)\n",
+ " axes.axis('off')\n",
+ " # Turn off tick labels\n",
+ " req_dpi = 100 \n",
+ " figure.set_size_inches(500 / float(req_dpi), \n",
+ " 500 / float(req_dpi)) \n",
+ " if regime == 'raw':\n",
+ " G.draw_raw_graph()\n",
+ " elif regime == 'done':\n",
+ " G.draw_done_graph(bitstring)\n",
+ " else:\n",
+ " raise ValueError('Regime is wrong')\n",
+ " \n",
+ " figure.savefig(filename, format='png',\n",
+ " transparent=True, dpi=req_dpi) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 197,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAASUAAAEeCAYAAADM2gMZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABKFklEQVR4nO2deXxkRdWGn84ymR0m7MPWsss6LAKirIKgsoqKooAKUYzKJsoHIr4ogiAgiwYlKIKgIi4ggoCsKiACMoDsW2DYGTL7ZCZbf3+cGyYzSW5V973dfTtTz++Xz4+punUr6dvnVp065z25QqFAIBAIZIW6ak8gEAgEBhOMUiAQyBTBKAUCgUwRjFIgEMgUwSgFAoFMEYxSIBDIFMEoBQKBTBGMUiAQyBTBKAUCgUwRjFIgEMgUwSgFAoFMEYxSIBDIFMEoBQKBTBGMUiAQyBQN1Z5AoLK0tHVOAT4CvB/YGVgLaAT6gLeB+4B7gFvbW5tfqtY8A8svuaCntHzQ0ta5DXAicBDQA0wEciN0XwDUYwbqHOCW9tbm8KAEKkIwSqOclrbOScCFwCFAE2ZsimE+8DDw2fbW5hkpTy8QGEIwSqOYlrbOHYHrgUnAuARD9QKLgS+1tzb/Jo25BQIjERzdo5SWts49gduBVUlmkMB8jxOA9pa2zmOTzi0QiCOslEYh0QrpdmB8GYZfCHy9vbX5l2UYOxAIRmm00dLWORF4DljN1Xf7Dcew22ZNrLlSPXV1Od6Y1cc9Ty3m7v8txvFUdAFbt7c2P53KpAOBQYTt2+jjAmCyq9OhO4+nZa+JrLtqA8+93suTM3pYbcV6PrvLBI7eZyK5kc7ljCbg9y1tncU6zQMBJyFOaRTR0tY5DfgMDh/SNus1svsWY5m9oJ8fXTeXt+b0AzBpXI4TD5jMNuuNYY8tmrj90cUjDVEHrA8cAYRtXCBVwkppdPENbBUTy0e2MZv1p38vfNcgAczrKnD1PxYAsM/W40YMYoqYAJzc0tbp6BYIFEcwSqOElrbOFYFP4IhDmjIhR37VBnr6Cjz4XPeQ9mde62XW/H5WnFDHeqs7F9JrADuUOOVAYFiCURo97INFasey9spmaF7r7KOnb/g+HW/1Rn2dLqNxWFBmIJAawSiNHnbEUkdiWXmyfeSd8/pH7PPO/P6l+sZQh+XPBQKpEYzS6GFnRs5le5exjdZlce/Ih/6LewpL9XWwafArBdIkGKXRw9pevSLzkWJ4Wj2wYmqjBZZ7glEaPTT6dFrU7V4FNUVti3q8LFcfHid+gYAvwSiNHnp9Or0T+ZKaJ4380TdPtLZ35o7sdxpEHTD0GC8QKJFglEYPb/t0enmmHblNba6ncYTDtfyq9Uv1jaVQqAPmes0wEPAgGKXRwz0+nWbN7+elt3pprM+x3QZjhrRvNLWB5on1zF7QzwtvuBdfDX2dDWu+ddHPJG1a/JQDgaEEozR6uBcTZHNy03+7APj4juNZZdCx/6RxOT67iwkL3PxwlyspF4AxPa/ngCOBxyX9VdJuksJpXKBkgkrAKKGlrXNNTB1grE//Q3cZz+6bj6W7t8CTr/TQ1w+brNnA+KY6Hn6hm0tume88ocv1d9M892bGdncs2/QQcC7wB0levq5AYIBglEYRLW2dtwB74RGvBCZdsvvmTay5UgN1OXhjVh//8pMuAaCufyGrz/wFuZF7vwz8GPiFpHlev0RguScYpVFEpDZ5HZYsW14KPUxa8B8mL3zIp/cc4OfARZJeLe/EArVOMEqjiJa2zlx97+xn++onrU+uvFJHdX3zWe2dK6nzi0QYoBf4DXCepEfLM7NArROM0ihC0tf66iZc/GbzYRTqhp6spUWu0MNKs6+nqee1JMPcivmdbpMUHsLAuwSjNEqQ9AUiwbWFTRswa/JekPMK8i6OQqFrTM/rd64y+w9rAVumMOKjmHG6RlIIwgwEozQakHQIti1693x//tjNmTtpZwopGqZcfw9jel59YXFTfoM137oIYE+swOWHUxj+Vaw+3aWS5qQwXqBGCUapxpG0H/AnhpE2XtC0MXMm70GBesglC0nLFXqYsPBRJi+4hxzsJunuQXPYElO9/AyeOXgxzAfagQslhbLhyyHBKNUwkj4E3EhMQmxv/Qp0Tt6HnobmfnKNxVumQg91/Ytpnvs3mnpeH/jXR4Ftl41BkrQm8HXgaGCFou+1NH3A74FzJf034ViBGiIYpRpF0gcwZ7GztluB3PQ3VvrCJf11Y0/KUVjPuXIqFMgVesgVepi48GEmdD063Cnb1yT9dIS5TcKivI8H1vH8leK4E/M73SzJK0s4ULsEo1SDSNoG+6I6SykBTwK7Snpb0oHdDav8uatpIxaPmUpv/UoUcvVAgSjeskCu/n8NvZ0vrTD/n/s2db8UF4U5C9hI0syYeTZguuHfBLbx/f1ieAI4D7ha0oilVgK1TTBKNYakzYC7gZU8ur8A7Czpteja47AIa8BMUSHXSIF6cvSTK/ReebpOOyLqex1wgGP8n0s62mPOOWBXzCn+MY95u3gTuBj4maR3UhgvkCFCQm4NIWkD4Db8DNIrwIcGDFLEewZ3yAF1hR7qC4uoK3STo//FQc0nAK7VyJckbe0x74KkuyTtC2wKXEYyDabVgDOAlyVdLGm9BGMFMkYwSjWCpHWA24HVPbq/hRmkjmX+Pe+47t3+kl4AfuTonwMuLkYVQNKTklqAdTHD0ul77TCMB74GPCvpWkmh3NMoIBilGkDSGphB8nEazwL2kvTMMG15x7UvLvPfZwEzHNd8ADjUY15LIekNSd/BfqevYVvNUqnDfFf/lvRPSQdICs92jRJ8ShlH0kqYD2kzj+7zsBXSA8OMkwNmE+8czy8bGyTpU8A1jvu+DmycRAlAUj1wIOZ32rHUcQbxLHA+cIWkrhTGC1SI8DbJMJJWAG7BzyB1AfsOZ5AiphBvkPqwqOpluRa4y3HvNYBvuyYYh6Q+SX+U9H5s9fVn8FJQGYkNgUswv5MkrZJkfoHKEVZKGUXSBOBm4IMe3buB/SXdEjPeNpj42kh0SHrPcA2StgAeJr4keA+w+QjbxpKQtCEW6/QFPMXrYlgEXAGcn+YcA+kTVkoZRNJYbKXgY5D6gEPiDFJE3tG+rD9p8HweA9oc1zcyKNwgDSQ9K6kV8zt9F8/iCCMwFvgy8JSk6yR9sBgHfaByBKOUMSQ1Yj6cvTy6F4DDo5giF8OuggbR4Wj/LjBioGTER6Nj/1SJAj+/h53YfRlIstLJYfFX/wTuk/SJyJ8VyAjBKGWI6MtxJbC/5yVfkvQbz755R3tHXKOkWcApHve5QFJZilNK6pJ0KfBe7G/0j4RD7oD5zJ6V9HVJE5POMZCcYJQyQnSEfSnwac9Ljpd0WRG3yDvaR9y+DeKXgCs5dn0s8LJsSOqXdIOkXTHD8nsgSU7ce4CLMKf4D6IQjECVCEYpA0S+jR8DX/S85DuSLijyNnlHe4drAEl9mAqAi1MlreXRLzGS/iPTk9oAMywLEgw3BVsNdkj6hSylJ1BhglHKBmcAx3j2PRv4QTGDR0YvqU9pYKx7gV87uo0HzvEZLy0kvSjpWMwpfgrwRoLhxmAviP9JulHS7sEpXjmCUaoykk7Gz1cD8FPgZBWvab0S8RVOeoBiBLdPwl348jOSdi5izFSQ1CnpLGxl+EVMWSAJHwXuAB6UdGh0EBEoIyFOqYpI+jq25fDhV8CRKkFPSNJ2wEhBlQDPy5J9ixnzm7hXQ49gYnB9xYydJtEKZ28sUvxDKQw5A7gAuEzS3BTGCyxDWClVCUlfxN8g/R44qhSDFJF3tHeUMOaFuI/mtwK+VMLYqSFTKLhZ0p6YptPVWGxXqayNaTrNkHROpXxnyxPBKFUBSZ/G5Dt8+CtwWMLVRir+pMHIKo8c69H1DFn+XtWR9LCkzwHrYYYlSdXeyZh43YuSrpS0VRpzDASjVHEk7Y85in0cp3cAn1Ty0kN5R3tHKYNKuhn4i6NbM/D9UsYvF5JelnQitur5JsPn/PnSABwGTJd0q6QPB6d4MoJRqiDRFuJahqk8Mgz3AQdIWpTCrfOOdp8YpZHwEYP7sqRpCe5RFiTNkXQutpL8HOYDS8JeWAL1I5KOkFS+iqCjmGCUKoSkDwLXY8fNLh7GUjZcJ1y+5B3tHaUOLOl5TNQ/jjqKFIOrJJJ6JF0NbI3Vsrs54ZBbYAcTL0o6SdKKCcdbrginbxVA0rbYVsxH6P8JTOjflWfme+8cdnwfV/VkLUklb2FkigZPAS6n72eLSIupKjJlhBOAz5JOLbvLsFp2HQnHGvUEo1RmJG2OibQ1e3R/HthFS+tqJ73/qpjQ/kh0A+MSnOwN3OcQ4HeObq9hYnBprQDLjqSpLKllt2LC4fqw7ft5kh5MONaoJWzfyohMD+jv+BmkGQwV+k+DvKP9paQGKeL3mPGNYyoJxeAqjaTXogDXdYDjgCRVe+ux3MYHJN0paV8F2d4hhD9ImZC0Lv5C/28Ce6o8ZapTDwcYjijK/BjcibEnRMa6ppA0T9KFWI7dIUDSlc5uwA3A45KOkmloBQhGqSzIssxvw46cXXQystB/GuQd7R1p3UjSo5gEbRxjSFkMrpJI6pX0e2B7rJbdDQmH3ARox1asp2YlpquaBKOUMpJWxrZsPmkb84B9ZMqO5SLvaE8SDjAcpwGuApEfk5RGUcqqEUWK/yOKO3svZliSVO1dFYvnmiHpJ5LWT2OetUgwSimi4oX+P6aRhf7TIu9o70jzZpI68fMbXaAyicFVGklPSfoSpoz5fZLVshsHfBUTnvuDrJDCckUwSikRHYvfhOVXuegGDpT0z/LOCqiQT2kZLsNireLYAHMcjxokvSnpNGzb3go8l2C4HHAwcK+keyQdpOVEtjeEBKRA5KT8K35Z6H3AwZKuL++s3o1RWkh8JZCpkl4vw70/APzL0W0BFiKQJM0js0RGZH9MoWCnFIZ8jiW17BamMF4mCUYpITJ9nT8C+3l0L2ABhL8t76wMSatjhSJHYhEwXsXrM/ne/9dY+kYcV8uSZEc1knYCvgEchF/eYxzvYNpaP5X0VpKBWto6m4CPATsDu2D18sZFzV2YEsQ/op+b2lubk+ZhOglGKQHRm/Bq7IjYh6Mk/aKMU1oKSTtiOXQj8bSkTcp4/6nA04BLkH9nSa5V1ahApls1UMtunKO7i8UsqWX3dDEXtrR1romFcByNGckJjOzO6cei0gvY6epF7a3Nqa+uBwhGqUSioLfLsIfLh+OiOJeKIekzQFxaxy2S9inzHL6FSfjGMR3YTlUUg6s00Snt0Vi0+KopDPkXTI7ln3Er35a2zhzQgm0DG4BiDxsWA72YQbu8vbU5dQMSHN0lEPlqLsDfIJ1aaYMUkXe0d1RgDhcCzzr6TMO+KMsNkmZKOgM7sWvBcgeTsD8WUX+/pE9JGqJE0dLWOQXbhp2PrYxKOf1siq69CLi9pa1zhdKnPDzBKJXGD/Cr6gHwQ+DMMs4ljryjPe0YpSFIWoyfGNwPJPmk44wqJC2SlcraDPNLulJ1XLwPK2b6rKRjFNWya2nrXAWTRN6eeL12XyZgzvv7W9o6U/3cglEqEkmnACd7dv8JcEq5HMkeVCMcYAiS/oadTsaROTG4SiKrZfdXSbthhuMaktWyy2Or1BnfOf2HP6LQfy8WqpCmxlMT9ozd3dLWmdQ/9i7BKBWBrISPb3mjy4Fjq2iQIBvbtwGOx+Kz4jhaQVYWSQ/IJJPXx9wESWrZrTh3wvtPpNC/AUUYpIN2GEd7azPtrc18eFpsWt6YaJ4uv6E3wSh5IulI7AHx4RqgRelk35dE5Ihf19Gt7Nu3ASQ9hzli48i0GFylkdQh6XhshfN/xId3DMvixjVZOG4TqPMROzXyq9az99Zj6fc/BBsHHNXS1plGLFYwSj5Ep1jtnt1vILnQfxqsTvybsQt4u0JzGeBM3HrYO+MfYrFcIGmWpLOxle/ngf/5XFcAZk3eE3L+GnUNdfCFPSYwd2GBR17sKWaa44DLo9O9RASj5EDSAfgL/d8OfEpSUZ9mmXD6kyq9tZSJu33To+u5Aw7awBIkdUu6AtgS2AdTohiR7sap9OeKc/UcsP04pjY3cNXdC+jqLvrxWBPYodiLliUYpRgk7YWJl/nkHN1LekL/aZB3tHdUYA7D8TvAlfO3Jv6HCcsdMoWCW6Lnc2vspdm7bL9547elkPPftr1n1Xr2mjaW+59ZzKMvlfReHYel1CQiGKURkJWc9hX6/y+W8Z/EIZk2eUd7xfxJg4lWZ1/HfbJ0ooqs2rs8Imm6pMOxlfGPgLkABXIsHrM25Py+4g318IUPTWTBogK/+1fJaXV1wMda2joT2ZVglIZBVub6RvzSAJ4A9pY0u6yTKp68o72jAnMYFkmPAD9zdBuDBfkFPJD0ShQ9vzbwjZ6Gld7IFfzPWQ7aYRxrTKnnt/9ayPxFiXb1fdhpXMkEo7QMsioWtwCTPLo/j8nYplJ5JGUyEaMUw2m4dYf2k/SRSkxmtCBprqTz357yqVMKuXovV8L6qzew55ZjefiFbh58LnG+bT+wbZIBglEahKSNKF7ov2yJiQnJO9o7KjCHEZH0Dn5icBcqFHX0QtJqkvaWdNKErieOg5xT97uxHj6/+wS6ugtc/Y9UvA9j8ZOBHhF/L9goRyb0fxuwmkf3NzGDVA6h/8TI1AvWcXSrik9pGdqBL2O5byOxISYGd04F5lMTRJ/vhtjfbeBnKwYVqcgVurz8SQftOJ7Vp9Rz+R3zmbMwlcPYehJGjQejxLtC/7fjL/S/pyRXkmk1mUp8AcUFuHW0y46kPklfx30a9x1JVyn98lOZR6ZougVLG6Atcfg76wp9UOh3Gqat39NIf3+BnTZuYqeNl87PXX2KHTrvulkTW67byFtz+rjyLqcTvB935H4sy71RiiQkbsPPOTcPc2p7Ba9VkbyjveIxSiMh6V+yqrmHxnSbiKUxHFaZWVWeKIp9dZY2PtOwFVHRAYl1/QvIFXop5NyLlrq6HBuvOfI7bNUV6ll1hXrGN3lNowt3gGwsy7VRktV4vxXY1KN7F/BR1UZl07yjPQtbt8F8CziA+Oz1z0n6maR7KjSnsiGTFdmIJduuadFPGrpKAIzp8ROkPPmqOSO2fWGPCey0SRPX3ruQW6d7h9/VAQ/5dh6O5dYoRRHDN2LBZy66scDIWlFHzDvaOyowB28kvSrTFjrL0fViSe/LQAqPN9FztiVLr362IF43PTENfZ0UclWpM9CAWz/LOcByh0zo/3r8xNz7gE9K+nt5Z5UqWQ8HGI4fA0cSXy9v66jPpRWZURFE26+pLO14nob9PhVPMM5RoKn7FRaPWQdyFbt9AbilvbU5USL6cmeUouPlPwB7eHQvYNuGv5R3VqmTd7R3VGAORSFpsaTjcOsunSmrh5aktloiou3Xxgz1/6xcrTkNx8SFD9HduIaXXyklFgDnJh1kuTJK0VHqr7HqDT4cJel3ZZxSucg72rPmUwJA0o2SbiT+81kJOB1/5c+kc5rM0O3X5pQmJVsJnsc0zx9p6nl1eiHX8DNsBVc0l9+xgMvvKCp26S3cZbWcLDdGSUuE/j/lecmxkn5ZximVhegt7gpt6KjAVErleGAv4mNdWiW1S3o0rZtG2681Gbr6yWr57MWYhMn0QT+PSpo7uNM3zvnrHvMmvO+4QhHyJSWyEDgyjUICy4VRih64CzEtGh9OkXRR+WZUVtYk/nOdB8yq0FyKRtKzks7HRM1Gog64SNLupYQ2yGr1bcJQA5RVjfB3sIrD06OfR7DyWLGp/JI+PwmO66mfQtfYDaEIxYAiWQRc3d7afFcag416oxQZpLOAr3lecpYk1ylQlsk72jMToxTDD4DDid927Iqteq+JG0jSCpjTefDR++akq1WdJs+x9OpnOvBasZ+ZpM8CvwRYcf7ddI+ZSl/dREj/RK4HS7k6Pq0BR71RAk4BTvLsezF++VhZJu9oz6Q/aTCS5kv6JlboM45zZWL7C6KXz9oMXf24TiKrxSLgMZY2Po9Jmpd0YEmfBK4kOvWrK3SzyqxreWvKIfTXjU/TMHUDrwEfbG9tTk22Z1Qbpeg05wzP7r/ECkZmfRXhohbDAYbjt8BXgA/G9FkLuEOmYzUNmFKBeZXC2wxd/TwjaYgwW1IkHYT97ZbKL6nvX8iqnb/jnRX3p7e+mUJdYh/TAuBx4KPtrc2ppiyNWqMkqQWLffHhGuBLqqLQf4rkHe0dFZhDYmTqil/HooPjEri2r9CUfChggYPTl/l5oxIvO0n7Ys/ysEuh+kIXq8y6hvnjpjF34k4FqO8lV7QHvCf6+T+gLWlM0nCMSqMk6VDg557dsyL0nxZ5R3smt2/R9mtdhma+Z1Vepwt4lCWO5+nY9mt+NSYjaW/gj8QnYpMDJnVNf6a3YaXPLRy32ecp9H4pV+hvKNQ5XWzzsM/il8B57a3NZVPIGHVGSdKBDNpPO7iN7Aj9p0Xe0d5RgTnEEgWwbspQ/0/qJaBT4i2WPv2ajlWgzcSLTNIewHX4Oe+fB/a48Bs7vwo8cNrpZ262aMx7dl08Zi26G9egt36FJT6nQh+5Qu8rhbqmm4G7gD+3tzaXrJXry6gySpI+TMzydRnuAQ5UdoT+ExMddWcqRklWinvwydc0zCBl8dkrAE+z9NH7dElvVHFOsUjaBVvt++TSdQB7SHo3i7+u0L3m+MVPM37x0+92KpB79/9i35FECbbFksUHoyRkQv/X4fe2eIjsCf2nwVrEb3fmqExa4tH26z0MzXx3ic1Vi4Us2X4N/Pyvlp4JSTsBNwHjPbrPwAzSy4Ouz2HPzFLkKCx7XUUZFUZJ0vvwF/p/HNhH0siaDbVL3tGeij9JUhOwGUP9P5PTGL8MvM5Q5/PzWdl+lUL0zP+NeLmXAV7HDNKyn//KxK+wFlP5gqW1b5QkbYm/0P9zwF7KptB/GuQd7R3FDihpJYYan/eS3WdnDrZ6mB79PCLpzWpOKG0kbY3pgPm8BN7EDNJzw7S5tvqvVCNEJqsPlhdaIvTvE5/yMtkW+k+DkmOUotzAge3X4J8hy/uMswLwE0n3Vnsi5SB6Cd8GrOjRfSb2zD81QrvLKFV86wY1bJQk5TFdbR+1vjcwXe2XnT1rm7yjvQNA0jiGbr+2xG+1WQ1eZcnK5z3ES+eC5cXtUMvbs+GQtClmkHxy9Aa05B+P6ROMUlpImooZJJ+3+DvYli3LQv9pkXe0HxQFlW6C3wllpekDnmJp388jkt71a0T+rB2Iz97fFvgiVi1lVCBpY+AOYBWP7nOwZ/4RR79glNJA0irY22I9j+5zqQ2h/8RE2y9XmetdKzEXT+axJOhwevT/Py6pK+4iLRGDu8Ex/oAYXGYVEXyRtD5mkHzKfw0Ut/ivR99glJIiE/q/BXO0uliICf1XNMaiEkgaj2W6T2PJ8ftW+J3EVINXGHr69WKCtJ4bsZOnuOq5K2NicMeUeI9MELkp7sBPqG0B8BFJ93sOn0mjlCsUaiP/VCbAfivwfo/u3Vgc0m3lnVX5kbQqQ53PG5PN9Is+4AmGbr9SrzEXHXL8j/i0ij5ga0mPpX3/SiBpbeBu/JQOujCDdHcR43dgqT0jsZVSFNLzpSaMUuSYvRHY3aN7L/BxSa7lfaaQSfVuwNDj9zWqNql45rJ03td04IlKRshLOhsrzxTHXdiRePYf9EFEftO7cW/JwWRQ9pV0exHj10fXxe2Wmqux/c389k2WJ3UtfgZpQOg/0wYp2n4NV/XUJzK3GrzM0O1XRwa+6GdgBSrjDPduwCeB31diQmkgaTVsy+ZjkLqxAwxvgxSxOvHf/wXA7CLHTIWKrZRa2jqbsQdke2AX7EFqwP6oL2JvhQeBu9pbm7vgXb3p32APlQ9HKmO62pJGqnqaxe1XLxbxPp0lK6BHVMXKIS4kfQ4rBhHHDOC9tZBCEh3k3ImFbLgoeVcgaUfgvpguT0ny8d2mTtlXSi1tne8DTgT2xwzQRIZ+IdfDDFUXUNfS1vnLXH/3T6aaCqSvQTqmmgYpWg5vxNDkU58Tk2owh6GrnyclLa7ajErjakwMLq6G39qY/s93KjKjEpElL/8dP4PUBxySYFeQSSc3lHGl1NLWuRIWJ7I3ll/jvzIoFLqhv37Cwun1Kyz4NzmcMXAnS/phyZMtksjpvuz2awv8cu+qxb+Bm1myCnopA9uvVJC0DbbKjpOrWQxsKumFysyqOKKT5duwGCsX/cChkmL1yR33OwE4L6bLLyQdVer4SSjLSqmlrXMfTJJzHKXUx8rlxkA9C8ZvyaKxG7DS7L/S2DfiAc6Z5TJIsizqNRha9XRDqlD1NCEtozVeS9J/JV0KfDmmWxNwPnBgRSZVBLLacjfjZ5AKwBFJDFJEZldKqRullrbOz2FllZOvGnKN9NVN5u0pn2Tl2dcxpneIrM1FwKmJ78O7/quNGOr/8YmgrQazGCS5AfzC0b+jvNOpOqdi1U3i8iAPkLS3pFsqNCcn0ar7JixK3YejJF2Vwq0za5RS3b61tHUeiDmmU9/G5Pq7WWX2H2jsfTfB/xeUqKstaRJLVz3dCtt++QhlVYMXWEZ4DJgxsP2StCHwTMz1MyMH6qhG0leBnzi6PQ1sKam7AlOKJTqFvRE7APLhaEm+Ms+ue99PvL75hyX9PY17FUtqK6WWts51gKuIMUh7bNHEhms0sOZKDUwal2NsY46u7gIzZvZx79OLuf+ZkZ+TQq6RmSvsx+rvXEmOvt8BX3YZpGj7NZWhqx+fo9Zq0M3wVU9d2k95R3tHsmnVDD/HtnBbxPTZGCv5HedPKTuSxgLX42+QjknLIEVkdqWUilFqaevMYacgsf6jfbYex6RxOV7t7OP5N/pY3FNgpUn1bLJWA5uu3ci263Vzyc3zGXbtlstRyI2lc/KeL6w095bDtUwGuEwKdmOGGqCVkv5+ZaKTJbrPA6ufp1SaXvhoKauUCEm9sgoodzm6flfSb1QlGRtZUvGfgD09L/mGpItTvP8YLE4pjto2Stix/TTXeJfeOp+XZ/bSvUy1q6lT6jnhgElsvd4Y3r/JGO59avgVU6GukUVNG63x1pQVto7+sNMG/WxOKU71yvA8Q4/fX03x9CvvaO9I6T6ZR9LdkRP4kJhuk7CqyZ+vyKQGMSgYOC5vbzAny8qYp8lU4g9qZlUzpisto/RtLP4olufeGL723muz+rjzsUUcuMN4Nl2rcUSjZPSPbex9xzfhsNIsZviqp3PLfN+8oz2TZZXKyDeB/YiPkD9C0s8lxQUQpkq0mv8tNjfPS8pyspzZrRukYJRa2jq3IgUfTX+0ZuhxhSTl6nMLx27ECvP/QV2hqpWRZmLbr8G5X0+rDFVPPQjbt0FImiHpTNzVkS+WtH0phyUlzKkeK/31cc9LzgS+V6bpjG6jBHyahNumlSfVsetmNsSjHe5DkVyhn0Vj8oxfXDHdtuGqnr6eoeDDvKO9owJzyBrnYUJvcbpbA2Jwl5VzIpFBuhz7rvhwLnBqGZ+vUW+UdqVIFcOdNhnDxlMbqa+DFSfUsf7qDdTl4KaHunj4Rffqp5BrpLthtXIYpUUMX/V0Xto3SguZgoLLadlRgalkCkmLJB2PnXDFcZZMDG52meZRh50KHuZ5yUXAt8r8whu9Rik6dYs7fh2WDVZvYKdNliyuevsKXP+fLm59xFP1IldH95g1LY+5dN5m+Kqn1dh+JcFVV+0tSWWvappRbsAipfeJ6TMgBnds2jePQlJ+ChzpecklwHEVWIG7npnaNUrYKUbRW7cr71rIlXctpLEeVp5cxwc2aWK/941juw3GcOFf5zFnofsz6av3LjFWwAILp7N0AOIbGdp+JSH4k0ZAUkEmnfsY8WJwX5XUnmYaTmSQLgCO9rzkF8DXKvRMjt6VEhYB3Uf8Bz4iPX3w+qx+/nBfF3MWFvjUB8Zz6C4TuOTm+c5rC8Pn93YxtOrpY9U83qwAeUd7RwXmkFkkPS3pAuxEbiTqsQooH0rDKEQG6Rz8pXh/jUcwcIq4jFJVq/4kNUo9pKQLdM9Ti/nUB8az5brma+pzfjyFAqbXPX3Qz3PLBlUuB+Qd7ctbOMBwDIjBxfnedgcOBv6Q5EaRQToDk+vx4XfAFyr13EapLa6A4lcrMZeRSGqU5pFStnzX4gK9fQUa6nOMb8oxryv+hVXIjXlRkm8A2mgm72jvqMAcMo2kuZK+hR3Jx3GepJsS+uC+A5zi2fePwJDshDLjKkv2pqqsqZVoldPe2tyLRSsnZsOpDTTU51iwqJ/5i9wr6HGLn1lH0k+iZNTlmeBT8uNq4pUWwRzAJ5V6A0knY05zH/6CaSJVOtgu0/4kSGfrdY9Ppw3XaGCHDcfQMMwd11+9gSN2t+pA/3pqMS7hglx/D03drzYAX8UCFq+XtGu0dF7eyDvaOyowh8wT+Wu+DsOnVg7iJEk+1UOWHf8bWMCjD38DPlUlpYLMG6U04pRuwHRsYks+rzK5ji98aCKf2bmfl2f2MXdhP02NOVZdoY6pzTaNRzu6uf7+2FqEABRyOZq63/3b5TCp3f2B/0r6MfD7LEhTlJvIP+AqW/5SJeZSC0h6SNJlQEtMtyYs8NI38pooCfhcz+63AQdXcYuUeaOUxkrpRkxyI5ZnXuvlhge6mPFOH6utWMfW641hs7UbGdOQ46Hnu/np3+Zx8U3z3WkmwJieN2noHzadbBvsJONFSSfLNI9HM3lH+xtyVJxdDvk27iodB0nay2cwSV/GAh59uAsTmqvmZzL6jVLkV7oIO44fkZnz+vnLA12cd/08TrpyDl+9dBatl87i5Kvm8LNb5jPdI5IbTOxt4kJnReKp2FJ6hqSfygoXjkbyjvaOCsyhppD0NnCaR9eLogTauLG+CPzM89b3APtlIJB19BuliAtIGl/tQ6Gfhr5ZjO32PuUeD7RiOkV/kbTbKPM75R3tIRxgeC7BxPTi2ATzQQ2LrLSTb87c/VgJeXcAXvlZPoxSe2vzXOCzQFnfAjn6aJ7zt1JiEHKYXMSdmN/psEjXptbJO9o7KjCHmiNKJRrR4CzdVUNimyQdAlyBXzjMQ8A+FZCv8WX5MEoA7a3Nt2L+nPKsmAqFhWMXPfvrhv65TyUcaRoWr9Ih6RRJWVWm9CGEA5SIpLtwV80dEIMbfN3HsfACn+/OI5jW9ewSppg6klYA4vKz+oGqqHEOJu0qrV8FbiXlFVOuv4fG3jevuegbHzwcK9T3UewUIwlrAD/A/E6XSNo46TyrQN7R3lGBOdQy38ThCwU+L2kHAEn7YRHYPqoYjwN7KVvVhV2rpNeykJCeejHKlrbOekyq4TPEK/+5KRSAXibPv49JXdMfA7YZ/EeTtCVwHLZ1TGM79lesNthdtZCsGzltV47pspGkiolO1SKSTgW+7+j2APBd4Dr8nrOngN0kvZlsdukSZUDcFNPlPklxlYYrQur17Ntbm/vaW5uPwmKXOjGJ2OLp76G+bw6rzPoDk7qmg0mkLFWxU9Kj0QnIuphK38wh4xTHvsAdwMOSDs+y30lWLyzOIEGVEytrhHNxHwi8D4vA9nkengM+lDWDFJHpRNwBUjdKA7S3Nt+IyeRehOXIuYXSCgVy/d3U9S1g8oL7WK3zKsb0vj24x/dl5Y2XQtIbkr6LpQm0AE8mnP5WmCPzJUnfluT68leDvKP9tWrnMNUCkhYBx3t09Qk0fhHYQ9JryWZVNjLv5IYyGiWA9tbmWe2tzd/CqswejZWVeQVTF1iAGaoF0X8/29T90svNc29i9Xd+waSu6eQYIhWwMjExJpK6oojdzbBqEbcm/BVWxzK+Z0j6maRNEo6XJnlHe0cF5jBa+AvJn5UZmEHKxBd7BGrCKKXuU/Khpa1zApYeMQbb3r3W3trcLWk9bJUTt0zuBbaQ5HUKJ2kLzO/0Oce4vtyE+Z3uqKbfSdLXgLhaYFdHsTQBD6IXzmOUlnr1GrCLpFSS08uFpNuBPWK6fFzSnys1n5Eo60ppJNpbmxe0tza/2N7a/HR7a3NHe2tzN4CkF7AvfBwNFFHdVNJjko7EtnanYzK4SRg4+Zsu6fOywoLVIIQDpEj0kruwhEvfwFZImTZIETWxUqqKUXJwJvZBx/FRSXG6y0OQ9KYkYcbpKOCJ0qb3LltiFSpeknRqFfxOeUd7RwXmMNr4HvBOEf3fxpzaT5dpPqkRZTIEo1QKssohPiJZP3blJo0w/iJJv8Aq6u6NqVcmYTXsSHmGrLjhexOO50ve0R5STIpnbfy3+J3AnpKSvtwqxUqYfPVIdJN8F5EKaVXITZsrsEDMbWP6bAJ8Bf8M7aWI/EG3ArdK2gzzOx1G6TXsxgJfAr4k6W/YNvT2Mvqd8o72jjLdd1QSBc/ejkOCZxB/kPRoGaeUNq5V0iuqnEZ4LJlbKcG7glw+JW9OT2PbJOlxSS3Y1k7AWwmH/Ajwd+ARSV9I2+8kaTIQJ8tSICNL8VpA0gZYfNpqRVx2uKR8eWZUFmpi6wYZNUoAku7BQvrjWBF/+VGfe74l6XQsGPNI3JnkLrYAfon5nU6TtErSOUbkHe2vajkQuUsDmcrkHZjcTTGMpYgDlwwQjFJKnIQ7N+loSZunedPI7/RLzJn9YaygYRJWw4znDFl9sU0Tjpd3tAd/kgeS1sEMkusLOxIfl7RnilMqJ8EopYGkl4EfObrVYU7v1HWSZMUM/x7lDG0GtFNq2ozRhJ38PS7pb5L2KnHeeUd7RwljLldIWhMzSPmEQznF4DJCpqviDibTRiniHNx1qPbE9JLKhqQnJH0Je+OcRnK/0z6Yo/1RSV+UFHcysiwhRikBMo2k24H1Pbq7Direix3KZJ2wUkoLWXXbb3l0Pa8SgYyS3pb0fezN8wUsCjgJm2Mlm1+S9F1JrkIAEFZKJRP59W4HfKRqeoBTPfqdLqkYJ3k1qIlkXKgBoxTxW9w1uzbAT00wFSQtlvQrLHl3L+IlIXxYFTv5e1nSZVGYwkjkHWMFn9IwyAT9bgN8fHq9WBmkM3FXzZ2Mf3mliiOpHljT0S2slIohivXxCRE4rdJvrMjvdJukj2EP+6XAogRDNhGd/Em6RdLew/id8o4xOhLcf1QiaQoWprGlR/d+rFDkddF/n4j7wOWLkrYvfYZlZTXiYxIX4K7wUjGqkpBbKpKuAA53dLssijmqGlHs1NHA1ygu9mUkHseKM1yFHUXPiunbD4xV5SuvZpYoruvvgI/RKACfk/SbZcY4DXf4yX+A92clCHEAmXLmv2O6PFXBTAQnNbFSGsTJuDXAj5S0dSUmMxKSZko6A4t3+jyQNPJ34OTvZeCHjr6vBIO0BJkY3t/wM0hgK57fDPPvP8K9At0eOMJ/dhWjZpzcUGNGSSaedZajWw64oBwhAsUS+Z2uwIoVfAgr3JmEVYAvO/oEf1KEpAnY39xX4vXLkZ9wuLG6gBM8xvihTKA/SwSjVGbOx12Kehfg4ArMxYvI73SHpH2xI+Sf4fZRlEpHmcatKSSNA67HngUfvibpUkef67BtYByrYnreWSIYpXISvbFO9Oj6o+jBzBSSnpL0FSyk4FTcMi3F8krK49UcUczXn7HVqQ8nSPqpx7gDBy6uih9fTyFqP02CUaoAfwT+4eiTx2+5XRUiv9MPsHkeAUxPaehjJH1PwxRRXB6QFXu4FpOl8eEkST8uYvwncStTNAAXZsGFEBGMUrmJ3ljH4Y62PVlSsYmWFSXyO10JbINJlf414ZCTgO9gwZiXy8pQLRdE6R6/w6rS+HCapHNKuNX3AFe1kj2BA0sYuxzUlFGqqZCAZZHUzjJll4bhSklZPBEZEZm2z7HYyV0aW9DbMF/cLVk7rk4LSQ1YyMQhnpecIek7Ce73eUx5NI4OYNPI5VAVIkO9mPgS45Mkza/QlJzU5EppEKfiLt10eIaD2oZF0tOSWrE33CkkL6W8JxZx/rikL2XR15aEKGL5cvwN0jnEVMXx5ErgfkefPFaFt5qsSbxBmp0lgwQ1bpRkBf9c1U0hIyECxSLpHUlnYQ/3YVjl1SRsglUvniHp+6PB7ySpDovh8q3ccgHwf0qoCBqtOH3Smk6WtG6SeyWkprZuUONGKeIirCppHO/HyojXJJK6JV0FfDulIVfCVpkvS/qVpK1SGreiRC+aNiwx2oc27KQtFZ+FpAcwEb84xmJVeKtFzSTiDlDzRklWBfYbHl3PiYLpahmXZEmxNBKd/Em6XdLHopVH5okM0oW4g0kHuAw7qk/biXoyMNfR5xOSfMMT0iaslKrEDZgzN4418ZNAyTL5Mo49cPL3hKSjJY0v470SERmkc/FXhbgCi9ZO3ckv6S38giUvVHXE4IJRqgbR2+94GFrnexm+JZNArVXyjvZLgP8mvMfG0TgzJJ0haY2E46VKZJDOxD8G7TdYPmQ5Tx1/iruO4GZAaxnnMBLBKFULSf/D0jfiGAucXYHplAvX9u23wHbArliKRZKtSjPmw3pJ0hWSpiUYK02+C/yfZ98/AEdI6ivjfJAlQB/j0fV0+Yn4pUkwSlXmu7h1YT4t6QMVmEuqRCuEvKNbhyzP7h+SDsRWPT8BFia4dSMmF/Owovy9avmdJJ2Cf17Z9ZgmkislJBUk3Y5lGsSxApUXgwtGqZpImon//r7WfveVgDhHfQ/w2uB/kPSspK8Da2GrC5fWuYvdMf/dk5K+UsmDA0knAj/w7H4TcIgqL+FyIm6Bvy9Kel8lJhPFo7nqImYuV7LWvpg+XAI86eizLW6xuKyRd7S/PNI2RdIsSWdj27/PAg8lnMtG2PH6y5LOVJlTeSQdg7uqzQB/Bw6OTmUriqQO3HpXOeDiCr0U13K0v1WNv5OLUWeUorejjxP0LEm+JZqzQOIKJpJ6ZAJm78MkPa4jud/pZGzb+GtJ2yQYa1hkigoXena/EzhQUhI54qScg1taZwcsGLbc1NzWDUahUQKQdDNuIf/VsRSOWiHvaO/wHSjyO/1T0kHYqudi3IqecTRiEdUPSbpT0n5prAQkHYmtyHz4J7CfpCT+s8TIXwzubJVfDC4YpYxxAm7dmxMkrVeJyaRA3tFekuKkpOei7dHaWBxXUh/DbsBfMN3n1lL9TpIOw9JHfLgP+JisHFcW+DNWximO1TA1h3ISjFKWkPQ0dvIUxxj8fRXVJu9o70gyeOR3+hGwHpaS82CS8YANsfidGZLOklWk9Z3Lp4FfEZ9IOsCDwEckuRKzK0YUN3cM4ApFOFblFeyvmaq4gxm1Rinie8BMR5+PS9qtAnNJSkWq4kZ+p99hIvg7A38imd9pCnby1yHpKknbOu5/MCZB4vNsTgf2ljQnwfzKgqQnsG1xHA2UN1k8rJSyhqRZ+C2RL5TJX2QS3xillO9ZkPSvyEhsiCU+J5G4aMBO/h6UdLekA5b9m0vaHxNp8/ks/gfsJakzwZzKjXCXd/8wcECZ7h+MUka5DHdp7S1xi8VVk1WIF3vrJrnm0ohIel7SsdhD/k2SP8wDJ39PSfqapImSPoJFYMcVTRzgSeBDUVxaZolWcCd7dP2xyqNxVXMKAbAcGKUoovc4j65nSFqxvLMpGdfW7SVVQFFS0mxJ5wLrA5/Gii8mYQNsi/M6FpTpk7D6LGaQXCuQrPAr4AFHnzx+xTC8kRXgnBzTpZ8yvsiSMOqNEoCkO7A3cxwrU/7TkFLJO9o7KjCHd4n8TtcAOwIfwNIrkhjFifht2V4A9pCUyS/TcKg4Mbg0k8Vdq6TXVKEUnGJZLoxSxInYNieOYyRtVInJFEne0V6VApSR3+leSZ/AVj0XkMzvFMfLmEHKXFqEC0n349bzHke6YnA16U+C5cgoSXoe+9LE0QCcV/7ZFE3e0d5RgTnEIulFScdjqQ0nkq6/YjYWh+SKlM4yPmJwn5S0e0r3C0apRvgB7tI4+0ryrRlWKSoSDpAGkuZIOg/zOx2CW1zfhxWBf0k6R5Lry5ZJZHry8uh6kawyS1KCUaoFJM3FL7Xkx6qOSuBI5B3tHRWYQ1FI6pX0e0k7AjthJ2tJ/E4rYCd/L0r6rSqUaZ8yP8GdLL458JUU7hWMUg3xK9zqjO8Fji7/VNxEMUquahhV8Sn5Iuk+SZ8EPgokrYFWT3Typyh/L8sxZoORJYsf69H1e5JWSXi7YJRqheg05DiPrqdLWqnM0/FhNUwxcyQW4d6SVh1Jm2C10tKMx/kgFnH+jKRjVAOqD5L+juXGxbEi/tpRIxGMUi0h6Z/A7x3dpuDnAyg3PjFKmS5zLGlD4A6gXFKw62HyJjMk/Sjlo/VycAJuMbijJG1XyuDR6joYpRrkW7gfjK9I2qwSk4kh72jvqMAcSkbSezCD5FOAoJfkfqcTgRck/U4ZrYwsE4M7x9Ethzm9S/mONhO/Iu3Bnf5SNZZboxQdL7sUAuoxp3c1q+vmHe2Z9SdFK5Y7cSsggumI746d2p2P+/g8jnqikz9J90g6OIN+p7Nxh028H//Kv4NxrRRfqUQGQKkst0Yp4mzcutV7AftWYC4jUTPhAIORSZXcidtJD7Zi3TdKAO6Q9A1s+3E8yX+/gZO/ZyUdF6VfVB2ZGJ1PEdWzS5hzzW7dYDk3SjJRMJ9yPedJGlPu+YxA3tHeUYE5FIWsVtwdmK/HxWLgAEl3LjPGXEkXYAoFnwDuTTit9wA/xvxO50ryMZbl5o/Y3ymO1Sk+/akmE3EHWK6NUsRvcAf4bYh/Nda0yTvaM7V9k9U1ux2T2XXRg+lZ3RozXq+kP8rKYu0IXINbPC2OydgK5XlJ10RxVFVB/mJwx0Wnl76ElVItE+2tfWJHTlOFCwlGTk7XG72jAlPxIgqhuA2L83LRi6VVuLTUB49/v0yVcj0sTyyp3+lTwH0D+XspRVIXhaTHcSukFisGF4xSrRMlTF7l6DYZ+H4FpjOYNTDJ3pHoAt6u0FxikTQFK2+0hUf3Pqwo6PUl3utlSd/EHOjHkXy1+H7gWuA5ScdXwe8k3J/j3sB+nuMFozRK+D/clWSPkrRVJSYTkXe0d2QhRklWleMWYGuP7v3AYZJc1WR97jtP0oXY9vpg4F8Jh1wXO/l7RdL5kvIJx/NC0mz8xeDiAmkHCEZpNCDpVeAsR7c6yqupvCx5R3vV/UlRFPXfsFpyLgpYhdjfpjyHPkl/krQzVlPtdyTzO03CTv6el3StpPenMU8Hl+Mu1rAejhO7aMvvKtIQjFINcR7uQoK7AR8v/1SAjJ+8ycon3Yhtf3z4kqQryjglJP1H0mewL/CPgCRFBeqITv4U5e+Vy+8kfzG4UxSvlLAa8QqeC4FZxcyt0gSjNAhZIcFveXQ913MZnZTMxijJNKX/glU88aFV0mVlnNJSRH6nb2FbmWMw1cok7IilJj0n6QSVoZCkpH8DLqM9nvigX+fWLQtb/jiCURrKtVi11Tjy2PK+3OQd7R0VmMMQIoN8HbCH5yXHSbqkfDMamcjvdDEWonAQ7s/WxbrYinqGpB/L0mjS5P8AVw27QzRyWbCa9idBMEpDiN4ix+GudfbtKEiwnOQd7RX3KUVBpH/ASgP58K3IGV1VIr/TdZJ2wfxfvyG53+k4bOX0B0k7peFrlPQGcLpH15HE4IJRGo1I+i/wS0e3CcCZZZxDPe4cpo5y3X84ZMJ31wAf87zkVFnV3Uwh6UFJn8W2x+dgcrulUoed/N0D/FvSISn4nS4GnnL02YLhNb+CURrFfBv3MvrzKp8C4lTiHZYLgHfKdO8hRF+0q4EDPS/5nqSkmkBlRdIMSSdhX+SvA88nHHJ77OTveUknqsSSXZK68Qvo/b6klZf5t5os1T2YYJRGQKapfIZH13KFCOQd7S9WymEZrdquAD7peckPyYYWlReS5kv6CbAxZnT/kXDIdTBn9AxJF0jyyQFcdk634i4LtiJDxeDCSmmUcyHut+dOmDxr2uQd7R1luOcQoriXy4BDPS85Hzu2zvQJz3BEfqfrJe0KbIetDJPURpuIrXieleXvfbDIF9g3sITlOFokbTPov2s6GReCUYpF0mL8KpeeI2l8yrevejhAZJB+Bnze85KfACfWokFaFkkPSfoc9jn8kOR+p49jJ3/3S/q0PApTSHoBPzG4i79y0bONX/7Jq9stGPveNeaN34Z547dj/rhpLBqTp69uqUcz8yuliicg1iDXY/ISccffa2GVNnxOTXzJO9o7UrzXEKI3+kVAi+cllwLHjgaDNBhZ8cuTI//YEdiJ2wYJhnwf8FssleUioF2WZjISP8ReCkNWQAVyLGpaj3njt9mpt765C1g0Z+KuuUKuHrNV/eQKfRRy9eQKvYxf9NTiBeOnrUL5CoamQq5QGFXPUFmQtAUwnfiVZRewsaRU3kSyUuNxhQkPlvSnNO41zL1z2DbsOM9LfgUcqQyrGaZFtHrcF4tT2y2FIRdgJ70XygqmDnfPTzJIU74ALBz7XuZM3Bmoo1DnKfVV6CuQq1+MrdiOam9tzuRWLhglTyS14a7H9ZvoqDmN+71A/BZu2yh0IVUig3QWcJLnJVcDR0hKEvNTk0S+nOMxn2LSXUcBW5WfjxXefPeLGX0mtwO799VNpHPyh+lpWI1CXcmlCXsxX9XxwGXtrc2ZMgLBp+TPabj9CodK2inpjaLj92rFKAl/g/R7LCxiuTNIYPFskg7DttpnkSynLMeSk7//SPrMgN8pMlDHdjes0vdm86F0N66RxCCBGdAJmBLnr1vaOjOlXx5WSkUg6Tjsg4zjQWCHJFsZmVRrR0yXecAKaftvJJ2Kv2bUn7F0h54051DLyBKUD8dWIBumMOQrWCBl+6urHrMOhd4HoL6RXKoRKAuBG4BD21ubM7H9Do7u4vgpFkW7cUyf7YDDcCdWxpF3tKceoyRLXvU1SDdiIm3BIA1Cpvl+iaSfY9WATyDeL+hiLeDs/tzY03KFnoYCDQ0jGaTVVqxj83Uaya/awLqrNLDainXU5XJccvM8/vtC7Mc0HvORnQp8L8FcUyNs34og+hKe4NH1LEkTE9wq72jvSDD2EKIV4Nme3W8BPhFFHQeGQVK/pL9K2gMTvrsS0yMviVmTdp9QINdEbuQl0m6bjeXTH5zAjhs1scaUeuqKW01NAP6vpa3TRzW07ASjVCQyTembHd3WwE9JcCQqFqMkqRX3lnSAO4CDJLmKeAYiJE2XdAT2ojkT6Czm+kVj1mVxUx5y8ZuaVzv7uPnhLn5+y3xOuWo2T79atA0cC1zb0tZZdZtQ9QnUKCfgjvT9hkqXtcg72jtKHHcpJB2FbUl9+Aewv0xzKlAkkl6T9G0s3ugrwDM+182ZsBOFnNup/a8nF/PH+7p48Plu3p5bkmsoh+Vb+qo/lI1glEpA0pO4v8xNuCvwjkTe0Z5YsiR6e1/q2f0+rFjkgqT3Xd6RtFDSz7CKL/sSU/etp2Fl+hpWrNTUwORYfEQOy0owSqVzOu4s/YOjPKpiKev2TdKhmCa0j+PhAeAjklyKCYEiiPxON0r6EDANOxhZas81f+wWFCr/FX1/S1tnuXXCYglGqUQkzcJil1xcqCLq2EexKWs5unX4jjfM+J/AHK8+BulhYG9JSXSuAw4kPSLp85iq5RlEL7vFY9aGXMVDiLqx4gtVIxilZFwK/M/RZyvgi0WMuRbxn8tsR67UiEg6AMu78nnSHwP2ioxvoAJIel3Sd4B1+nNNX+urr3T5OcBO4sqlEeZFMEoJkNSLn1b3D+QvNJ93tHd4jrMUkj6K6Y/7xKY9AewpqWIicoGlKMwfv/VMKFTjlLMek+OpGiF4MiGSbpNVej0gptsqWHDaNz2GTN2fJOnDwJ+IV7Ic4BngQ5LeKvY+geKIctrWwlbTWw762bhpcUfd/HFbUaj89g3M4V01glFKhxOxCN64L/2xki6V9KxjrLyjvaOIeREF8F2PnQa6eB7YQyZeH0iRKAVlM8zoDDZCKw57QbqpJMVS1R1UMEopIOk5SRcQvxJqxErz7O8YLu9o9w4HkFWMvQELjHPRgRmkV33HDwwlWv3kWXrlsxWmweRtaer6u4vpnjZzq3VjCEYpTc7ARMBWjemzn6S9JP09pk/ecZ8On8nISk3fhOU2uXgFM0iZ1NfJKrKS5ZszdPuVePvT0DebgiOKu0z0A/+uxo0HCEYpJSTNjSJ22x1dfyxpWuQkH47EPiVJ22GpMD75d68Du0uqeA25WkEm7LYeS698toz+rSzk6KO+bx59DakX4nUxH/hPpW86mGCU0uVy4KtYMNxIbAZ8mWEiwmWFHtd03KMjrlHS1sDfAZ/z5DexFdJzHn2XC6JT0i2X+dkCOyqvKE09r7CwfhLk3C6edVau57O7LJniGs3mIP/4juPZe9oSQYmz/uTcmY0B7i9huqkR9JRSRlaB9W5Ht05gQ0lLJWdKWh+IMxCdklaKufcWwJ3AiH0GMRNbIbnirEYlUUDrBgx1PK9bzXkNprthFWZO+YRX7ttGUxv45oHu91BLmzMf+J/trc27+M2wPISVUspI+oeka4mvkdYMfJehBQdL3rpJei8mmepjkGZhcUjLhUGS1MxQx/NmwLhqzsvB7DG9bz+S61+8RaG+sdnV+ZnXen0Mjot5lJ6vmRrBKJWHb2GnbHHH8F+V9HNJTwz6t7xj3I7h/lHSRlhi5yoec5uDRWo/4tG3ppDJCG/EUMezK22nmvQDTwOPAI8O+nlFUqGlrfMg4NeUf/tYwFbPN5X5Pk6CUSoDkjoknYuV/h6JeuB8SR/REhXJvGPoIc7oaMt3B7C6x9TmYblsD3n0zTSSVmGo43lT/OKxqsU7LDE+A//7hGL0qdpbm//c0tZ5JyYp4lm2pCQWAZ9sb22uut56MErl44dYzltcxvXeWNDljdF/5x1jdgz+D5mW9x24neNgpXw+IqmqTsxiiZz/mzB0++VjhKtFL/AkS698HgHeUGkyxl8EnqV8RmkhcFF7a3MmXlbB0V1GJB2OW6v7GWCLV1c9hpU7f39/IdcwjVwduUIfDX2zqetfMDiEbj9Jf43GXgsTXvMRkusCPirprlJ+j0oQBR2uxlDH83vxS4+pFm+y9MrnUeApWXXl1Ghp63wfdoiR9jauC7gNOCgLqyQIK6VycxUWIrD9cI29dZOZP27LjRaO2/QVYMV3VjywwVwMZoassmkfjb1vM6Hrf4zpffNVAElrYCskH4O0GFOMvCv5r5MOksZixmbZ7ZePT6xadGOJyoNXPo9JerMSN29vbX6gpa1zT+BWLCA2jaS4BdF4h2TFIEFYKZWdKLL63sH/1t2wCnMm7kx3Y7QD8YjczfV3U8g1zssVFl2++szL966jN66iyru3Ag6Q5NIULwvR6mcqQx3Pm5DOl6pcvMZQx/PTykD1lpa2zvWAazCjXuqqqQ97WZ0KXJiV0koDBKNUASRdBXy2QB1zJ+zA/PHTgIbSki77e/vrCovqmufcRFNvbN5sL/BxSTeUMudikTSO4RNOncfZVWQR8DhLb78ekzSzqrNyEIn7fw1LbQL/tJZeTN1yOnB4e2tzJoNmg1GqAJLW6suNfXrmlIPH99ZNhmTVTY1CD5Pn38+krmErd/cBn5L0p+Q3Wppo9bMOQx3PG5Jtfa6XGep4fi4m3SfztLR1jsXi4b6JrZwWYv63gfirPmyL1oAd+f8GuKC9tfmJoaNlh2CUKkBLW+fKuf5FzxRyjVPSlDfNFXqYuOBBJi98YPA/9wOflfS7pONHchvDJZxWPCGrCBZiaqCDt1+PaZQraLa0dU7APqdtsADaMdjf4hmsanNHe2tzTXzZg1EqMy1tnY3AQxQKG5PLDTnSra+DDddoYIt1G9lg9UaaJ9UxcWyOeV0FXnizlzseW8Qzr438Ms8Velhh3p1MWPQU2NvwCEm/LmaOUcJpnqGO5/Wpon6GBy+y9MrnUeAFSZlx2gaKJ5y+lZ9TgPWGM0hgOUsn7G85S7MX9PPy270s7i2wxpR6tl1/DNuuP4YbHujiLw8MX26tkGtkzsTdGNv9CvX9849yGSRJk7EE02UTTquqNuhgPktvvQZWP1XV/QmUh2CUykhLW+fmwEnE5FgVCvDQ893c/uginn196RXRdhuM4ag9J7Df+8bx9Ks9PD3CiqmQq+ftKZ98tq9+0uUD/xYlnA7IbQzefpVaILMSFDD1y2XjfjokZeqEKFA+wvatjLS0dd6ARWyX7AA+fLfx7LzpWP715GKuuDOmFmShv2uF+XdfMrHrsUmYEdocP4G3ajGHoY7nxyXNr+qsAlUnrJTKRFTQb08Snki9PNPcI1MmOIcZt7hx7RMmdj2W5HbloB9LkVg27uflElMuAqOcYJTKR0sag6y2gp3WzVno2L3k6ljUlKcvN5b6qlTmAUwSZbiE04XVmlCg9ghGqXzsi59g/4hMHpdjp03MP/7Q893O/rlCH92NazCuu+zKtn3AUwzdfr0WVj+BpASjVAZa2jpzWHRzydTl4Mg9JzK+qY4nZvTw6EvuDIdCrpHuxlXTNkozMYMzePv1ZJzcRiCQhGCUykNiSdXP7TqeTddu5J15ffziNk/fb66O7sappd6yh6XlNgaM0Jth9ROoJMEolYdm7EteEod80E7cZi/o5/y/zGNul79N6M95Kby+wVDH81OS3HvEQKDMBKNUHkrOJfnkTuPYc8uxzF3Yz/l/mctbc4oMz1m68kU3wyechpLcgcwSjFJ56KKEUICD3z+OD08bx7yufn58wzxen1V8vGAh1/AGcAJmhJ7NgtxGIFAMwSiVh+cpslLGx3ccxz5bj2PBIjNIr7xTWvpWX/3kmyT9tqSLA4EMkGWpiZqlvbW5C3jVt/8B24/jI9uYQTr/hnnMmFlyPukClhGUCwRqjbBSKh/3YLpDsVn2W+Ub2Xc7W1S9PbefD20xfGjT67P6uPlhr1P4B9xdAoHsEoxS+WjHar9NjOs0oWmJzcqv2kB+1eE/kqdf7fExSm8BmcszCQSKIRil8nE3lnYRa5Tufbqbe59OXNkUbOt2dq0IeQUCIxF8SmUiMg5nYMaiEvRhcqeBQE0TjFJ5uQwryVxuJcQFwFHtrc3zynyfQKDsBD2lMtPS1rkBFjNULm2jxcDf21ub9yvT+IFARQkrpTITlbE5DBNxT5seYEY0fiAwKghGqQK0tzb/CTiKdA3TYqAD+EB7a/PsFMcNBKpKMEoVor21+bfAfsDbWBHEJCwEbgS2b29tDnlsgVFF8ClVmJa2zsnAxcCnsMTdYipTzse2bF9ob22+vgzTCwSqTjBKVaKlrXN94OvAkZiO9eDKpgP0Y4aoEXgBOBu4tr21OQisBUYtwShVmZa2ziZgGrAt8EFgday66QJMauR+4MH21uaOKk0xEKgowSgFAoFMERzdgUAgUwSjFAgEMkUwSoFAIFMEoxQIBDJFMEqBQCBTBKMUCAQyRTBKgUAgUwSjFAgEMkUwSoFAIFMEoxQIBDJFMEqBQCBTBKMUCAQyRTBKgUAgUwSjFAgEMsX/A/YppaA+GbRqAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Example of drawing method of the class GrapgModel\n",
+ "n_nodes = 5\n",
+ "E = [(0,1),(0,2),(0,3), (0,4),(1,2),(1,3), (1,4), (2,3), (2,4),(3,4) ]\n",
+ "weghts_list = [1,2,7,4,5]\n",
+ "distancies_list = [1,2,2,1,1,2,2,1,2,1]\n",
+ "G = GraphModel(n_nodes, E, weghts_list, distancies_list )\n",
+ "graph_drawing(G,'raw',filename = 'dummy_graph.png')\n",
+ "\n",
+ "# n_nodes = 3\n",
+ "# E = [(0,1),(0,2),(1,2)]\n",
+ "# weghts_list = [5,5,100]\n",
+ "# distancies_list = [1,1,10]\n",
+ "# G = GraphModel(n_nodes, E, weghts_list, distancies_list )\n",
+ "# graph_drawing(G,'raw',filename = 'dummy_graph.png')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 232,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "graph_drawing(G,'done',bitstring = [1,1,1,0,0],filename = 'dummy_graph_option.png')\n",
+ "# graph_drawing(G,'done',bitstring = [1,0,1],filename = 'dummy_graph_option.png')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 199,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 7, 4, 5]"
+ ]
+ },
+ "execution_count": 199,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "G.weights"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 200,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 200,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(G.distancies) == len(G.edges)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Circuit construction"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Calculation of the hamiltonian coefficients \n",
+ "\n",
+ "\\begin{equation}\n",
+ "H = \\sum_{i=1}^{N} (h_i - \\sum_{j \\not= i} g_{ij}) \\, Z_i + \\sum_{i"
+ ]
+ },
+ "execution_count": 205,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister\n",
+ "from qiskit import Aer, execute\n",
+ "from qiskit.circuit import Parameter\n",
+ "\n",
+ "nqubits = n_nodes\n",
+ "# Drawing the circuit for p=1\n",
+ "beta = Parameter(\"$\\\\beta$\")\n",
+ "qc_mix = QuantumCircuit(nqubits)\n",
+ "for i in range(0, nqubits):\n",
+ " qc_mix.rx(2 * beta, i)\n",
+ "\n",
+ "gamma = Parameter(\"$\\\\gamma$\")\n",
+ "qc_p_1 = QuantumCircuit(nqubits)\n",
+ "for edge in G.edges: # pairs of nodes\n",
+ " qc_p_1.rzz(2 * gamma * g[edge[0], edge[1]], edge[0], edge[1])\n",
+ " qc_p_1.barrier()\n",
+ "\n",
+ "qc_p_2 = QuantumCircuit(nqubits)\n",
+ "for i in range(0, nqubits):\n",
+ " qc_p_2.rz(2 * gamma * k[i],i)\n",
+ " qc_p_2.barrier()\n",
+ " \n",
+ "qc_0 = QuantumCircuit(nqubits)\n",
+ "for i in range(0, nqubits):\n",
+ " qc_0.h(i)\n",
+ "\n",
+ "qc_qaoa = QuantumCircuit(nqubits)\n",
+ "\n",
+ "qc_qaoa.append(qc_0, [i for i in range(0, nqubits)])\n",
+ "qc_qaoa.append(qc_p_1, [i for i in range(0, nqubits)])\n",
+ "qc_qaoa.append(qc_p_2, [i for i in range(0, nqubits)])\n",
+ "qc_qaoa.append(qc_mix, [i for i in range(0, nqubits)])\n",
+ "qc_qaoa.measure_all()\n",
+ "qc_qaoa.decompose().decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 206,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from scipy.optimize import minimize\n",
+ "from qiskit.visualization import plot_histogram"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 207,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.5\n",
+ "8.0\n",
+ "5.0\n",
+ "5.5\n",
+ "14.5\n",
+ "9.0\n",
+ "11.0\n",
+ "28.5\n",
+ "36.0\n",
+ "20.5\n"
+ ]
+ }
+ ],
+ "source": [
+ "for edge in G.edges: # pairs of nodes\n",
+ " print(2*g[edge[0], edge[1]])\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 208,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0, 0, 1, 0, 1]"
+ ]
+ },
+ "execution_count": 208,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x = \"00101\"\n",
+ "x = list(map(int,list(x)))\n",
+ "x"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Here we create the QAOA model to **minimize** the function: \n",
+ "\n",
+ "\\begin{equation}\n",
+ "C(\\vec{x}) = -2V \\sum_{i=1}^{N} w_i z_i + \\sum_{i"
+ ]
+ },
+ "execution_count": 231,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "plot_histogram(counts, figsize=(16, 10), color=None, number_to_keep=None,\n",
+ " sort='asc', target_string=None, legend=None,\n",
+ " bar_labels=True, title=\"Final Distribution\", ax=None)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "00111 corresponds to 0,1,2 nodes are occupied"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/team 8/ReadMe.md b/team 8/ReadMe.md
new file mode 100644
index 0000000..f60e898
--- /dev/null
+++ b/team 8/ReadMe.md
@@ -0,0 +1,13 @@
+# Space debris collection
+
+Welcome to our repository! Here, we propose an efficient solution to optimize space expedition to collect space garbage.
+
+In this repository, you can find:
+* Our [business proposal](https://github.com/ab-jiteshlalwani/Hackathon2022/blob/main/team%208/Business_Application.md) : Business_Application.md
+* A [technical explanation](https://github.com/ab-jiteshlalwani/Hackathon2022/blob/main/team%208/Technical_Explanation.ipynb) of what algorithm does and how it works on this problem : Technical_Explanation.ipynb
+* Our codes for:
+ * [Quantum Annealing](https://github.com/ab-jiteshlalwani/Hackathon2022/blob/main/team%208/space_debris_collection_QA_Dwave.ipynb) : space_debris_collection_QA_Dwave.ipynb
+ * [QAOA with Pennylane](https://github.com/ab-jiteshlalwani/Hackathon2022/blob/main/team%208/space_debris_collection_Pennylane.ipynb) : space_debris_collection_Pennylane.ipynb
+ * [QAOA with Qiskit](https://github.com/ab-jiteshlalwani/Hackathon2022/blob/main/team%208/Debris_Removal_Model_Qiskit.ipynb): Debris_Removal_Model_Qiskit.ipynb
+
+ Here is a link to our presentation slides: https://docs.google.com/presentation/d/1zBIP7QOgtwzTeTv0sfvOP2ZzHSZc5o7bAlzJogANkA8/edit?usp=sharing
diff --git a/team 8/Technical_Explanation.ipynb b/team 8/Technical_Explanation.ipynb
new file mode 100644
index 0000000..ba7f72e
--- /dev/null
+++ b/team 8/Technical_Explanation.ipynb
@@ -0,0 +1,128 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "030bde69-364a-46c8-b41b-13e0892a6d24",
+ "metadata": {},
+ "source": [
+ "# Technical solution to space debris collection\n",
+ "\n",
+ "Here, we formulate the problem to solve to optimize space cleaning. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "69f1bc92-9639-46da-98cc-89805327de17",
+ "metadata": {},
+ "source": [
+ "The problem of trash in space has become a boiling issue: objects are orbiting around the earth, endangering the space expeditions. They are composed of dysfunctional instruments that are no longer in use, or broken parts that were torn apart from a larger device. In spite of being mostly very small, they travel at such impressive speeds that by Newton's law, any shock with one of these could cause tremendous damage to a space ship or a satellite. Since these space expeditions are very costly, it is a major challenge to avoid them, and to remove them from space in the long term. Therefore, the challenge of cleaning space has been undertaken by companies, space agencies and public institutions.\n",
+ "\n",
+ "To optimize their travel and collection schedule, two main constraints should be fulfilled:\n",
+ "1) Since the space ship has limited capacity, it can only collect so much that it can contain.\n",
+ "2) Fuel can also be contained in limited amounts, and is in itself very expensive. It is hence desirable to travel the longest distance that the fuel quantity allows.\n",
+ "\n",
+ "To formulate it simply, the challenge is to find the shortest path between debris that gathers the most of them, within the capactity of the ship. Using brute force, one would have to try all possible combinations of debris to find the one that fulfills these conditions the best. It is therefore a combinatorial optimization problem that would grow exponentially in the number of debris to choose from. It is therefore unscalable and untractable to classical computer at large scales. To circumvent this delicate issue, we propose to use a quantum-classical algorithm to get a better solution than a classical computer could get. Using the gate-based model in quantum computing, we solve the problem with the Quantum Approximate Optimization Algorithm.\n",
+ "\n",
+ "## Cost function \n",
+ "\n",
+ "To perform the optimization, we first express the problem in a cost function that we attempt to minimize. We start with a set of N debris. We encode the information about the debris in a bitstring:\\begin{equation}\n",
+ "z = z_1 z_2 \\cdots z_N, \\text{where } z_i = \\begin{cases}\n",
+ "1, & \\text{if debris i is collected} \\\\\n",
+ "0, & \\text{if otherwise.}\n",
+ "\\end{cases}\n",
+ "\\end{equation}\n",
+ "\n",
+ "To solve the problem with brute force method, we must inspect all possible bitstrings $z$ and pick the one that maximizes the volume of the debris collected. Therefore, it is a combinatorial optimization problem. To formulate it, we pair each debris $i$ with its weight/size $w_i$. The debris locations can be reported on a graph with edge set $E$ and vertex set $V$ such that $G = \\{E,V\\}$. Each vertex is associated with a weight, and each edge $i -j$ with a distance $d_{ij}$. With these notations, we encode the problem into the cost function:\n",
+ "\\begin{equation}\n",
+ "C(z) = (V-\\sum_{i=1}^{N} w_i z_i)^2 + \\sum_{ii} g_{ij} -\\sum_{j=0.24\n",
+ " Downloading PennyLane_Lightning-0.24.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (9.3 MB)\n",
+ "\u001b[K |████████████████████████████████| 9.3 MB 27.1 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: appdirs in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4.4)\n",
+ "Collecting semantic-version==2.6\n",
+ " Downloading semantic_version-2.6.0-py3-none-any.whl (14 kB)\n",
+ "Requirement already satisfied: cachetools in /usr/local/lib/python3.7/dist-packages (from pennylane) (4.2.4)\n",
+ "Collecting retworkx\n",
+ " Downloading retworkx-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB)\n",
+ "\u001b[K |████████████████████████████████| 1.6 MB 47.5 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: autograd in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4)\n",
+ "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.21.6)\n",
+ "Collecting toml\n",
+ " Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)\n",
+ "Collecting autoray>=0.3.1\n",
+ " Downloading autoray-0.3.2-py3-none-any.whl (36 kB)\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from pennylane) (2.6.3)\n",
+ "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.7.3)\n",
+ "Collecting ninja\n",
+ " Downloading ninja-1.10.2.3-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl (108 kB)\n",
+ "\u001b[K |████████████████████████████████| 108 kB 48.6 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: future>=0.15.2 in /usr/local/lib/python3.7/dist-packages (from autograd->pennylane) (0.16.0)\n",
+ "Installing collected packages: ninja, toml, semantic-version, retworkx, pennylane-lightning, autoray, pennylane\n",
+ "Successfully installed autoray-0.3.2 ninja-1.10.2.3 pennylane-0.24.0 pennylane-lightning-0.24.0 retworkx-0.11.0 semantic-version-2.6.0 toml-0.10.2\n",
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (2.6.3)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sys\n",
+ "!{sys.executable} -m pip install pennylane\n",
+ "!{sys.executable} -m pip install networkx"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import networkx as nx\n",
+ "import pennylane as qml\n",
+ "from pennylane import numpy as np \n",
+ "import matplotlib.pyplot as plt"
+ ],
+ "metadata": {
+ "id": "vTd6PsprHhIm"
+ },
+ "execution_count": 5,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Space debris optimization"
+ ],
+ "metadata": {
+ "id": "wr3gMLPUepdb"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "In this work, we solve the combinatorial optimization problem of space debris collection. A challenge for space agencies, satellite producers and any actor involved in space travel is to avoid space debris. In spite of possibly small sizes, their speeds on orbits make any collision with satellite or spacecraft threaten the success of space expeditions with major damage. Therefore, a major concern is to collect these debris and destroy them at the entrance of the atmosphere."
+ ],
+ "metadata": {
+ "id": "FdAx9nEVeytw"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "The problem is the following. Debris collection journeys are expensive, since the quantity of fuels used to propel the engins is massive, and the capacity of each space craft limits the amount of space garbage that can be collected. To optimize each trip to space, we must therefore seek debris located at particular locations, such that they minimize the distance and hence the fuel consumption, and they maximize the quantity of trash collected. We solve the latter problem first, and add further constraints to the problem progressively."
+ ],
+ "metadata": {
+ "id": "sMUPN0CCfzsU"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Formulation of the cost function "
+ ],
+ "metadata": {
+ "id": "wKXwHlEhP2_-"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Let us first consider the problem of maximization of the volume of trash that is collected. This task is related to the knapsack problem. \n",
+ "\n",
+ "We start with a set of N debris. We encode the information about the debris to collect in a bitstring:\n",
+ "\\begin{equation}\n",
+ "z = z_1 z_2 \\cdots z_N, \\text{where } z_i = \\begin{cases}\n",
+ "1, & \\text{if debris i is collected} \\\\\n",
+ "0, & \\text{if otherwise.}\n",
+ "\\end{cases}\n",
+ "\\end{equation}\n",
+ "\n",
+ "To solve the problem with brute force method, we must inspect all possible bitstrings $z$ and pick the one that maximizes the volume of the debris collected. Therefore, it is a combinatorial optimization problem. To formulate it, we pair each debris $i$ with its weight/size $w_i$. The debris locations can be reported on a graph with edge set $E$ and vertex set $V$ such that $G = \\{E,V\\}$. Each vertex is associated with a weight, and each edge $i -j$ with a distance $d_{ij}$. With these notations, we encode the problem into the cost function:\n",
+ "\\begin{equation}\n",
+ "C(z) = (V-\\sum_{i=1}^{N} w_i z_i)^2 + \\sum_{i, j=1}^{N} d_{ij} z_i z_j\n",
+ "\\end{equation}\n",
+ "where the first term corresponds to the knapsack problem and the second aims at minimizing the travelled distance. To simplify the implementation, the constant term can be removed:\n",
+ "\\begin{align}\n",
+ "C(z) &= (-2V\\sum_{i=1}^{N} w_i z_i + 2\\sum_{ii} g_{ij} -\\sum_{j 1]\n",
+ "light_edges = [(u, v) for (u, v, d) in G.edges(data=True) if d[\"weight\"] <= 1]\n",
+ "pos = nx.spring_layout(G, seed=11) \n",
+ "nx.draw_networkx_nodes(G, pos, node_size=700, node_color=\"r\")\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=heavy_edges, width=6)\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=light_edges, width=6, edge_color=\"b\", style=\"dashed\")\n",
+ "nx.draw_networkx_labels(G, pos, font_size=20, font_family=\"sans-serif\")\n",
+ "edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels)\n",
+ " \n",
+ "#nx.draw(G, with_labels=True, alpha=0.8, node_size=300)\n",
+ "\n"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 418
+ },
+ "id": "987QfIbfgt6D",
+ "outputId": "329c4481-f867-409f-dc81-467fc2ec0d07"
+ },
+ "execution_count": 6,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{('0', '1'): Text(-0.31213490044069825, 0.0229285235823255, '1'),\n",
+ " ('0', '2'): Text(0.18180059090333675, -0.7976561108038269, '2'),\n",
+ " ('0', '3'): Text(-0.6981592185316541, -0.4262551763130149, '2'),\n",
+ " ('0', '4'): Text(0.2340158724740534, -0.207744883060842, '1'),\n",
+ " ('1', '2'): Text(0.26598412752594675, 0.16442417717540436, '1'),\n",
+ " ('1', '3'): Text(-0.6139756819090442, 0.5358251116662163, '2'),\n",
+ " ('1', '4'): Text(0.3181994090966634, 0.7543354049183892, '2'),\n",
+ " ('2', '3'): Text(-0.12004019056500914, -0.28475952271993604, '1'),\n",
+ " ('2', '4'): Text(0.8121349004406984, -0.06624922946776313, '2'),\n",
+ " ('3', '4'): Text(-0.0678249089942925, 0.30515170502304884, '1')}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 6
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {}
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We implement the QAOA algorithm on this data set. We choose:\n",
+ "- Mixer Hamiltonian: $\\hat{H}_M = \\sum_{i=0}^{N-1} X_i$\n",
+ "- Problem Hamiltonin as defined above\n",
+ "\n",
+ "For an approximate Trotterization with p steps, the evolution yields the following state:\n",
+ "\\begin{equation}\n",
+ "|\\overrightarrow{\\gamma}, \\overrightarrow{\\beta}\\rangle = e^{i\\beta_p H_M} e^{i\\gamma_p H_P} \\cdots e^{i\\beta_1 H_M} e^{i\\gamma_1 H_P}|+\\rangle^{\\otimes{N}}\n",
+ "\\end{equation}\n",
+ "where $|+\\rangle^{\\otimes{N}} = \\frac{1}{\\sqrt{2^N}} \\sum_{z\\in \\{0,1\\}^N} |z\\rangle $ is an equal superposition of all bitstrings."
+ ],
+ "metadata": {
+ "id": "QiItM9uZKZoU"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "dev = qml.device(\"default.qubit\", wires=len(G.nodes()), shots= 1024)\n",
+ "\n",
+ "@qml.qnode(dev)\n",
+ "def QAOA_Circuit(G, weights, V, p, angles):\n",
+ " N_vertices = len(G.nodes())\n",
+ " wires = range(N_vertices)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ "\n",
+ " # Initialize the states\n",
+ " for i in range(N_vertices):\n",
+ " qml.Hadamard(wires=wires[i])\n",
+ "\n",
+ " # Apply QAOA\n",
+ " gammas = angles[:p]\n",
+ " beta = angles[p:]\n",
+ "\n",
+ " problem_coef = []\n",
+ " problem_operators = []\n",
+ "\n",
+ " for step in range(0, p):\n",
+ " \n",
+ " # Apply the problem Hamiltonian\n",
+ " \n",
+ " for i in range(0, N_vertices):\n",
+ " coef_single = V*weights[i] - sum([v for k,v in distances.items() if str(i) in k])\n",
+ " qml.RZ(coef_single*gammas[step], wires=wires[i])\n",
+ " if step == 1:\n",
+ " problem_coef += [coef_single]\n",
+ " problem_operators += [qml.PauliZ(wires=wires[i])]\n",
+ "\n",
+ " for j in range(i+1, N_vertices):\n",
+ " coef_double = (1/2*weights[i]*weights[j] + 1/4*nx.get_edge_attributes(G, \"weight\")[(str(i), str(j))])\n",
+ " qml.MultiRZ(gammas[step]*coef_double, wires=[wires[i]]+[wires[j]])\n",
+ " if step == 1:\n",
+ " problem_coef += [coef_double]\n",
+ " problem_operators += [qml.PauliZ(wires[i]) @ qml.PauliZ(wires[j])]\n",
+ "\n",
+ "\n",
+ " # Apply the mixer Hamiltonian\n",
+ " for i in range(0, N_vertices):\n",
+ " qml.RX(beta[step], wires=wires[i])\n",
+ "\n",
+ " # Compute the expectation value of the problem Hamiltonian\n",
+ " # problem_H = qml.Hamiltonian(problem_coef, problem_operators)\n",
+ "\n",
+ " return qml.expval(qml.Hamiltonian(problem_coef, problem_operators))\n"
+ ],
+ "metadata": {
+ "id": "zc9MhBK3MJqV"
+ },
+ "execution_count": 7,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "@qml.qnode(dev)\n",
+ "def QAOA_Circuit_optimized_probas(G, weights, V, p, angles):\n",
+ " N_vertices = len(G.nodes())\n",
+ " wires = range(N_vertices)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ "\n",
+ " # Initialize the states\n",
+ " for i in range(N_vertices):\n",
+ " qml.Hadamard(wires=wires[i])\n",
+ "\n",
+ " # Apply QAOA\n",
+ " gammas = angles[:p]\n",
+ " beta = angles[p:]\n",
+ "\n",
+ " for step in range(0, p):\n",
+ " \n",
+ " # Apply the problem Hamiltonian\n",
+ " \n",
+ " for i in range(0, N_vertices):\n",
+ " coef_single = V*weights[i] - sum([v for k,v in distances.items() if str(i) in k])\n",
+ " qml.RZ(coef_single*gammas[step], wires=wires[i])\n",
+ "\n",
+ " for j in range(i+1, N_vertices):\n",
+ " coef_double = (1/2*weights[i]*weights[j] + 1/4*nx.get_edge_attributes(G, \"weight\")[(str(i), str(j))])\n",
+ " qml.MultiRZ(gammas[step]*coef_double, wires=[wires[i]]+[wires[j]])\n",
+ "\n",
+ " # Apply the mixer Hamiltonian\n",
+ " for i in range(0, N_vertices):\n",
+ " qml.RX(beta[step], wires=wires[i])\n",
+ "\n",
+ " return qml.probs(wires)"
+ ],
+ "metadata": {
+ "id": "ZKp_UBGi23J6"
+ },
+ "execution_count": 151,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Optimize the angles\n",
+ "def cost_function(G, weights, V, p, angles):\n",
+ " def optimizable_object(angles):\n",
+ " cost_exp_val = QAOA_Circuit(G, weights, V, p, angles)\n",
+ " return cost_exp_val\n",
+ " return optimizable_object"
+ ],
+ "metadata": {
+ "id": "i3CKY8f0mdV1"
+ },
+ "execution_count": 105,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Parameters\n",
+ "V = 10\n",
+ "weights = np.array([1,2,7,4,5], requires_grad=False)\n",
+ "p=2\n",
+ "\n",
+ "angles = np.array(2*p*[np.pi/4], requires_grad=True)\n",
+ "#angles = np.pi/p*np.array(2*p*[0])\n",
+ "shots=1024\n",
+ "\n",
+ "dev = qml.device(\"default.qubit\", wires=len(G.nodes()), shots=shots)"
+ ],
+ "metadata": {
+ "id": "7hZXeG4dOj1w"
+ },
+ "execution_count": 235,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "circuit = QAOA_Circuit(G, weights, V, p, angles)"
+ ],
+ "metadata": {
+ "id": "c2H1BfBmu6Ma"
+ },
+ "execution_count": 236,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from scipy.optimize import minimize\n",
+ "cost = cost_function(G, weights, V, p, angles)\n",
+ "optimized_params = minimize(cost, angles, method='COBYLA')\n",
+ "optimized_angles = optimized_params.x\n",
+ "\n",
+ "#optimizer = qml.GradientDescentOptimizer(stepsize=0.8)\n",
+ "#cost = cost_function(G, weights, V, p, angles)\n",
+ "#for k in range(100):\n",
+ "# if k % 5 == 0:\n",
+ "# print(f\"Step {k}, cost: {cost(angles)}\")\n",
+ "# angles = optimizer.step(cost, angles)\n",
+ "#optimized_angles = angles"
+ ],
+ "metadata": {
+ "id": "t-XpCGgc1edP"
+ },
+ "execution_count": 237,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "proba_opt = QAOA_Circuit_optimized_probas(G, weights, V, p, optimized_angles)\n",
+ "exp_val_opt = QAOA_Circuit(G, weights, V, p, optimized_angles)\n",
+ "#probas_opt = result(0)\n",
+ "#exp_val = result(1)\n",
+ "print(exp_val_opt)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "jvZnSGY8BgR8",
+ "outputId": "51e52b12-59d5-4db2-c805-352f2cab3af7"
+ },
+ "execution_count": 238,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "-34.09912109375\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "xlabels = [str(bin(i)[2:]) for i in range(len(proba_opt))]\n",
+ "for x in range(len(xlabels)):\n",
+ " while len(xlabels[x]))"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 239
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "print(np.max(proba_opt))"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "yYn1_QjXbPaX",
+ "outputId": "cb8738fa-4e89-458e-9b11-aa1b9ecaa37f"
+ },
+ "execution_count": 240,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "0.1015625\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Classical algorithm"
+ ],
+ "metadata": {
+ "id": "3biD-ZFOZB5U"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Brute force\n",
+ "def classical_cost_calculator(z, G, weights, V):\n",
+ " weights = np.array(weights)\n",
+ " z = np.array(list(int(z[i]) for i in range(len(z))), requires_grad=False)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ " cost = (V-np.dot(weights,z))**2\n",
+ " for i in range(len(G.nodes())):\n",
+ " for j in range(i+1, len(G.nodes())):\n",
+ " cost += distances[(str(i), str(j))] * z[i] * z[j]\n",
+ " return cost\n",
+ "\n",
+ "def int_to_binary(G):\n",
+ " N = len(G.nodes())\n",
+ " n_list = list(range(2^N))\n",
+ "\n",
+ " def binary_filler(z,N):\n",
+ " while len(z)\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mz_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint_to_binary\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mz_list\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mbin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m: name 'n_list' is not defined"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "distances = nx.get_edge_attributes(G, \"weight\")\n",
+ "distances[('0', '1')]\n",
+ "cost = (V-weights*z)**2\n",
+ "cost"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "1ISZliobdc2N",
+ "outputId": "005b97e9-1cde-4895-b276-c1da049d145b"
+ },
+ "execution_count": 212,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "tensor([100, 100, 9, 100, 25], requires_grad=True)"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 212
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "len(G.nodes())"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "yl52JAZOeCU1",
+ "outputId": "e0979ac3-32c2-427e-8043-aeda094ac383"
+ },
+ "execution_count": 225,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 225
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ ""
+ ],
+ "metadata": {
+ "id": "Fe2uMEuXhDq3"
+ },
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/team 8/space_debris_collection_Pennylane.ipynb b/team 8/space_debris_collection_Pennylane.ipynb
new file mode 100644
index 0000000..1ee916e
--- /dev/null
+++ b/team 8/space_debris_collection_Pennylane.ipynb
@@ -0,0 +1,778 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "space_debris_collection_Pennylane.ipynb",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "iEYhchm4dvze",
+ "outputId": "3df98194-d82b-419d-f467-9e09b432bc9e"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Collecting pennylane\n",
+ " Downloading PennyLane-0.24.0-py3-none-any.whl (957 kB)\n",
+ "\u001b[K |████████████████████████████████| 957 kB 5.3 MB/s \n",
+ "\u001b[?25hCollecting pennylane-lightning>=0.24\n",
+ " Downloading PennyLane_Lightning-0.24.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (9.3 MB)\n",
+ "\u001b[K |████████████████████████████████| 9.3 MB 14.0 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: appdirs in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4.4)\n",
+ "Collecting toml\n",
+ " Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from pennylane) (2.6.3)\n",
+ "Collecting semantic-version==2.6\n",
+ " Downloading semantic_version-2.6.0-py3-none-any.whl (14 kB)\n",
+ "Collecting retworkx\n",
+ " Downloading retworkx-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB)\n",
+ "\u001b[K |████████████████████████████████| 1.6 MB 36.5 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.7.3)\n",
+ "Requirement already satisfied: cachetools in /usr/local/lib/python3.7/dist-packages (from pennylane) (4.2.4)\n",
+ "Collecting autoray>=0.3.1\n",
+ " Downloading autoray-0.3.2-py3-none-any.whl (36 kB)\n",
+ "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.21.6)\n",
+ "Requirement already satisfied: autograd in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4)\n",
+ "Collecting ninja\n",
+ " Downloading ninja-1.10.2.3-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl (108 kB)\n",
+ "\u001b[K |████████████████████████████████| 108 kB 53.9 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: future>=0.15.2 in /usr/local/lib/python3.7/dist-packages (from autograd->pennylane) (0.16.0)\n",
+ "Installing collected packages: ninja, toml, semantic-version, retworkx, pennylane-lightning, autoray, pennylane\n",
+ "Successfully installed autoray-0.3.2 ninja-1.10.2.3 pennylane-0.24.0 pennylane-lightning-0.24.0 retworkx-0.11.0 semantic-version-2.6.0 toml-0.10.2\n",
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (2.6.3)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sys\n",
+ "!{sys.executable} -m pip install pennylane\n",
+ "!{sys.executable} -m pip install networkx"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import networkx as nx\n",
+ "import pennylane as qml\n",
+ "from pennylane import numpy as np \n",
+ "import matplotlib.pyplot as plt"
+ ],
+ "metadata": {
+ "id": "vTd6PsprHhIm"
+ },
+ "execution_count": 2,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Space debris optimization"
+ ],
+ "metadata": {
+ "id": "wr3gMLPUepdb"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "In this work, we solve the combinatorial optimization problem of space debris collection. A challenge for space agencies, satellite producers and any actor involved in space travel is to avoid space debris. In spite of possibly small sizes, their speeds on orbits make any collision with satellite or spacecraft threaten the success of space expeditions with major damage. Therefore, a major concern is to collect these debris and destroy them at the entrance of the atmosphere."
+ ],
+ "metadata": {
+ "id": "FdAx9nEVeytw"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "The problem is the following. Debris collection journeys are expensive, since the quantity of fuels used to propel the engins is massive, and the capacity of each space craft limits the amount of space garbage that can be collected. To optimize each trip to space, we must therefore seek debris located at particular locations, such that they minimize the distance and hence the fuel consumption, and they maximize the quantity of trash collected. We solve the latter problem first, and add further constraints to the problem progressively."
+ ],
+ "metadata": {
+ "id": "sMUPN0CCfzsU"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Formulation of the cost function "
+ ],
+ "metadata": {
+ "id": "wKXwHlEhP2_-"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We start with a set of N debris. We encode the information about the debris to collect in a bitstring:\n",
+ "\\begin{equation}\n",
+ "z = z_1 z_2 \\cdots z_N, \\text{where } z_i = \\begin{cases}\n",
+ "1, & \\text{if debris i is collected} \\\\\n",
+ "0, & \\text{if otherwise.}\n",
+ "\\end{cases}\n",
+ "\\end{equation}\n",
+ "\n",
+ "To solve the problem with brute force method, we must inspect all possible bitstrings $z$ and pick the one that maximizes the volume of the debris collected. Therefore, it is a combinatorial optimization problem. To formulate it, we pair each debris $i$ with its weight/size $w_i$. The debris locations can be reported on a graph with edge set $E$ and vertex set $V$ such that $G = \\{E,V\\}$. Each vertex is associated with a weight, and each edge $i -j$ with a distance $d_{ij}$. With these notations, we encode the problem into the cost function:\n",
+ "\\begin{equation}\n",
+ "C(z) = (V-\\sum_{i=1}^{N} w_i z_i)^2 + \\sum_{ii} g_{ij} -\\sum_{j 1]\n",
+ "light_edges = [(u, v) for (u, v, d) in G.edges(data=True) if d[\"weight\"] <= 1]\n",
+ "pos = nx.spring_layout(G, seed=11) \n",
+ "nx.draw_networkx_nodes(G, pos, node_size=700, node_color=\"r\")\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=heavy_edges, width=6)\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=light_edges, width=6, edge_color=\"b\", style=\"dashed\")\n",
+ "nx.draw_networkx_labels(G, pos, font_size=20, font_family=\"sans-serif\")\n",
+ "edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels)\n",
+ " \n",
+ "#nx.draw(G, with_labels=True, alpha=0.8, node_size=300)\n",
+ "\n",
+ "#N_vertices = 3\n",
+ "#G = nx.Graph()\n",
+ "#G.add_edge('0', '1', weight = 1)\n",
+ "#G.add_edge('1', '2', weight = 10)\n",
+ "#G.add_edge('2', '0', weight = 10)\n"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 418
+ },
+ "id": "987QfIbfgt6D",
+ "outputId": "330af4e4-a1a4-45b1-dffe-32897f9ab1a7"
+ },
+ "execution_count": 195,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{('0', '1'): Text(-0.31213490044069825, 0.0229285235823255, '1'),\n",
+ " ('0', '2'): Text(0.18180059090333675, -0.7976561108038269, '2'),\n",
+ " ('0', '3'): Text(-0.6981592185316541, -0.4262551763130149, '2'),\n",
+ " ('0', '4'): Text(0.2340158724740534, -0.207744883060842, '1'),\n",
+ " ('1', '2'): Text(0.26598412752594675, 0.16442417717540436, '1'),\n",
+ " ('1', '3'): Text(-0.6139756819090442, 0.5358251116662163, '2'),\n",
+ " ('1', '4'): Text(0.3181994090966634, 0.7543354049183892, '2'),\n",
+ " ('2', '3'): Text(-0.12004019056500914, -0.28475952271993604, '1'),\n",
+ " ('2', '4'): Text(0.8121349004406984, -0.06624922946776313, '2'),\n",
+ " ('3', '4'): Text(-0.0678249089942925, 0.30515170502304884, '1')}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 195
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {}
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We implement the QAOA algorithm on this data set. We choose:\n",
+ "- Mixer Hamiltonian: $\\hat{H}_M = \\sum_{i=0}^{N-1} X_i$\n",
+ "- Problem Hamiltonin as defined above\n",
+ "\n",
+ "For an approximate Trotterization with p steps, the evolution yields the following state:\n",
+ "\\begin{equation}\n",
+ "|\\overrightarrow{\\gamma}, \\overrightarrow{\\beta}\\rangle = e^{i\\beta_p H_M} e^{i\\gamma_p H_P} \\cdots e^{i\\beta_1 H_M} e^{i\\gamma_1 H_P}|+\\rangle^{\\otimes{N}}\n",
+ "\\end{equation}\n",
+ "where $|+\\rangle^{\\otimes{N}} = \\frac{1}{\\sqrt{2^N}} \\sum_{z\\in \\{0,1\\}^N} |z\\rangle $ is an equal superposition of all bitstrings."
+ ],
+ "metadata": {
+ "id": "QiItM9uZKZoU"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "dev = qml.device(\"default.qubit\", wires=len(G.nodes()), shots= 1024)\n",
+ "\n",
+ "@qml.qnode(dev)\n",
+ "def QAOA_Circuit(G, weights, V, p, angles):\n",
+ " N_vertices = len(G.nodes())\n",
+ " wires = range(N_vertices)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ "\n",
+ " # Initialize the states\n",
+ " for i in range(N_vertices):\n",
+ " qml.Hadamard(wires=wires[i])\n",
+ "\n",
+ " # Apply QAOA\n",
+ " gammas = angles[:p]\n",
+ " beta = angles[p:]\n",
+ "\n",
+ " problem_coef = []\n",
+ " problem_operators = []\n",
+ "\n",
+ " for step in range(0, p):\n",
+ " \n",
+ " # Apply the problem Hamiltonian\n",
+ " \n",
+ " for i in range(0, N_vertices):\n",
+ " coef_single = V*weights[i] - sum([v for k,v in distances.items() if str(i) in k])\n",
+ " qml.RZ(coef_single*gammas[step], wires=wires[i])\n",
+ " if step == 1:\n",
+ " problem_coef += [coef_single]\n",
+ " problem_operators += [qml.PauliZ(wires=wires[i])]\n",
+ "\n",
+ " for j in range(i+1, N_vertices):\n",
+ " coef_double = (1/2*weights[i]*weights[j] + 1/4*nx.get_edge_attributes(G, \"weight\")[(str(i), str(j))])\n",
+ " qml.MultiRZ(gammas[step]*coef_double, wires=[wires[i]]+[wires[j]])\n",
+ " if step == 1:\n",
+ " problem_coef += [coef_double]\n",
+ " problem_operators += [qml.PauliZ(wires[i]) @ qml.PauliZ(wires[j])]\n",
+ "\n",
+ "\n",
+ " # Apply the mixer Hamiltonian\n",
+ " for i in range(0, N_vertices):\n",
+ " qml.RX(beta[step], wires=wires[i])\n",
+ "\n",
+ " # Compute the expectation value of the problem Hamiltonian\n",
+ " # problem_H = qml.Hamiltonian(problem_coef, problem_operators)\n",
+ "\n",
+ " return qml.expval(qml.Hamiltonian(problem_coef, problem_operators))\n"
+ ],
+ "metadata": {
+ "id": "zc9MhBK3MJqV"
+ },
+ "execution_count": 196,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "@qml.qnode(dev)\n",
+ "def QAOA_Circuit_optimized_probas(G, weights, V, p, angles):\n",
+ " N_vertices = len(G.nodes())\n",
+ " wires = range(N_vertices)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ "\n",
+ " # Initialize the states\n",
+ " for i in range(N_vertices):\n",
+ " qml.Hadamard(wires=wires[i])\n",
+ "\n",
+ " # Apply QAOA\n",
+ " gammas = angles[:p]\n",
+ " beta = angles[p:]\n",
+ "\n",
+ " for step in range(0, p):\n",
+ " \n",
+ " # Apply the problem Hamiltonian\n",
+ " \n",
+ " for i in range(0, N_vertices):\n",
+ " coef_single = V*weights[i] - sum([v for k,v in distances.items() if str(i) in k])\n",
+ " qml.RZ(coef_single*gammas[step], wires=wires[i])\n",
+ "\n",
+ " for j in range(i+1, N_vertices):\n",
+ " coef_double = (1/2*weights[i]*weights[j] + 1/4*nx.get_edge_attributes(G, \"weight\")[(str(i), str(j))])\n",
+ " qml.MultiRZ(gammas[step]*coef_double, wires=[wires[i]]+[wires[j]])\n",
+ "\n",
+ " # Apply the mixer Hamiltonian\n",
+ " for i in range(0, N_vertices):\n",
+ " qml.RX(beta[step], wires=wires[i])\n",
+ "\n",
+ " return qml.probs(wires)"
+ ],
+ "metadata": {
+ "id": "ZKp_UBGi23J6"
+ },
+ "execution_count": 197,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Optimize the angles\n",
+ "def cost_function(G, weights, V, p, angles):\n",
+ " def optimizable_object(angles):\n",
+ " cost_exp_val = QAOA_Circuit(G, weights, V, p, angles)\n",
+ " return cost_exp_val\n",
+ " return optimizable_object"
+ ],
+ "metadata": {
+ "id": "i3CKY8f0mdV1"
+ },
+ "execution_count": 198,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Parameters\n",
+ "V = 10\n",
+ "if N_vertices == 5:\n",
+ " weights = np.array([1,2,7,4,5], requires_grad=False)\n",
+ "elif N_vertices == 3:\n",
+ " weights = np.array([5,5,100], requires_grad=False)\n",
+ "\n",
+ "p=2\n",
+ "\n",
+ "#angles = np.array(2*p*[np.pi/4], requires_grad=True)\n",
+ "angles = np.array(2*p*[1])\n",
+ "shots=2048\n",
+ "\n",
+ "dev = qml.device(\"default.qubit\", wires=len(G.nodes()), shots=shots)"
+ ],
+ "metadata": {
+ "id": "7hZXeG4dOj1w"
+ },
+ "execution_count": 262,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "circuit = QAOA_Circuit(G, weights, V, p, angles)"
+ ],
+ "metadata": {
+ "id": "c2H1BfBmu6Ma"
+ },
+ "execution_count": 263,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from scipy.optimize import minimize\n",
+ "cost = cost_function(G, weights, V, p, angles)\n",
+ "optimized_params = minimize(cost, angles, method='COBYLA')\n",
+ "optimized_angles = optimized_params.x\n",
+ "\n",
+ "#optimizer = qml.GradientDescentOptimizer(stepsize=0.8)\n",
+ "#cost = cost_function(G, weights, V, p, angles)\n",
+ "#for k in range(100):\n",
+ "# if k % 5 == 0:\n",
+ "# print(f\"Step {k}, cost: {cost(angles)}\")\n",
+ "# angles = optimizer.step(cost, angles)\n",
+ "#optimized_angles = angles"
+ ],
+ "metadata": {
+ "id": "t-XpCGgc1edP"
+ },
+ "execution_count": 264,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "proba_opt = QAOA_Circuit_optimized_probas(G, weights, V, p, optimized_angles)\n",
+ "exp_val_opt = QAOA_Circuit(G, weights, V, p, optimized_angles)\n",
+ "#probas_opt = result(0)\n",
+ "#exp_val = result(1)\n",
+ "print(exp_val_opt)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "jvZnSGY8BgR8",
+ "outputId": "6730b459-1c13-4795-c1a4-9553c6718f09"
+ },
+ "execution_count": 265,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "-22.35400390625\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "xlabels = [str(bin(i)[2:]) for i in range(len(proba_opt))]\n",
+ "for x in range(len(xlabels)):\n",
+ " while len(xlabels[x]))"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 268
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "print(np.max(proba_opt))"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "yYn1_QjXbPaX",
+ "outputId": "2cb54657-7908-4f74-9e6a-80390a98e333"
+ },
+ "execution_count": 267,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "0.14453125\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Classical algorithm"
+ ],
+ "metadata": {
+ "id": "3biD-ZFOZB5U"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Brute force\n",
+ "def classical_cost_calculator(z, G, weights, V):\n",
+ " weights = np.array(weights)\n",
+ " distances = nx.get_edge_attributes(G, \"weight\")\n",
+ " cost = []\n",
+ " for number in range(len(z)):\n",
+ " z_vector = [int(z[number][-1])]\n",
+ " for i in reversed(range(0,len(weights)-1)):\n",
+ " z_vector = z_vector + [int(z[number][i])]\n",
+ " z_vector = np.array(z_vector, requires_grad=False)\n",
+ "\n",
+ " cost_n = (V-np.dot(weights,z_vector))**2 # - np.dot(weights,z_vector)\n",
+ " for i in range(len(G.nodes())):\n",
+ " for j in range(i+1, len(G.nodes())):\n",
+ " cost_n += distances[(str(i), str(j))] * z_vector[i] * z_vector[j]\n",
+ " cost = cost + [cost_n]\n",
+ " return cost\n",
+ "\n",
+ "def int_to_binary(G):\n",
+ " N = len(G.nodes())\n",
+ " n_list = list(range(2**N))\n",
+ "\n",
+ " def binary_filler(z,N):\n",
+ " while len(z))"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 254
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "min_cost = np.min(classical_cost)\n",
+ "print(min_cost)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "1ISZliobdc2N",
+ "outputId": "817f3496-215d-4c07-ad3d-659daef2e304"
+ },
+ "execution_count": 255,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "optimal_packages= np.where(np.array(classical_cost) == np.min(classical_cost))[0]\n",
+ "optimal_bitstrings = [bin(optimal_packages[i])[2:] for i in range(len(optimal_packages))]\n",
+ "for i in range(len(optimal_bitstrings)):\n",
+ " while len(optimal_bitstrings[i])< N_vertices:\n",
+ " optimal_bitstrings[i] = '0' + optimal_bitstrings[i]\n",
+ "print(\"The optimal trajectories are: \", optimal_bitstrings)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "KKEpG2iLwPm7",
+ "outputId": "ccee5148-5e25-482d-9d21-9a7b02e7dd1b"
+ },
+ "execution_count": 256,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "The optimal trajectories are: ['00110', '01100', '11000']\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ ""
+ ],
+ "metadata": {
+ "id": "x7J3X509RWXn"
+ },
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/team 8/space_debris_collection_QA_Dwave.ipynb b/team 8/space_debris_collection_QA_Dwave.ipynb
new file mode 100644
index 0000000..a80a535
--- /dev/null
+++ b/team 8/space_debris_collection_QA_Dwave.ipynb
@@ -0,0 +1,589 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "space_debris_collection_QA_Dwave.ipynb",
+ "provenance": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 117,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "iEYhchm4dvze",
+ "outputId": "90f67db7-edf5-4af7-ddcb-bf7187df8779"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Requirement already satisfied: pennylane in /usr/local/lib/python3.7/dist-packages (0.24.0)\n",
+ "Requirement already satisfied: autoray>=0.3.1 in /usr/local/lib/python3.7/dist-packages (from pennylane) (0.3.2)\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from pennylane) (2.6.3)\n",
+ "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.21.6)\n",
+ "Requirement already satisfied: appdirs in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4.4)\n",
+ "Requirement already satisfied: cachetools in /usr/local/lib/python3.7/dist-packages (from pennylane) (4.2.4)\n",
+ "Requirement already satisfied: semantic-version==2.6 in /usr/local/lib/python3.7/dist-packages (from pennylane) (2.6.0)\n",
+ "Requirement already satisfied: autograd in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.4)\n",
+ "Requirement already satisfied: retworkx in /usr/local/lib/python3.7/dist-packages (from pennylane) (0.11.0)\n",
+ "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from pennylane) (1.7.3)\n",
+ "Requirement already satisfied: pennylane-lightning>=0.24 in /usr/local/lib/python3.7/dist-packages (from pennylane) (0.24.0)\n",
+ "Requirement already satisfied: toml in /usr/local/lib/python3.7/dist-packages (from pennylane) (0.10.2)\n",
+ "Requirement already satisfied: ninja in /usr/local/lib/python3.7/dist-packages (from pennylane-lightning>=0.24->pennylane) (1.10.2.3)\n",
+ "Requirement already satisfied: future>=0.15.2 in /usr/local/lib/python3.7/dist-packages (from autograd->pennylane) (0.16.0)\n",
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (2.6.3)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sys\n",
+ "!{sys.executable} -m pip install pennylane\n",
+ "!{sys.executable} -m pip install networkx"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Space debris optimization"
+ ],
+ "metadata": {
+ "id": "wr3gMLPUepdb"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "In this work, we solve the combinatorial optimization problem of space debris collection. A challenge for space agencies, satellite producers and any actor involved in space travel is to avoid space debris. In spite of possibly small sizes, their speeds on orbits make any collision with satellite or spacecraft threaten the success of space expeditions with major damage. Therefore, a major concern is to collect these debris and destroy them at the entrance of the atmosphere."
+ ],
+ "metadata": {
+ "id": "FdAx9nEVeytw"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "The problem is the following. Debris collection journeys are expensive, since the quantity of fuels used to propel the engins is massive, and the capacity of each space craft limits the amount of space garbage that can be collected. To optimize each trip to space, we must therefore seek debris located at particular locations, such that they minimize the distance and hence the fuel consumption, and they maximize the quantity of trash collected. We solve the latter problem first, and add further constraints to the problem progressively."
+ ],
+ "metadata": {
+ "id": "sMUPN0CCfzsU"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Let us first consider the problem of maximization of the volume of trash that is collected. This task is related to the knapsack problem. \n",
+ "\n",
+ "We start with a set of N debris. We encode the information about the debris to collect in a bitstring:\n",
+ "\\begin{equation}\n",
+ "z = z_1 z_2 \\cdots z_N, \\text{where } z_i = \\begin{cases}\n",
+ "1, & \\text{if debris i is collected} \\\\\n",
+ "0, & \\text{if otherwise.}\n",
+ "\\end{cases}\n",
+ "\\end{equation}\n",
+ "\n",
+ "To solve the problem with brute force method, we must inspect all possible bitstrings $z$ and pick the one that maximizes the volume of the debris collected. Therefore, it is a combinatorial optimization problem. To formulate it, we pair each debris $i$ with its weight/size $w_i$. The debris locations can be reported on a graph with edge set $E$ and vertex set $V$ such that $G = \\{E,V\\}$. Each vertex is associated with a weight, and each edge $i -j$ with a distance $d_{ij}$. With these notations, we encode the problem into the cost function:\n",
+ "\\begin{equation}\n",
+ "C(z) = (V-\\sum_{i=1}^{N} w_i z_i)^2 + \\sum_{i 1]\n",
+ "light_edges = [(u, v) for (u, v, d) in G.edges(data=True) if d[\"weight\"] <= 1]\n",
+ "pos = nx.spring_layout(G, seed=11) \n",
+ "nx.draw_networkx_nodes(G, pos, node_size=700, node_color=\"r\")\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=heavy_edges, width=6)\n",
+ "nx.draw_networkx_edges(G, pos, edgelist=light_edges, width=6, edge_color=\"b\", style=\"dashed\")\n",
+ "nx.draw_networkx_labels(G, pos, font_size=20, font_family=\"sans-serif\")\n",
+ "edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels)"
+ ],
+ "metadata": {
+ "id": "987QfIbfgt6D",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 427
+ },
+ "outputId": "02129067-7847-4e2e-8d0c-374b26094829"
+ },
+ "execution_count": 119,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{('0', '1'): Text(-0.31213490044069825, 0.0229285235823255, '1'),\n",
+ " ('0', '2'): Text(0.18180059090333675, -0.7976561108038269, '2'),\n",
+ " ('0', '3'): Text(-0.6981592185316541, -0.4262551763130149, '2'),\n",
+ " ('0', '4'): Text(0.2340158724740534, -0.207744883060842, '1'),\n",
+ " ('1', '2'): Text(0.26598412752594675, 0.16442417717540436, '1'),\n",
+ " ('1', '3'): Text(-0.6139756819090442, 0.5358251116662163, '2'),\n",
+ " ('1', '4'): Text(0.3181994090966634, 0.7543354049183892, '2'),\n",
+ " ('2', '3'): Text(-0.12004019056500914, -0.28475952271993604, '1'),\n",
+ " ('2', '4'): Text(0.8121349004406984, -0.06624922946776313, '2'),\n",
+ " ('3', '4'): Text(-0.0678249089942925, 0.30515170502304884, '1')}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 119
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {}
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "!pip install dwave-ocean-sdk"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "_zjw_nquuQYx",
+ "outputId": "40039bad-3ab6-4931-b9c8-8c3e60db11a6"
+ },
+ "execution_count": 120,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Requirement already satisfied: dwave-ocean-sdk in /usr/local/lib/python3.7/dist-packages (5.3.0)\n",
+ "Requirement already satisfied: dimod==0.11.3 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.11.3)\n",
+ "Requirement already satisfied: dwave-system==1.15.0 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (1.15.0)\n",
+ "Requirement already satisfied: dwave-tabu==0.4.5 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.4.5)\n",
+ "Requirement already satisfied: dwave-cloud-client==0.10.1 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.10.1)\n",
+ "Requirement already satisfied: penaltymodel==1.0.2 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (1.0.2)\n",
+ "Requirement already satisfied: dwave-inspector==0.3.0 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.3.0)\n",
+ "Requirement already satisfied: dwave-networkx==0.8.12 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.8.12)\n",
+ "Requirement already satisfied: dwave-greedy==0.2.5 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.2.5)\n",
+ "Requirement already satisfied: dwavebinarycsp==0.2.0 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.2.0)\n",
+ "Requirement already satisfied: dwave-neal==0.5.9 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.5.9)\n",
+ "Requirement already satisfied: dwave-preprocessing==0.4.0 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.4.0)\n",
+ "Requirement already satisfied: minorminer==0.2.9 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.2.9)\n",
+ "Requirement already satisfied: dwave-hybrid==0.6.8 in /usr/local/lib/python3.7/dist-packages (from dwave-ocean-sdk) (0.6.8)\n",
+ "Requirement already satisfied: numpy<2.0.0,>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from dimod==0.11.3->dwave-ocean-sdk) (1.21.6)\n",
+ "Requirement already satisfied: plucky>=0.4.3 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (0.4.3)\n",
+ "Requirement already satisfied: diskcache>=5.2.1 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (5.4.0)\n",
+ "Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (7.1.2)\n",
+ "Requirement already satisfied: requests[socks]>=2.18 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (2.23.0)\n",
+ "Requirement already satisfied: pydantic>=1.7.3 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (1.9.1)\n",
+ "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (2.8.2)\n",
+ "Requirement already satisfied: homebase>=1.0 in /usr/local/lib/python3.7/dist-packages (from dwave-cloud-client==0.10.1->dwave-ocean-sdk) (1.0.1)\n",
+ "Requirement already satisfied: importlib-metadata>=1.0 in /usr/local/lib/python3.7/dist-packages (from dwave-greedy==0.2.5->dwave-ocean-sdk) (4.12.0)\n",
+ "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from dwave-hybrid==0.6.8->dwave-ocean-sdk) (2.6.3)\n",
+ "Requirement already satisfied: Flask>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from dwave-inspector==0.3.0->dwave-ocean-sdk) (1.1.4)\n",
+ "Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.7/dist-packages (from dwave-inspector==0.3.0->dwave-ocean-sdk) (5.8.0)\n",
+ "Requirement already satisfied: fasteners in /usr/local/lib/python3.7/dist-packages (from minorminer==0.2.9->dwave-ocean-sdk) (0.17.3)\n",
+ "Requirement already satisfied: rectangle-packer>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from minorminer==0.2.9->dwave-ocean-sdk) (2.0.1)\n",
+ "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from minorminer==0.2.9->dwave-ocean-sdk) (1.7.3)\n",
+ "Requirement already satisfied: Werkzeug<2.0,>=0.15 in /usr/local/lib/python3.7/dist-packages (from Flask>=1.1.1->dwave-inspector==0.3.0->dwave-ocean-sdk) (1.0.1)\n",
+ "Requirement already satisfied: itsdangerous<2.0,>=0.24 in /usr/local/lib/python3.7/dist-packages (from Flask>=1.1.1->dwave-inspector==0.3.0->dwave-ocean-sdk) (1.1.0)\n",
+ "Requirement already satisfied: Jinja2<3.0,>=2.10.1 in /usr/local/lib/python3.7/dist-packages (from Flask>=1.1.1->dwave-inspector==0.3.0->dwave-ocean-sdk) (2.11.3)\n",
+ "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=1.0->dwave-greedy==0.2.5->dwave-ocean-sdk) (3.8.1)\n",
+ "Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=1.0->dwave-greedy==0.2.5->dwave-ocean-sdk) (4.1.1)\n",
+ "Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/dist-packages (from Jinja2<3.0,>=2.10.1->Flask>=1.1.1->dwave-inspector==0.3.0->dwave-ocean-sdk) (2.0.1)\n",
+ "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (1.15.0)\n",
+ "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests[socks]>=2.18->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (1.24.3)\n",
+ "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests[socks]>=2.18->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (2022.6.15)\n",
+ "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests[socks]>=2.18->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (3.0.4)\n",
+ "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests[socks]>=2.18->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (2.10)\n",
+ "Requirement already satisfied: PySocks!=1.5.7,>=1.5.6 in /usr/local/lib/python3.7/dist-packages (from requests[socks]>=2.18->dwave-cloud-client==0.10.1->dwave-ocean-sdk) (1.7.1)\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "\n",
+ "from dwave.system.samplers import DWaveSampler\n",
+ "from dwave.system.composites import EmbeddingComposite\n",
+ "import numpy as np"
+ ],
+ "metadata": {
+ "id": "U9UX8YnHg4DJ"
+ },
+ "execution_count": 121,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from collections import defaultdict"
+ ],
+ "metadata": {
+ "id": "D4bYyUHD92e0"
+ },
+ "execution_count": 122,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "Q = defaultdict(int)"
+ ],
+ "metadata": {
+ "id": "rH9taLW50UtQ"
+ },
+ "execution_count": 123,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "w = [1,2,7,4,5]"
+ ],
+ "metadata": {
+ "id": "6Vk1R4N0Do1s"
+ },
+ "execution_count": 124,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Constraint Knapsack enncoded\n",
+ "for i in range(len(w)):\n",
+ " for j in range(i+1,len(w)):\n",
+ " # print(i,j)\n",
+ " # print()\n",
+ " # print(2*w[i]*w[j])\n",
+ " Q[(i,j)] = 2*w[i]*w[j]\n",
+ " \n",
+ " "
+ ],
+ "metadata": {
+ "id": "eolHbTxjEHMf"
+ },
+ "execution_count": 125,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "Q"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "YDO2DtLIHfz-",
+ "outputId": "dacd6dd7-8e23-491b-acd3-b63e2a32ddd5"
+ },
+ "execution_count": 126,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "defaultdict(int,\n",
+ " {(0, 1): 4,\n",
+ " (0, 2): 14,\n",
+ " (0, 3): 8,\n",
+ " (0, 4): 10,\n",
+ " (1, 2): 28,\n",
+ " (1, 3): 16,\n",
+ " (1, 4): 20,\n",
+ " (2, 3): 56,\n",
+ " (2, 4): 70,\n",
+ " (3, 4): 40})"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 126
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "for i in range(len(w)):\n",
+ " # print(i,i)\n",
+ " Q[(i,i)] = -19*w[i]+w[i]"
+ ],
+ "metadata": {
+ "id": "ISBmL_SAOmmQ"
+ },
+ "execution_count": 127,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "Q"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "e1IQe3nzPwa8",
+ "outputId": "de330812-e036-481b-d78d-db1507a79c72"
+ },
+ "execution_count": 128,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "defaultdict(int,\n",
+ " {(0, 0): -18,\n",
+ " (0, 1): 4,\n",
+ " (0, 2): 14,\n",
+ " (0, 3): 8,\n",
+ " (0, 4): 10,\n",
+ " (1, 1): -36,\n",
+ " (1, 2): 28,\n",
+ " (1, 3): 16,\n",
+ " (1, 4): 20,\n",
+ " (2, 2): -126,\n",
+ " (2, 3): 56,\n",
+ " (2, 4): 70,\n",
+ " (3, 3): -72,\n",
+ " (3, 4): 40,\n",
+ " (4, 4): -90})"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 128
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "distances = nx.get_edge_attributes(G, \"weight\")"
+ ],
+ "metadata": {
+ "id": "Ue3pREmUhSry"
+ },
+ "execution_count": 129,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#Objective TSP encoded\n",
+ "for i in range(len(w)):\n",
+ " for j in range(i+1,len(w)):\n",
+ " # print(i,j)\n",
+ " # print(distances[(str(i),str(j))])\n",
+ " # print()\n",
+ " Q[(i,j)] += distances[(str(i),str(j))]"
+ ],
+ "metadata": {
+ "id": "TRpjNAJOR6b2"
+ },
+ "execution_count": 130,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "Q"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "etHe5AhTgorW",
+ "outputId": "9be79d07-9824-4557-8d4f-43713aa1e6e3"
+ },
+ "execution_count": 131,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "defaultdict(int,\n",
+ " {(0, 0): -18,\n",
+ " (0, 1): 5,\n",
+ " (0, 2): 16,\n",
+ " (0, 3): 10,\n",
+ " (0, 4): 11,\n",
+ " (1, 1): -36,\n",
+ " (1, 2): 29,\n",
+ " (1, 3): 18,\n",
+ " (1, 4): 22,\n",
+ " (2, 2): -126,\n",
+ " (2, 3): 57,\n",
+ " (2, 4): 72,\n",
+ " (3, 3): -72,\n",
+ " (3, 4): 41,\n",
+ " (4, 4): -90})"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 131
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "sampler = DWaveSampler(token = '##############')\n",
+ "sampler = EmbeddingComposite(sampler)"
+ ],
+ "metadata": {
+ "id": "C_f4fG7Yjsgt"
+ },
+ "execution_count": 132,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "response = sampler.sample_qubo(Q, num_reads = 1000)"
+ ],
+ "metadata": {
+ "id": "NTtKZYCfhvdX"
+ },
+ "execution_count": 133,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "response"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "HtyEp8vOiX9f",
+ "outputId": "1e97780a-7ca5-490f-b6c8-2a3eea9a4ab5"
+ },
+ "execution_count": 134,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "SampleSet(rec.array([([0, 0, 1, 0, 1], -144., 395, 0. ),\n",
+ " ([0, 0, 1, 1, 0], -141., 294, 0. ),\n",
+ " ([1, 0, 1, 0, 1], -135., 74, 0. ),\n",
+ " ([0, 1, 1, 0, 0], -133., 71, 0. ),\n",
+ " ([1, 0, 1, 1, 0], -133., 34, 0. ),\n",
+ " ([0, 1, 1, 1, 0], -130., 29, 0. ),\n",
+ " ([1, 1, 1, 0, 0], -130., 26, 0. ),\n",
+ " ([0, 1, 1, 0, 1], -129., 25, 0. ),\n",
+ " ([1, 0, 1, 0, 0], -128., 13, 0. ),\n",
+ " ([0, 0, 1, 0, 0], -126., 15, 0. ),\n",
+ " ([0, 0, 0, 1, 1], -121., 7, 0. ),\n",
+ " ([0, 0, 1, 1, 1], -118., 1, 0. ),\n",
+ " ([1, 0, 0, 1, 1], -118., 4, 0. ),\n",
+ " ([1, 1, 1, 1, 0], -117., 3, 0. ),\n",
+ " ([0, 1, 0, 1, 1], -117., 4, 0. ),\n",
+ " ([1, 1, 1, 0, 1], -115., 1, 0. ),\n",
+ " ([1, 1, 0, 1, 1], -109., 2, 0. ),\n",
+ " ([1, 1, 1, 1, 0], -117., 2, 0.2)],\n",
+ " dtype=[('sample', 'i1', (5,)), ('energy', '